1

刚开始学习Prolog,遇到一个不懂的问题。当我问:

?- fail; true.

序言回答:

true

这是我所期望的。但是,如果我问:

?- true; fail.

序言回答:

true ;
false.

..我不明白为什么。析取运算符应该是可交换的。为什么这两个 Prolog 答案不同?

4

3 回答 3

3

另请注意,Prolog 析取运算符 ,(;)/2一般不是可交换的。例如:

?- !; write(else).
true.

?- write(then); !.
then
true ;
true.

只有在执行左分支时隐式选择点没有被切割时,才会尝试回溯的右分支。请注意一个子句,例如:

foo :- (!; write(else)).

相当于:

foo :- !.
foo :- write(else).

因此,削减和(其他)副作用导致(;)/2不表现为逻辑分离。

于 2014-03-01T12:00:52.863 回答
1

它只是顶级交互的一个细节,然后您可以根据您使用的 Prolog 解释器观察到不同的行为。

SWI-Prolog 在介绍性文档中提供了一些信息:

2.1.2 执行查询

加载程序后,可以向 Prolog 询问有关该程序的问题。下面的查询询问 Prolog 'sam' 喜欢什么食物。如果系统可以证明某个 X 的目标,系统会以 X = 响应。如果用户想要另一个解决方案,则可以键入分号 (;) 或空格键 6。如果您不想看到更多答案,请使用返回键。如果用户使用返回键或 Prolog 知道没有更多答案,Prolog 会以句点 (.) 完成输出。如果 Prolog 找不到(更多)答案,它会写为 false。

于 2014-03-01T10:46:18.863 回答
1

关于 prolog 如何显示结果的困惑。当您在 prolog 中进行查询时,它将尝试找到所有可能的答案。这意味着它将从第一个事实或子句开始,依次遍历它们,当它最终使查询为真时,显示答案。如果在寻找最后一个解决方案的过程中存在选择点,prolog 会提示用户寻找更多可能的成功解决方案。

如果是:

?- false ; true.

此查询首先查看子句false,该子句失败,然后,由于存在析取;,检查;which is之后的子句true。这成功了,prolog 显示:

true

请注意,当它找到此解决方案时,没有更多选择,因此不会提示您提供进一步的解决方案。

现在让我们看第二个例子:

?- true ; false.

Prolog 查看第一个子句 ,true并成功并告诉用户:

true

但在这种情况下,它并没有穷尽所有可能的解决方案,因为有一个析取;产生了另一种选择。因此,当您;在提示符处输入时:

true ;

您告诉 prolog 找到更多解决方案。Prolog 会返回并检查析取后的子句和遇到false。这失败了,没有其他解决方案。因此,您对进一步解决方案的请求失败并且序言输出false

true ;
false

第一个true意味着它成功了。这false意味着它没有找到更多的解决方案,并且在第二次尝试中失败了。

Prolog 的行为是通过适当的子句顺序寻求解决方案,并在您要求时将它们呈现出来,直到它失败为止。当它最终失败时,你得到false. 一些序言输出no。上述行为不是交换性问题。

于 2014-03-01T12:32:09.880 回答