Roni Koren Kurtberg
Roni Koren Kurtberg

Reputation: 515

anonymous variables - prolog - a few queries

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

Answers (1)

Paulo Moura
Paulo Moura

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

Related Questions