# Term\_expansion not applied

**URL:** <https://swi-prolog.discourse.group/t/term-expansion-not-applied/2731>\
**Category:** Help!\
**Tags:** how-to\
**Created:** [July 31, 2020, 9:29pm UTC](https://swi-prolog.discourse.group/t/term-expansion-not-applied/2731 "2020-07-31T21:29:52Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![stuz5000](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/stuz5000/32/940_2.png) [@stuz5000](https://swi-prolog.discourse.group/u/stuz5000)\
**Post date:** [July 31, 2020, 9:29pm UTC](https://swi-prolog.discourse.group/t/term-expansion-not-applied/2731/1 "2020-07-31T21:29:52Z")

</div>

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

```prolog
:- 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)).

```

```prolog
?- 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,

```prolog
?- 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](https://www.swi-prolog.org/pldoc/doc_for?object=term_expansion/2) Am I misreading it?

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 1, 2020, 7:08am UTC](https://swi-prolog.discourse.group/t/term-expansion-not-applied/2731/2 "2020-08-01T07:08:56Z")

</div>

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.
