Next: , Previous: , Up: ref-lte   [Contents][Index]

4.8.7 Copying Terms

The meta-logical predicate copy_term/2 makes a copy of a term in which all variables have been replaced by brand new variables, and all mutables by brand new mutables. 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)),
   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, then 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

Please note: If the term being copied contains attributed variables (see lib-atts) or suspended goals (see ref-sem-sec), then those attributes are not retained in the copy. To retain the attributes, you can use:

copy_term(Term, Copy, Body)

which in addition to copying the term unifies Body with a goal such that executing Body will reinstate the attributes in the Copy. Copy as well as Body contain brand new (unattributed) variables only.

Send feedback on this subject.