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"
在 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"