Sometimes a user-defined predicate will require module name expansion (see
ref-mod-mne). This can be specified by providing a
meta_predicate declaration for that procedure.
Module name expansion is needed whenever the argument of a predicate has some module-dependent meaning. For example, if this argument is a goal that is to be called, then it will be necessary to know in which module to call it—or, if the argument is a clause to be asserted, in which module it should go.
Consider, for example, a sort routine to which the name of the
comparison predicate is passed as an argument. In this example, the
comparison predicate should be called, with two arguments like the
@=</2, with respect to the module
containing the call to the sort routine. Suppose that the sort
mysort(CompareProc, InputList, OutputList)
meta_predicate declaration for this is
:- meta_predicate mysort(2, +, -).
The significant argument in the
mysort/3 term is the ‘2’,
which indicates that module name expansion is required for this argument
and that two additional arguments will be added when this argument is
invoked as a goal. This means that whenever a goal
mysort(A, B, C) appears in a clause, it will be
transformed at load time into
C), where M is the source module. There are some
exceptions to this compile-time transformation rule; the goal is not
transformed if either of the following applies:
The reason for (2)
is that otherwise module name expansion could
build larger and larger structures of the form Mn: … :M2:M1:Goal.
For example, consider the following program fragment adapted from the
library(samsort) for the full program):
:- module(samsort, [samsort/3]). :- meta_predicate samsort(2, +, ?), sam_sort(+, 2, +, +, ?). samsort(_, , ) :- !. samsort(Order, List, Sorted) :- sam_sort(List, Order, , 0, Sorted). . . .
sam_sort/5 goal in this example would have the module name of its
second argument expanded thus:
sam_sort(List, samsort:Order, , 0, Sorted)
because of the
meta_predicate declaration. However, in this
situation the appropriate source module will have already been
attached to Order because it is the first argument of
which also has a
meta_predicate declaration. Therefore it is
not useful to attach the module name (
samsort) to Order in the call of
The argument of a
meta_predicate declaration can be a term, or a
sequence of terms separated by commas. Each argument of each of these
terms must be one of the following:
requires module name expansion
If the argument will be treated as a goal, then it is better to explicitly indicate this using an integer; see the next item.
a non-negative integer.
This is a special case of ‘:’ which means that the argument can be
made into a goal by adding nsuppressed additional arguments. E.g., if
the argument will be passed to
should be used.
An integer is treated the same as ‘:’ above by the SICStus runtime. Other tools, such as the cross referencer (see The Cross-Referencer) and the SICStus Prolog IDE (see SICStus Prolog IDE), will use this information to better follow predicate references in analyzed source code.
If the number of extra arguments is unknown or varies, then the generic
: is always safe to use, but will give less accurate results from
source analysis tools.
The reason for ‘+’, ‘-’ and ‘?’ is simply so that the information
contained in a DEC-10 Prolog-style “mode” declaration may be represented
meta_predicate declaration if you wish. There are many examples of
meta_predicate declarations in the library.
Prior to release 4.1, only
: (colon) was used and the
integer form was undocumented (but supported, e.g. by the cross