我是初学者,我正在使用SWI Prolog编写规则来打印有关添加两个数字的所有事实。以下是代码:
addition(X,Y,Z) :- Z is X+Y.
add(X,Y):-
between(X,Y,A),
addition(X,A,Z),
writeln(addition(X,A,Z)),
X1 is X+1,
add(X1,Y).
以下是输出:
1 ?- add(1,2).
addition(1,1,2)
addition(2,2,4)
addition(1,2,3)
addition(2,2,4)
false.
正如您所看到的那样,输出加法(2,2,4)正在重复,并且缺少加法(2,1,3)。我在这做错了什么?
答案 0 :(得分:1)
addition/3
是一个“规则”,或“谓词”,而非事实。无论如何,您已将其定义为:
% addition(X, Y, Z)
% Z is the sum of the integers X and Y
现在你要将这个谓词应用于(我猜这里)每对X和Y使得X在A和B之间,Y在A和B之间:
% add(A, B, Addition)
% Add all numbers X and Y that are between A and B
add(A, B, addition(X, Y, Z)) :-
between(A, B, X),
between(A, B, Y),
addition(X, Y, Z).
您会注意到您不需要递归(或迭代):您可以使用between/3
是非确定性的事实,并创建将在回溯时评估的选择点。
您现在可以这样称呼它:
?- add(1, 2, A).
A = addition(1, 1, 2) ;
A = addition(1, 2, 3) ;
A = addition(2, 1, 3) ;
A = addition(2, 2, 4).
您可以按;
或空格来回溯并评估下一个解决方案。
add/3
的第三个参数与addition/3
头部的术语 add/3
统一。它恰好与谓词addition/3
具有相同的名称,但它可以被称为任何内容。
如果您坚持通过一次通话打印出来,可以使用forall/2
:
?- forall(add(1, 2, A), format('~q', [A])).