## 4.6 Comparison and Unification of Terms

Although unification is mostly done implicitly while matching the head of a predicate, it is also provided by the predicate =/2.

[ISO]+Term1 = +Term2
  Unify Term1 with Term2. True if the unification succeeds. For behaviour on cyclic terms see the Prolog flag occurs_check. It acts as if defined by the following fact.

      =(Term, Term).

[ISO]+Term1 \= +Term2
  Equivalent to ``\+`Term1 = Term2`. See also dif/2.

### 4.6.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 < Atoms < Strings < Compound Terms25Strings might be considered atoms in future versions. See also section 4.22
2. Variables are sorted by address. Attaching attributes (see section 6.1) does not affect the ordering.
3. Atoms are compared alphabetically.
4. Strings are compared alphabetically.
5. Numbers are 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 flag iso is defined, all floating point numbers precede all integers.
6. Compound terms are first checked on their arity, then on their functor-name (alphabetically) and finally recursively on their arguments, leftmost argument first.

[ISO]+Term1 == +Term2
  True if Term1 is equivalent to Term2. A variable is only identical to a sharing variable.
[ISO]+Term1 \== +Term2
  Equivalent to ``\+`Term1 == Term2`.
[ISO]+Term1 @< +Term2
  True if Term1 is before Term2 in the standard order of terms.
[ISO]+Term1 @=< +Term2
  True if both terms are equal (==/2) or Term1 is before Term2 in the standard order of terms.
[ISO]+Term1 @> +Term2
  True if Term1 is after Term2 in the standard order of terms.
[ISO]+Term1 @>= +Term2
  True if both terms are equal (==/2) or Term1 is after Term2 in the standard order of terms.
compare(?Order, +Term1, +Term2)
  Determine or test the Order between two terms in the standard order of terms. Order is one of ``<``, ``>`` or ``=``, with the obvious meaning.

### 4.6.2 Special unification and comparison predicates

This section describes special purpose variations on Prolog unification. The predicate unify_with_occurs_check/2 provides sound unification and is part of the ISO standard. The predicate subsumes_term/2 defines `one-sided-unification' and is part of the ISO proposal established in Edinburgh (2010). Finally, unifiable/3 is a `what-if' version of unification that is often used as a building block in constraint reasoners.

[ISO]unify_with_occurs_check(+Term1, +Term2)
  As =/2, but using sound-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 goals below:

      1 ?- A = f(A).

      A = f(f(f(f(f(f(f(f(f(f(...))))))))))
      2 ?- unify_with_occurs_check(A, f(A)).

      No

  I.e. the first creates a cyclic-term, which is printed as an infinitely nested f/1 term (see the `max_depth` option of write_term/2). The second executes logically sound unification and thus fails. Note that the behaviour of unification through =/2 as well as implicit unification in the head can be changed using the Prolog flag occurs_check.

+Term1 =@= +Term2
  True if Term1 is `structurally equal' to Term2. Structural equivalence is weaker than equivalence (==/2), but stronger than unification (=/2). Two terms are structurally equal if their tree representation is identical and they have the same `pattern' of variables. Examples:

  > `a` | `=@=` | `A` | false
  > `A` | `=@=` | `B` | true
  > `x(A,A)` | `=@=` | `x(B,C)` | false
  > `x(A,A)` | `=@=` | `x(B,B)` | true
  > `x(A,B)` | `=@=` | `x(C,D)` | true

  Note that a term is always structurally equivalent to a copy of it. Term copying takes place in e.g., copy_term/2, findall/3 or proving a clause added with assert/1. In the pure Prolog world (i,e,, without attributed variables), =@=/2 behaves as if defined by the code below. With attributed variables, structural equivalence of the attributes is tested rather than trying to satisfy the constraints.

      A =@= B :-
              subsumes_chk(A, B),
              subsumes_chk(B, A).

  This predicate safely handles cyclic terms. A cyclic term is structurally equivalent to itself.

  The predicates =@=/2 and \=@=/2 are cycle-safe. Attributed variables are considered structurally equal iff their attributes are structurally equal. This predicate is known by the name variant/2 in some other Prolog systems.

+Term1 \=@= +Term2
  Equivalent to ```\+`Term1 =@= Term2'`.
[ISO]subsumes_term(@Generic, @Specific)
  True if Generic can be made equivalent to Specific by only binding variables in Generic. The current implementation performs the unification and ensures that the variable set of Specific is not changed by the unification. On success, the bindings are undone.26This predicate is often named subsumes_chk/2 in older Prolog dialects. The current name was established in the ISO WG17 meeting in Edinburgh (2010). The `chk` postfix was considered to refer to determinism as in e.g., memberchk/2.
term_subsumer(+Special1, +Special2, -General)
  General is the most specific term that is a generalisation of Special1 and Special2. The implementation can handle cyclic terms.
unifiable(@X, @Y, -Unifier)
  If X and Y can unify, unify Unifier with a list of Var = Value, representing the bindings required to make X and Y equivalent.27This predicate was introduced for the implementation of dif/2 and when/2 after discussion with Tom Schrijvers and Bart Demoen. None of us is really happy with the name and therefore suggestions for a new name are welcome. This predicate can handle cyclic terms. Attributed variables are handles as normal variables. Associated hooks are not executed.
?=(@Term1, @Term2)
  Succeeds, if the syntactic equality of Term1 and Term2 can be decided safely, i.e. if the result of `Term1 == Term2` will not change due to further instantiation of either term. It behaves as if defined by `?=(X,Y) :- \+ unifiable(X,Y,[_|_]).`