Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog 为什么来自swipl的响应不一致?_Prolog_Swi Prolog_Prolog Toplevel - Fatal编程技术网

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)。
vs
max([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).