11.3.93 goal_expansion/5 [hook]


M:goal_expansion(+Goal1, +Layout1, +Module, -Goal2, -Layout2)

Defines transformations on goals while clauses are being compiled or asserted, and during meta-calls.



Goal to transform.


Layout of goal to transform.


Source module of goal to transform.


Transformed goal.


Layout of transformed goal.


Defines transformations on goals while clauses are being consulted, compiled or asserted, after any processing by user:term_expansion/6 of the terms being read in. It is called for every simple Goal1 in the source module Module found while traversing the clause bodies. Typically, Module has imported the predicate Goal1 from module M.

If it succeeds, Goal1 is replaced by Goal2; otherwise, Goal1 = Goal2. Goal2 may be an arbitrarily complex goal, and M:goal_expansion/5 is recursively applied to its subgoals.

Please note: the arguments of built-in meta-predicates such as call/1, setof/3 and on_exception/3 are not subject to such compile-time processing.

This predicate is also used to resolve any meta-calls to Goal1 at runtime via the same mechanism. If the transformation succeeds, Goal2 is simply called instead of Goal1. Otherwise, if Goal1 is a goal of an existing predicate, that predicate is invoked. Otherwise, error recovery is attempted by user:unknown_predicate_handler/3.

M:goal_expansion/5 can be regarded as a macro expansion facility. It is used for this purpose to support the interface to attributed variables in library(atts), which defines the predicates M:get_atts/2 and M:put_atts/2 to access module-specific variable attributes. These “predicates” are actually implemented via the M:goal_expansion/5 mechanism. This has the effect that calls to the interface predicates are expanded at compile time to efficient code.

For accessing aspects of the load context, e.g. the name of the file being compiled, the predicate prolog_load_context/2 (see ref-lps-lco) can be used.

Layout1 and Layout2 are for supporting source-linked debugging in the context of goal expansion. The predicate should construct a suitable Layout2 compatible with Term2 that contains the line number information from Layout1. If source-linked debugging of Term2 is not important, Layout2 should be [].


Exceptions are treated as failures, except an error message is printed also.

See Also


Send feedback on this subject.