1 a =@= Afalse 2 A =@= Btrue 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 between the left and right argument. Its performance is comparable to ==/2, both on success and (early) failure. 71The current implementation is contributed by Kuniaki Mukai.
This predicate is known by the name variant/2 in some other Prolog systems. Be aware of possible differences in semantics if the arguments contain attributed variables or share variables.72In many systems variant is implemented using two calls to subsumes_term/2.