- Reference manual
:- Goal. Goal is then treated as a directive. If Term2 is a list, all terms of the list are stored in the database or called (for directives). If Term2 is of the form below, the system will assert Clause and record the indicated source location with it:
When compiling a module (see chapter
6 and the directive module/2),
will first try term_expansion/2
in the module being compiled to allow for term expansion rules that are
local to a module. If there is no local definition, or the local
definition fails to translate the term, expand_term/2
will try term_expansion/2
user. For compatibility with SICStus and Quintus Prolog,
this feature should not be used. See also expand_term/2, goal_expansion/2
It is possible to act on the beginning and end of a file by expanding
latter is supported by most Prolog systems that support term expansion
end_of_file on reaching the end of the input.
begin_of_file may be used to initialise the
compilation, for example base on the file name extension. It was added
in SWI-Prolog 8.1.1.
The current macro-expansion mechanism originates from Prolog systems in the 1980s and 1990s. It has several flaws, (1) the hooks act globally (except for definitions in a module), (2) it is hard to deal with interactions between transformations, (3) macros can not be reused between modules using the normal module export/import protocol and (4) it is hard to make source code aware tools such as the graphical debugger act properly in the context of macro expansion. Several Prolog implementations have tried to implement better expansion mechanisms. None of these solve all problems and all are largely incompatible with our current macro expansion. Future versions may provide a new mechanism to solve these issues.
Controlled interaction is provided between macro expansion defined in
a module and the
Here, SWI-Prolog uses a pipeline where the result of local
module expansion is the input for the expansion in
which is the input for the expansion in
system. See also section
Scoping, i.e., make a rule defined in a module only active
if this module is imported into the module being compiled, can be
emulated by defining the macro globally in the
and some logic to verify the macro expansion should apply. If (goal)
expansion effectively defined inlining it is good practice to
also define the predicate and have the macro expansion check that the
predicate is in scope. Here is an example.
:- module(m1, [double/2]). double(X, D) :- D is X*2. user:goal_expansion(double(X,D), D is X*2) :- prolog_load_context(module, M), predicate_property(M:double(_,_), imported_from(m1)).
For term expansion that is not related to a specific predicate we can define a sentinel predicate rather than using the goal predicate and check it is imported into the current module to verify that the module that defines the expansion is imported into the current compilation context.