?- [1 2 3 4 5,R]
输出
R = [1, 2]
R = [1, 3]
R = [1, 4]
R = [1, 5]
R = [2, 3]
R = [2, 4]
R = [2, 5]
R = [3, 4]
R = [3, 5]
R = [4, 5]
我使用了创建子集并修改它的代码
sub(0,_,[]).
sub(N,[X|T],[X|R]):-N>0,N1 is N-1,sub(N1,T,R).
sub(N,[_|T],R):-N>0,sub(N,T,R).
我会打电话给你
子(2,[1,2,3,4,5],R)
但有没有办法在不使用计数器的情况下完成?
答案 0 :(得分:2)
Prolog是关于定义关系(以规则的形式)并试图避免程序性思考(执行步骤以实现结果)。您可以通过将其分解为对的简单规则来解决此问题:
H
且尾部为T
的列表,有效对为[H,E]
,其中E
是T
的成员。H
且尾部为T
的列表,有效对是从T
中选取的一对。如果您考虑这些规则,它们是(1)互斥(没有与两个规则相匹配的解决方案),以及(2)它们是完整的(它们涵盖所有有效的解决方案)。
在Prolog中写这些,你得到:
pair([H|T], [H,E]) :- member(E, T).
pair([_|T], P) :- pair(T, P).
这提供了一种关系解决方案,产生:
| ?- sub([a,b,c,d], S).
S = [a,b] ? ;
S = [a,c] ? ;
S = [a,d] ? ;
S = [b,c] ? ;
S = [b,d] ? ;
S = [c,d] ? ;
(1 ms) no
| ?-
并且在更一般的情况下工作:
| ?- pair(L, P).
L = [A,B]
P = [A,B] ? ;
L = [A,B|_]
P = [A,B] ? ;
L = [A,_,B|_]
P = [A,B] ? ;
L = [A,_,_,B|_]
P = [A,B] ? ;
...
答案 1 :(得分:1)
一种简单的方法:
?- L = [1,2,3,4,5], forall((nth1(I,L,X), nth1(J,L,Y), I<J), writeln(I/J)).
1/2
1/3
1/4
1/5
2/3
2/4
2/5
3/4
3/5
4/5
L = [1, 2, 3, 4, 5].
答案 2 :(得分:0)
是的,因为您不必考虑任意长度的子集。
您需要考虑两个步骤,两者都有两种变体。
% Use the head as the first element
pairs((H, P2), [H | T]) :- pairs((H, P2), T).
% If we have the first element, use the head as the second element
pairs((P1, H), [H | _]) :- nonvar(P1).
% Ignore the head and pick what we need out of the tail
pairs(P, [_ | T]) :- pairs(P, T).