我正在做一个程序,结果是一对值 [X,Y],按字典序排列,介于 0 和 N-1 之间
我现在有这个:
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.
我不想要第二个答案(假),只想要第一个。我希望它在找到答案后停止。有什么想法吗?
最佳答案
请记住,有一种非常更容易的方法来获得您想要的东西。如果确实 X 和 Y 都应该是整数,请使用 between/3
枚举整数(此处的“字典顺序”与自然数的顺序相同: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, []))
)。
这个程序的好处是您可以轻松地重新编写它以使用您选择的另一个“字母表”。
?- 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
in the pair 定义列表中对的顺序。尝试写例如 bagof(X-Y, ( foo(Y), foo(X) ), Ps)
查看 Ps
中的对顺序是什么.
关于list - 按字典顺序创建值对 0 到 n-1 的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31506781/