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 ascall/1
,setof/3
andon_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.