This library package is supplied to solve the following problem: often you
write code that works more than one way around except that this requires
twice, and one of the calls must therefore precede the other. For
reverse_terms(Term1, Term2) :- functor(Term1, F, N), % *** functor(Term2, F, N), % *** reverse_terms(N, 1, Term1, Term2). reverse_terms(0, _, _, _) :- !. reverse_terms(Z, A, Term1, Term2) :- arg(Z, Term1, Arg), arg(A, Term2, Arg), Y is Z-1, B is A+1, reverse_terms(Y, B, Term1, Term2).
As written, this can only be used to find Term2 given Term1.
If you swapped the two *** lines, you could find Term1 given
Term2, but then could not find Term2 given Term1. You can make a
bidirectional version of
reverse_terms/2 by using the
same_functor/3 in place of the *** lines:
reverse_terms(Term1, Term2) :- same_functor(Term1, Term2, N), % *** reverse_terms(N, 1, Term1, Term2).
library(samefunctor) defines the following predicates:
same_functor(T1, T2, F, N) if functor(T1, F, N) and functor(T2, F, N) are both true.
Either Term1, or Term2, or both Symbol and Arity
should be instantiated. This is the most general variant.
same_functor/3is appropriate and the greater generality of
same_functor/4is not needed.
same_functor/4 has the same argument order as
functor/3 except that it has two "term" arguments at the front.
Whenever a predicate's arguments include a functor specification expressed as
two arguments, the function symbol and its arity,
those two arguments should always
be adjacent, with the function symbol first and the arity immediately
same_functor/4 obey this rule.