`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`.

`Term`- term
`Copy`- term
`Body`- callable

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.

- A naive way to attempt to find out whether one term is a copy of another:
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.

- If you want the test to succeed even when the two terms do have
some variables in common, you need to copy one of them; for example,
identical_but_for_variables(X, Y) :- \+ \+ ( copy_term(X, Z), numbervars(Z, 0, N), numbervars(Y, 0, N), Z = Y ).

- An example of
`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.

Send feedback on this subject.