copy_term/[2,3] [ISO]copy_term(+Term, -Copy)
Makes a copy of Term in which all variables have been replaced by new variables that occur nowhere outside the newly created term.
copy_term(+Term, -Copy, -Body)
Furthermore, if Term contains attributed variables,
unifies Body with a term such that executing Body
will reinstate equivalent attributes on the variables in Copy.
Otherwise, Body is unified with true.
Independent copies are substituted for any mutable terms in term. It behaves as if defined by:
copy_term(X, Y) :-
assert('copy of'(X)),
retract('copy of'(Y)).
The implementation of copy_term/2 conserves space by not copying
ground subterms.
When you call clause/[2,3] or instance/2, you get a new copy
of the term stored in the database, in precisely
the same sense that copy_term/2 gives you a new copy.
identical_but_for_variables(X, Y) :-
\+ \+ (
numbervars(X, 0, N),
numbervars(Y, 0, N),
X = Y
).
This solution is sometimes sufficient, but will not work if the two terms have any variables in common.
identical_but_for_variables(X, Y) :-
\+ \+ (
copy_term(X, Z),
numbervars(Z, 0, N),
numbervars(Y, 0, N),
Z = Y
).
copy_term/3. library(clpfd) uses
attributes to represent domain variables.
| ?- use_module(library(clpfd)).
| ?- X in 1..5, copy_term(f(X),T,Body).
T = f(_A),
Body = clpfd:(_A in 1..5),
X in 1..5 ?
yes
copy_term/2 is part of the ISO Prolog standard; copy_term/3 is not.