 # Term_expansion not applied

I’m struggling with a simple example of term_expansion. I seems to be missing a trick, or simply having a brain fart.

``````:- module(scratch,[
z/2,
x/1
]).

term_expansion(q(A,B), z(B,A)).

q(1,2).      % ==>  z(2,1).

x(q(1,2)).   % ==>   x(z(2,1)).
``````
``````?- use_module(scratch).
true.

?- scratch:q(X,Y).
ERROR: Unknown procedure: scratch:q/2 (DWIM could not correct goal)  % Expected

?- scratch:z(2,1).
true.
``````

So far so good. But,

``````?- scratch:x(X).
X = q(1, 2).          % X = z(2,1) expected.
``````

Am I right in thinking that `q(A,B)` is a Term in both `q(1,2).` and `x(q(1,2)).`? So why isn’t the replacement `x(q(1,2)) => x(z(2,1)).` applied?

I thought that perhaps term_expansion applies only to the clauses asserted during consultion (and not their subcomponent terms) – however, the docs says its applied to “all terms read during consulting” https://www.swi-prolog.org/pldoc/doc_for?object=term_expansion/2 Am I misreading it?

term_expansion/2 is only called on the toplevel term. If you want to perform transformations inside the term you need to do so yourself. An intermediate step is provided by goal_expansion/2, which is called for each goal term in a clause.

Also note that term_expansion/2 is called only once per term, i.e., only the first answer of the expansion is used. goal_expansion/2 is called on the goal until fixed point is reached.

2 Likes