我用Result编写一个程序是一对以字典顺序在0和N-1之间的值[X,Y]
我现在有这个:
pairs(N,R) :-
pairsHelp(N,R,0,0).
pairsHelp(N,[],N,N) :- !.
pairsHelp(N,[],N,0) :- !.
pairsHelp(N,[[X,Y]|List],X,Y) :-
Y is N-1,
X < N,
X1 is X + 1,
pairsHelp(N,List,X1,0).
pairsHelp(N,[[X,Y]|List],X,Y) :-
Y < N,
Y1 is Y + 1,
pairsHelp(N,List,X,Y1).
我得到了我想要的第一次迭代,但是Prolog继续前进,然后给了我第二个答案。
?-pairs(2,R).
R = [[0,0],[0,1],[1,0],[1,1]] ;
false.
我不想要第二个答案(错误),只是第一个答案。我希望它在找到答案后停止。有什么想法吗?
答案 0 :(得分:4)
请记住,有一个很多更简单的方式来获得你想要的东西。如果确实X和Y都应该是整数,请使用between/3
枚举整数(&#34; lexicographical&#34;这里与自然数的顺序相同:0,1,2,... 。如果第三个参数是一个变量,这是between/3
枚举可能解决方案的顺序:
pairs(N, R) :-
succ(N0, N),
bagof(P, pair(N0, P), R).
pair(N0, X-Y) :-
between(0, N0, X),
between(0, N0, Y).
然后:
?- pairs(2, R).
R = [0-0, 0-1, 1-0, 1-1].
?- pairs(3, R).
R = [0-0, 0-1, 0-2, 1-0, 1-1, 1-2, 2-0, 2-1, ... - ...].
我使用传统的Prolog方式来表示一对,X-Y
(以规范形式:-(X, Y)
)而不是[X,Y]
(规范形式:.(X, .(Y, []))
)。< / p>
这个程序的好处是你可以轻松地重写它以使用另一个&#34;字母表&#34;你所选择的。
?- between(0, Upper, X).
在语义上等同于:
x(0).
x(1).
% ...
x(Upper).
?- x(X).
例如,如果我们的字母表包含b
,a
和c
(按此顺序排列!):
foo(b).
foo(a).
foo(c).
foo_pairs(Ps) :-
bagof(X-Y, ( foo(X), foo(Y) ), Ps).
然后:
?- foo_pairs(R).
R = [b-b, b-a, b-c, a-b, a-a, a-c, c-b, c-a, ... - ...].
foo/1
子句的顺序定义了您的字母顺序。联合foo(X), foo(Y)
以及对中X-Y
的顺序定义了列表中对的顺序。尝试编写例如bagof(X-Y, ( foo(Y), foo(X) ), Ps)
以查看Ps
中对的顺序。
答案 1 :(得分:2)
?- use_module(library(lambda)).
结合meta-predicate init0/3
和
xproduct//2
(“交叉产品”)只写:
?- init0(=,3,Xs), phrase(xproduct(\X^Y^phrase([X-Y]),Xs),Pss).
Xs = [0,1,2], Pss = [0-0,0-1,0-2,1-0,1-1,1-2,2-0,2-1,2-2].
一点更通用的东西怎么样?那么N
的其他值呢?
?- init0(=,N,Xs), phrase(xproduct(\X^Y^phrase([X-Y]),Xs),Pss).
N = 0, Xs = [], Pss = []
; N = 1, Xs = [0], Pss = [0-0]
; N = 2, Xs = [0,1], Pss = [0-0,0-1,
1-0,1-1]
; N = 3, Xs = [0,1,2], Pss = [0-0,0-1,0-2,
1-0,1-1,1-2,
2-0,2-1,2-2]
; N = 4, Xs = [0,1,2,3], Pss = [0-0,0-1,0-2,0-3,
1-0,1-1,1-2,1-3,
2-0,2-1,2-2,2-3,
3-0,3-1,3-2,3-3]
; N = 5, Xs = [0,1,2,3,4], Pss = [0-0,0-1,0-2,0-3,0-4,
1-0,1-1,1-2,1-3,1-4,
2-0,2-1,2-2,2-3,2-4,
3-0,3-1,3-2,3-3,3-4,
4-0,4-1,4-2,4-3,4-4]
...
它也适用于其他术语吗?订单怎么样?考虑his answer中使用的案例@Boris:
?- phrase(xproduct(\X^Y^phrase([X-Y]),[b,a,c]),Pss).
Pss = [b-b,b-a,b-c,a-b,a-a,a-c,c-b,c-a,c-c]. % succeeds deterministically