为什么来自swipl的反应不一致?

时间:2017-03-01 01:26:02

标签: 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).

下面我显示了在提示符下输入max([0, 1, 2], X).后我的屏幕显示的内容,然后点击 Enter

?- max([0, 1, 2], X).
X = 2 ▮

表示光标的位置。)

特别注意,解释器的下一个提示尚未出现。

在键入; 后,屏幕显示的是:

?- max([0, 1, 2], X).
X = 2 ;
false.

?- ▮

现在我终于得到了口译员的提示。

相反,下面我在提示符下输入max([2, 0, 1], X).后显示我的屏幕显示的内容,然后点击 Enter

?- max([2, 0, 1], X).
X = 2.

?- ▮

请注意,这次我立刻得到了解释器的提示 - 我不需要输入; 。此外,没有false

我发现了许多其他类似的不一致(例如,有时输出true.会出现在屏幕上,但在其他类似的情况下却不会出现。)

作为Prolog的新手,我发现这种不一致感到令人不安(更不用说令人沮丧了,因为他们不断提醒我,我确实 毫不了解 正在发生的事情)。

是否有一种简单的方法可以合理化这些不一致性?

或者,是否有一些Prolog的实现提供了比SWI-Prolog更一致和可预测的交互?

1 个答案:

答案 0 :(得分:5)

因此,正如@lurker所说,这是选择点的结果 - 有一条规则未经评估,可能产生更多解决方案。

让我们来看一个更简单的示例版本,max([0,1],X). vs max([1,0],X).

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

......你会看到行为也反过来。

希望这有助于证明此 是一致且可预测的互动,并且应该是Prolog的所有变种共享的。