刚开始学习Prolog,遇到一个不懂的问题。当我问:
?- fail; true.
序言回答:
true
这是我所期望的。但是,如果我问:
?- true; fail.
序言回答:
true ;
false.
..我不明白为什么。析取运算符应该是可交换的。为什么这两个 Prolog 答案不同?
刚开始学习Prolog,遇到一个不懂的问题。当我问:
?- fail; true.
序言回答:
true
这是我所期望的。但是,如果我问:
?- true; fail.
序言回答:
true ;
false.
..我不明白为什么。析取运算符应该是可交换的。为什么这两个 Prolog 答案不同?
另请注意,Prolog 析取运算符 ,(;)/2
一般不是可交换的。例如:
?- !; write(else).
true.
?- write(then); !.
then
true ;
true.
只有在执行左分支时隐式选择点没有被切割时,才会尝试回溯的右分支。请注意一个子句,例如:
foo :- (!; write(else)).
相当于:
foo :- !.
foo :- write(else).
因此,削减和(其他)副作用导致(;)/2
不表现为逻辑分离。
它只是顶级交互的一个细节,然后您可以根据您使用的 Prolog 解释器观察到不同的行为。
SWI-Prolog 在介绍性文档中提供了一些信息:
2.1.2 执行查询
加载程序后,可以向 Prolog 询问有关该程序的问题。下面的查询询问 Prolog 'sam' 喜欢什么食物。如果系统可以证明某个 X 的目标,系统会以 X = 响应。如果用户想要另一个解决方案,则可以键入分号 (;) 或空格键 6。如果您不想看到更多答案,请使用返回键。如果用户使用返回键或 Prolog 知道没有更多答案,Prolog 会以句点 (.) 完成输出。如果 Prolog 找不到(更多)答案,它会写为 false。
关于 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
。上述行为不是交换性问题。