4

在 Prolog 中,我输入了以下查询以检查它们是否匹配:

?- father(X) = X.

Prolog 对此作出回应:

X = father(X).

但在书中写道,Prolog 应该这样回应:

X = father(father(father(father(father(father(...)))))))))).

为什么会这样?

4

1 回答 1

4

短篇故事

Prolog书可能很旧。

Prolog 解释器很可能更新很多。此外,您的解释器足够聪明,可以非常紧凑地编写循环术语。

更长的故事

Prolog 执行机制的核心是术语的句法 统一。统一与模式匹配有相似之处。但是,模式匹配变量最多可能出现在等式符号的一侧双方可能会出现统一变量。

这使得构造循环项成为可能,即,将自身包含为子项的项。

可以通过执行“发生检查”来明确防止在统一期间创建这些术语——在这些情况下导致统一失败。Prolog 内置谓词unify_with_occurs_check/2顾名思义,在这种情况下会失败。


您的初始查询:

?- X = father(X).
X = father(X).            % unification succeeds, but creates cyclic term

使用内置谓词unify_with_occurs_check/2

?- unify_with_occurs_check(X,father(X)).
false.                    % "occur check" causes unification failure

让我们设置标志occurs_check以使所有统一都有一个“发生检查”:

?- set_prolog_flag(occurs_check,true).
true.                     % all following unifications will do "occurs check"

?- X = father(X).         % the exact same query succeeded above.
false.                    % here it fails because of the "occurs check"
于 2015-04-24T17:59:07.413 回答