Unifies Copy with a copy of Term in which all variables have been replaced by brand new variables, and all mutables by brand new mutables.
copy_term(+Term, -Copy, -Body)
Furthermore, if Term contains variables with goals blocked on
them, or variables with attributes that can be interpreted as a goal
(see lib-atts), then Body is unified with the conjunction of
such goals. If no such goals are present, then Body is unified with
true. The idea is that executing Body
will reinstate blocked goals and attributes on the variables in Copy
equivalent to those on the variables in Term.
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 endeavors to conserve space
by not copying ground subterms.
When you call
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. Suppose that you want to make
copy_term/3aware of the attribute
tfs/1in some module. Then with the module file:
:- module(foo, ). :- use_module(library(atts)). :- attribute tfs/1. attribute_goal(X, put_atts(X,tfs(Y))) :- get_atts(X, tfs(Y)).
the following query works:
| ?- foo:put_atts(X, tfs(ind)), copy_term(f(X), Copy, Body). Body = foo:put_atts(_A,tfs(ind)), Copy = f(_A), put_atts(X,tfs(ind)) ? RET yes
copy_term/2 is part of the ISO Prolog standard;
copy_term/3 is not.