Although unification is mostly done implicitly while matching the head of a predicate, it is also pro- vided by the predicate =/2.
?Term1=?Term2 [ISO]
Unify Term1withTerm2. True if the unification succeeds. For behaviour on cyclic terms see the Prolog flagoccurs check. It acts as if defined by the following fact:
=(Term, Term).
@Term1\=@Term2 [ISO]
Equivalent to\+Term1 = Term2.
This predicate is logically sound if its arguments are sufficiently instantiated. In other cases, such as ?- X \= Y., the predicate fails although there are solutions. This is due to the incomplete nature of\+/1.
To make your programs work correctly also in situations where the arguments are not yet suffi- ciently instantiated, usedif/2instead.
4.7.1 Standard Order of Terms
Comparison and unification of arbitrary terms. Terms are ordered in the so-called “standard order”. This order is defined as follows:
1. Variables<Numbers<Strings<Atoms<Compound Terms
2. Variables are sorted by address. Attaching attributes (see section7.1) does not affect the order- ing.
3. Numbersare compared by value. Mixed integer/float are compared as floats. If the comparison is equal, the float is considered the smaller value. If the Prolog flagisois defined, all floating point numbers precede all integers.
4. Stringsare compared alphabetically. 5. Atomsare compared alphabetically. 16
The predicatescyclic term/1andacyclic term/1are compatible with SICStus Prolog. Some Prolog systems supporting cyclic terms useis cyclic/1.
4.7. COMPARISON AND UNIFICATION OF TERMS 103
6. Compoundterms are first checked on their arity, then on their functor name (alphabetically) and finally recursively on their arguments, leftmost argument first.
@Term1==@Term2 [ISO]
True ifTerm1is equivalent toTerm2. A variable is only identical to a sharing variable.
@Term1\==@Term2 [ISO]
Equivalent to\+Term1 == Term2.
@Term1@<@Term2 [ISO]
True ifTerm1is beforeTerm2in the standard order of terms.
@Term1@=<@Term2 [ISO]
True if both terms are equal (==/2) orTerm1is beforeTerm2in the standard order of terms.
@Term1@>@Term2 [ISO]
True ifTerm1is afterTerm2in the standard order of terms.
@Term1@>=@Term2 [ISO]
True if both terms are equal (==/2) orTerm1is afterTerm2in the standard order of terms.
compare(?Order, @Term1, @Term2) [ISO]
Determine or test theOrderbetween two terms in the standard order of terms. Orderis one of <,>or=, with the obvious meaning.
4.7.2 Special unification and comparison predicates
This section describes special purpose variations on Prolog unification. The predicate unify with occurs check/2provides sound unification and is part of the ISO standard. The predicatesubsumes term/2defines ‘one-sided unification’ and is part of the ISO proposal estab- lished in Edinburgh (2010). Finally,unifiable/3is a ‘what-if’ version of unification that is often used as a building block in constraint reasoners.
unify with occurs check(+Term1, +Term2) [ISO]
As=/2, but usingsound unification. That is, a variable only unifies to a term if this term does not contain the variable itself. To illustrate this, consider the two queries below.
1 ?- A = f(A). A = f(A).
2 ?- unify_with_occurs_check(A, f(A)). false.
The first statement creates acyclic term, also called arational tree. The second executes log- ically sound unification and thus fails. Note that the behaviour of unification through =/2as well as implicit unification in the head can be changed using the Prolog flagoccurs check. The SWI-Prolog implementation ofunify with occurs check/2is cycle-safe and only guards against creating cycles, not against cycles that may already be present in one of the arguments. This is illustrated in the following two queries:
?- X = f(X), Y = X, unify_with_occurs_check(X, Y). X = Y, Y = f(Y).
?- X = f(X), Y = f(Y), unify_with_occurs_check(X, Y). X = Y, Y = f(Y).
Some other Prolog systems interpret unify with occurs check/2as if defined by the clause below, causing failure on the above two queries. Direct use of acyclic term/1is portable and more appropriate for such applications.
unify_with_occurs_check(X,X) :- acyclic_term(X). +Term1=@=+Term2
True if Term1 is a variant of (or structurally equivalent to) Term2. Testing for a variant is weaker than equivalence (==/2), but stronger than unification (=/2). Two termsAandB are variants iff there exists a renaming of the variables inAthat makesAequivalent (==) toBand vice versa.17 Examples:
1 a =@= A false
2 A =@= B true
3 x(A,A) =@= x(B,C) false 4 x(A,A) =@= x(B,B) true 5 x(A,A) =@= x(A,B) false 6 x(A,B) =@= x(C,D) true 7 x(A,B) =@= x(B,A) true 8 x(A,B) =@= x(C,A) true
A term is always a variant of a copy of itself. Term copying takes place in, e.g.,copy term/2, findall/3 or proving a clause added with asserta/1. In the pure Prolog world (i.e., without attributed variables), =@=/2 behaves as if defined below. With attributed variables, variant of the attributes is tested rather than trying to satisfy the constraints.
A =@= B :- copy_term(A, Ac), copy_term(B, Bc), numbervars(Ac, 0, N), numbervars(Bc, 0, N), Ac == Bc.
The SWI-Prolog implementation is cycle-safe and can deal with variables that are shared be- tween the left and right argument. Its performance is comparable to==/2, both on success and (early) failure. 18
17Row 7 and 8 of this table may come as a surprise, but row 8 is satisfied by (left-to-right)A→C,B→Aand (right-
to-left)C→A,A→B. If the same variable appears in different locations in the left and right term, the variant relation can be broken by consistent binding of both terms. E.g., after binding the first argument in row 8 to a value, both terms are no longer variant.