Prolog 如何匹配 "X = father(X)"?

How is Prolog matching "X = father(X)"?

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

?- father(X) = X.

Prolog 对此作出回应:

X = father(X).

但是书上写着Prolog应该这样响应:

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

为什么会这样?

短篇小说

Prolog 书可能很旧。

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

长话短说

Prolog 执行机制的核心是句法 unification of terms. Unification has similarities with pattern matching。但是,对于模式匹配,变量最多可能出现在等式符号的 一侧 上。统一变量可能出现在两边

这使得构造 cyclic terms 成为可能,即包含 自身 作为子项的术语。

可以通过执行“occurs check"---causing unification to fail in these cases. The Prolog builtin predicate 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 以使 所有 统一具有 "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"