copy_term/[2,3]
[ISO]copy_term(
+Term,
-Copy)
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, Body is unified with
the atom 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 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
. Suppose that you want to make copy_term/3
aware of the attribute tfs/1
in 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.