I noticed that term expansion does not expand terms included in other modules. I guess this is expected behavior and something like in the subject line doesnt work.
Does this also mean that i have to repeat term_expansions in every module that uses predicates in another module that i would like to expand.
term_expansion/2 simply processes the output of read/1. Modules are not involved, except for which term_expansion/2 rules are visible and the order in which they are handled. First it calls term_expansion/2 in the module being loaded. The result is passed to user:term_expansion/2 and the result thereof to system:term_expansion/0. Next DCG translation and finally (dict) function expansion is done. The final output is passed to the backend compiler.
The predicate prolog_load_context/2 can be useful to examine the context in which the expansion takes place.
To consolidate – I put all semantic checking code into one module, say, semantic_checks.
I then noticed that including an expansion within that module doesn’t work, since at the caller site the term isn’t expanded and the call occurs.
In fact there is no expansion in the semantic_check module either – somehow the pre-processor identifies that, and doesn’t do it – in my case it would be a call to true – after expansion – which doesn’t make sense (i think) – so, this is a good thing.
The only further remedy that is efficient I see is to include the term_expansion code in all modules that have such optional code.
I guess if term_expansion would propagate “upwards” to the caller site then this would work.
Perhaps a new compile time flag/directive could be added to allow that.
I guess, the same effect could be had if conditional compilation could work at the clause level – removing a clause, based on a custom compilation flag.
Edit:
There is, i guess, another option: to wrap the expanded term into an “external” predicate – the caller calls the external predicate and inside of it, the clause is expanded to true. Leading to an “empty” call.
However, this adds a call overhead across the whole code base, where semantic checks are needed – just to overcome this problem.