在 Prolog 中,我输入了以下查询以检查它们是否匹配:
?- father(X) = X.
Prolog 对此作出回应:
X = father(X).
但在书中写道,Prolog 应该这样回应:
X = father(father(father(father(father(father(...)))))))))).
为什么会这样?
在 Prolog 中,我输入了以下查询以检查它们是否匹配:
?- father(X) = X.
Prolog 对此作出回应:
X = father(X).
但在书中写道,Prolog 应该这样回应:
X = father(father(father(father(father(father(...)))))))))).
为什么会这样?
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"