While working on a directive to allow iterating through succeeding depths of recursion for an arbitrary predicate (even if the predicate does not terminate in normal prolog), it was pointed out that I should use functor/3 instead of copy_term/2 to obtain a most generic term.
What is the difference between these two if the argument of the compound terms is not instantiated?
In my code it turns out the term generated by functor/3 is more generic, than the one produced by copy_term/2 as Jan pointed out.
I can’t grasp why the difference, if T is not instantiated.
EDIT: I understand copy_term/2 shares ground terms and functor/3 does not (of course), but here we’re dealing with an argument which is not instantiated.
I see. In your code the term that you copy is the most general term, so your copy will be most general too.
Probably using functor/3 is faster though. copy_term/2 has to do a lot of work to figure out variable sharing, subtem sharing, cycles and ground terms. functor/3 simply allocates a term and fills it with variables.
In my original code I was doing something like this:
functor(Head,Pred,Arity),
% ...some code here...
wrap_predicate(M:Head, iterate_depth, OrigPred,
(
% We need to run iterate_depth_/4 only
% one time, on entry. Recursive calls
% need to be done normally (as if they
% were not wrapped)
prolog_current_frame(F),
prolog_frame_attribute(F,parent,P),
copy_term(Head,Head1),
( prolog_frame_attribute(P,parent_goal,Head1)
-> call(OrigPred)
; iterate_depth_(OrigPred, Start, Step, End, _Result)
)
)
).
But this worked erratically until I changed it to functor/3 like you suggested.