In Prolog I entered following query to check if they match:
?- father(X) = X.
Prolog responded with this:
X = father(X).
But in the book it is written that Prolog should respond like this:
X = father(father(father(father(father(father(...)))))))))).
Why is this happening?
The Prolog book is probably old.
The Prolog interpreter is most likely a lot newer. Also, your interpreter is smart enough to write a cyclic term very compactly.
At the heart of Prolog's execution mechanism lies syntactic unification of terms. Unification has similarities with pattern matching. However, with pattern matching variables may occur on at most one side of the equation sign. With unification variables may occur on both sides.
This makes it possible to construct cyclic terms, i.e., terms that contain themselves as a subterm.
It is possible to explicitly prevent these terms from being created during unification by performing an "occurs check"---causing unification to fail in these cases. The Prolog builtin predicate unify_with_occurs_check/2
does as its name suggests and fails in such cases.
Your initial query:
?- X = father(X).
X = father(X). % unification succeeds, but creates cyclic term
Using the builtin predicate unify_with_occurs_check/2
:
?- unify_with_occurs_check(X,father(X)).
false. % "occur check" causes unification failure
Let's set the flag occurs_check
to make all unifications have an "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"