Reputation: 515
Can you help me understand the engine of answering the next queries?
?- _ = _.
?- _ = 1.
?- A = _, B = _, C = A + B + 1.
And some extra query (not related to anonymous variables):
?- B = A + 1, A = C, C = B - 1.
I know the answers to above queries, but I want to understand how prolog find those answers :)
Thanks!
Upvotes: 0
Views: 532
Reputation: 18663
_
is called the _anonymous variable. Each occurrence of _
is a different variable. You can observe it easily by using the standard write_canonical/1
built-in predicate. For example:
| ?- write_canonical(_ = _).
=(_279,_280)
yes
A variable can be unified with any term, including other variable, as you observe in your queries. Note that the standard =/2
built-in predicate performs unification, not equality or arithmetic expression evaluation. Unification takes two terms and succeeds if the two terms are the same or can be made the same by unifying any variables in the terms. For example:
| ?- A + 1 = 2 + B.
A = 2
B = 1
(1 ms) yes
A query such as:
| ?- write_canonical(B = A + 1), nl, B = A + 1, write_canonical(B).
=(_279,+(_280,1))
+(_280,1)
B = A+1
yes
unifies the variable B
with the compound term +(A,1)
. _279
and _280
are the internal variable representation for, respectively, B
and A
. Different Prolog systems print these internal representation differently. For example, using SWI-Prolog:
?- write_canonical(B = A + 1), nl, B = A + 1, write_canonical(B).
=(_,+(_,1))
+(_,1)
B = A+1.
Regarding your extra query, B = A + 1, A = C, C = B - 1
, it creates cyclic terms. Consider the simpler query:
| ?- X = f(X).
The result and consequent variable binding report by the Prolog top-level depends on a specific Prolog system handles cyclic terms. For example, in GNU Prolog you will get:
| ?- X = f(X).
cannot display cyclic term for X
yes
while SICStus Prolog reports:
| ?- X = f(X).
X = f(f(f(f(f(f(f(f(f(f(...)))))))))) ?
Cyclic terms are useful for some applications, e.g. coinductive logic programming. But the handling of cyclic terms is not standardized and varies among Prolog systems. The ISO Prolog standard provides a built-in predicate, unify_with_occurs_check/2
, that checks if unification will create a cyclic term, preventing it. For example:
| ?- unify_with_occurs_check(X, f(X)).
no
| ?- unify_with_occurs_check(X, Y).
Y = X
(1 ms) yes
Upvotes: 1