Prolog中的一组(列表)的电源集

Prolog中的一组(列表)的电源集,prolog,Prolog,下一个谓词将从列表生成所有子集: candidate([],[]). candidate([H|T],[H|R]):- candidate(T,R). candidate([_|T],R):- candidate(T,R). 有人能帮我理解它是怎么工作的吗?它看起来很短,但它背后的重复性让人觉得很难理解。很容易看出,{}的唯一子集是{} 假设您想要生成集合S={a,b,c}的所有子集 然后,您可以从S中移除一个元素,比如元素a,获得集合S-{a}={b,c} 通过归纳假设,可以

下一个谓词将从列表生成所有子集:

candidate([],[]).
candidate([H|T],[H|R]):-
    candidate(T,R).
candidate([_|T],R):-
    candidate(T,R).

有人能帮我理解它是怎么工作的吗?它看起来很短,但它背后的重复性让人觉得很难理解。

很容易看出,{}的唯一子集是{}

假设您想要生成集合S={a,b,c}的所有子集

然后,您可以从S中移除一个元素,比如元素a,获得集合S-{a}={b,c}

通过归纳假设,可以生成{b,c}的所有子集,这些子集是 {},{b},{c},{b,c}。这是由目标候选人T,R

由于{b,c}的每个子集也是{a,b,c}的子集,因此可以得出结论,S={a,b,c}的子集是:

{},{b},{c},{b,c}候选人[|T],R:-候选人T,R, 还有这些与集合{a}相连的相同子集,即:

{a} ,{a,b},{a,c},{a,b,c}候选人[H|T],[H|R]:-候选人,R。 通过改变两个递归规则的顺序,您可以更清楚地看到这一点

candidate([], []).
candidate([_|T], R):- candidate(T, R).     % does not include first element
candidate([H|T], [H|R]):- candidate(T,R).  % do include first element
结果:

?- candidate([a,b,c],S).
S = [] ;
S = [c] ;
S = [b] ;
S = [b, c] ;
S = [a] ;
S = [a, c] ;
S = [a, b] ;
S = [a, b, c].

很容易看出{}的唯一子集是{}

假设您想要生成集合S={a,b,c}的所有子集

然后,您可以从S中移除一个元素,比如元素a,获得集合S-{a}={b,c}

通过归纳假设,可以生成{b,c}的所有子集,这些子集是 {},{b},{c},{b,c}。这是由目标候选人T,R

由于{b,c}的每个子集也是{a,b,c}的子集,因此可以得出结论,S={a,b,c}的子集是:

{},{b},{c},{b,c}候选人[|T],R:-候选人T,R, 还有这些与集合{a}相连的相同子集,即:

{a} ,{a,b},{a,c},{a,b,c}候选人[H|T],[H|R]:-候选人,R。 通过改变两个递归规则的顺序,您可以更清楚地看到这一点

candidate([], []).
candidate([_|T], R):- candidate(T, R).     % does not include first element
candidate([H|T], [H|R]):- candidate(T,R).  % do include first element
结果:

?- candidate([a,b,c],S).
S = [] ;
S = [c] ;
S = [b] ;
S = [b, c] ;
S = [a] ;
S = [a, c] ;
S = [a, b] ;
S = [a, b, c].