The meta-logical predicate `copy_term/2`

makes a copy of a term in
which all variables have been replaced by new variables that occur
nowhere else. This is precisely the effect that would have been
obtained from the definition

copy_term(Term, Copy) :- recorda(copy, copy(Term), DBref), instance(DBref, copy(Temp)), erase(DBref), Copy = Temp.

although the built-in predicate `copy_term/2`

is more
efficient.

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. One of the uses
of `copy_term/2`

is in writing interpreters for logic-based languages;
with `copy_term/2`

available you can keep "clauses" in a Prolog data
structure and pass this structure
as an argument without having to store the "clauses" in the Prolog
database. This is useful if the set of "clauses" in your interpreted
language is changing with time, or if you want to use clever indexing
methods.

A naive way to attempt to find out whether one term is a copy of another is shown in this example:

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

`copy_term/2`

is efficient enough to use without hesitation if
there is no solution that does not require the use of meta-logical
predicates. However, for the sake of both clarity and efficiency,
such a solution should be sought before using `copy_term/2`

.