Prolog 为什么来自swipl的响应不一致?
我想了解为什么与Prolog 为什么来自swipl的响应不一致?,prolog,swi-prolog,prolog-toplevel,Prolog,Swi Prolog,Prolog Toplevel,我想了解为什么与swipl的交互似乎不一致 这是一个典型的例子。假设我查阅了包含以下定义的知识库: acc_max([H|T], A, Max) :- H > A, acc_max(T, H, Max). acc_max([H|T], A, Max) :- H =< A, acc_max(T, A, Max). acc_max([], A, A). max([H|T], Max) :- acc_max(T, H, Max). (该▮指示光标的位置。) 请特别注意,口译员的下一个
swipl
的交互似乎不一致
这是一个典型的例子。假设我查阅了包含以下定义的知识库:
acc_max([H|T], A, Max) :- H > A, acc_max(T, H, Max).
acc_max([H|T], A, Max) :- H =< A, acc_max(T, A, Max).
acc_max([], A, A).
max([H|T], Max) :- acc_max(T, H, Max).
(该▮代码>指示光标的位置。)
请特别注意,口译员的下一个提示尚未出现
以下是我键入后屏幕的外观;:
现在我终于得到了翻译的提示
相比之下,我在下面显示了在提示下键入max([2,0,1],X]后屏幕的外观。
,然后按Enter键:
请注意,这次我立即得到了解释器的提示-我不需要键入;。此外,没有false
我发现了许多其他类似的不一致性(例如,有时输出true.
会显示在屏幕上,但在其他类似情况下则不会)
作为Prolog的新手,我发现这样的不一致令人不安(更不用说令人沮丧了,因为它们不断提醒我,我真的不知道发生了什么)
有没有一种简单的方法可以使这些不一致合理化
或者,是否有一些Prolog实现比SWI Prolog提供更一致、更可预测的交互?因此,正如@Lougler所说,这是选择点的结果,在这些情况下,有一条规则尚未评估,可能会产生更多的解决方案
让我们来看一个更简单的例子,max([0,1],X)。
vsmax([1,0],X)。
最大值([0,1],X)。
:
这将转到acc_max([1],0,X)。
,它同时匹配acc_max([H | T],A,max):-
规则。我们按照它们出现的顺序对它们进行评估:
首先,我们看到1>0
为真,并调用acc_max([],1,X)
。这只匹配acc_max([],A,A)。
,因此我们将X统一为1。我们有办法了!但我们也有一个尚未评估的规则。这就是你看到的:
X = 1 ▮
现在我们输入;,并计算第二个acc_max([H | T],A,max):-
规则。我们看到1=<0
不是真的,所以这个规则失败了。我们现在已经没有规则可以尝试了,所以没有更多的解决方案了。因此:
X = 1 ;
false.
现在我们来看一下max([1,0],X)。
:
现在是acc\u max([0],1,X)。
。同样,我们有两条规则,按照它们出现的顺序进行评估:
首先,我们看到0>1
不正确,因此第一条规则失败,我们对第二条规则进行评估
现在我们看到0=<1
是真的,并调用acc_max([],1,X)
。这只匹配acc_max([],A,A)。
,因此我们将X统一为1(再次)。我们有解决方案,这一次我们没有未评估的规则(即,没有未探索的选择点)。现在我们看到:
X = 1.
。。。毫无疑问,在Prolog的“思想”中,没有其他解决方案。如果要颠倒规则的顺序:
acc_max([], A, A).
acc_max([H|T], A, Max) :- H =< A, acc_max(T, A, Max).
acc_max([H|T], A, Max) :- H > A, acc_max(T, H, Max).
acc_max([],A,A)。
acc|u max([H | T],A,max):-H=A,acc|u max(T,H,max)。
。。。你也会看到这种行为发生逆转
希望这有助于证明这是一种一致且可预测的交互,应该是所有Prolog变体共享的交互。这与Prolog中的“选择点”有关。在您的第一个示例中,由于Prolog查找解决方案的顺序与您的输入相对应,因此在显示解决方案X=2
后,Prolog有一个选择点可供探索,因此它搜索了更多,但没有找到更多的查询解决方案。在你的第二个例子中,X=2
已经确定,没有选择点。回答得很好,尤其是最后一段。这种顶级行为的一个重要特性是,即使没有进一步的解决方案,它也可以轻松地让您检测到意外的选择点!这一点很重要,因为选择点会阻止某些优化,当然,选择点本身也不是免费的。在这方面,当前的SWI行为比以前有了巨大的改进。您应该在示例中将X=2
s更改为X=1
,因为您的示例不包含2。@Fatalize-谢谢!偷懒复制意大利面错误,哎哟。我的X不再是2。您还剩下一个;)我在开会前匆匆忙忙,真是太好了
X = 1 ;
false.
X = 1.
acc_max([], A, A).
acc_max([H|T], A, Max) :- H =< A, acc_max(T, A, Max).
acc_max([H|T], A, Max) :- H > A, acc_max(T, H, Max).