【问题标题】:How to print all the facts in prolog如何在序言中打印所有事实
【发布时间】:2014-08-27 13:16:06
【问题描述】:

我是一个初学者,我正在使用 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.

如您所见,输出addition(2,2,4) 重复,而addition(2,1,3) 缺失。我在这里做错了什么??

【问题讨论】:

  • 一开始就避免使用像writeln这样的副作用。
  • add/2究竟应该是什么意思?从您写的谓词或您的描述中看不太清楚。

标签: prolog


【解决方案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 的第三个参数与add/3 头部的term addition/3 统一。它恰好与谓词addition/3 同名,但它可以被称为任何名称。

如果您坚持通过一次调用将其打印出来,您可以使用forall/2

?- forall(add(1, 2, A), format('~q', [A])).

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 2016-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多