Although unification is mostly done implicitly while matching the head of a predicate, it is also provided by the predicate =/2.
=(Term, Term).
\+Term1 = Term2Comparison and unification of arbitrary terms. Terms are ordered in the so called ``standard order''. This order is defined as follows:
\+Term1 == Term2<>=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 predicates subsumes/2 and subsumes_chk/2 define `one-sided-unification' and are found in many Prolog systems. Finally, unifiable/3 is a `what-if' version of unification that is often used as a building block in constraint reasoners.
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.
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'.
subsumes(General, Specific) :-
        term_variables(Specific, SVars),
        General = Specific,
        term_variables(SVars, SVars2),
        SVars == SVars2.
\+ \+ subsumes(Generic, Specific).Term1 == Term2 
will not change due to further instantiation of either term. It is 
defined similar to ?=(X,Y) :- once((X==Y ; X \= Y)). 
However, attributed variables are not considered. A case of different 
behaviour is:
?- freeze(X,X=1),Y=2, ?=(X,Y). false. ?- freeze(X,X=1), Y=2, once((X==Y ; X \= Y)). Y = 2, freeze(X, X=1).