A meta-predicate is a predicate that calls other predicates
dynamically, modifies a predicate or reasons about properties of a
predicate. Such predicates use either a compound term or a predicate
indicator to describe the predicate they address, e.g.,
With modules, this simple schema no longer works as each module defines
its own mapping from name+arity to predicate. This is resolved by
wrapping the original description in a term <module>:<term>,
Of course, calling assert/1
from inside a module, we expect to assert to a predicate local to this
module. In other words, we do not wish to provide this
wrapper by hand. The meta_predicate/1
directive tells the compiler that certain arguments are terms that will
be used to lookup a predicate and thus need to be wrapped (qualified)
with <module>:<term>, unless they are
In the example below, we use this to define maplist/3
inside a module. The argument `2' in the meta_predicate declaration
means that the argument is module sensitive and refers to a predicate
with an arity that is two more than the term that is passed in. The
compiler only distinguishes the values 0..9 and
which denote module-sensitive arguments, from
, which denote
modes. The values 0..9 are used by the
cross-referencer and syntax highlighting. Note that the helper
does not need to be declared as a meta-predicate because the maplist/3
wrapper already ensures that
Goal is qualified as <module>:Goal.
See the description of
:- module(maplist, [maplist/3]). :- meta_predicate maplist(2, ?, ?). %% maplist(:Goal, +List1, ?List2) % % True if Goal can successfully be applied to all % successive pairs of elements from List1 and List2. maplist(Goal, L1, L2) :- maplist_(L1, L2, Goal). maplist_(, , _). maplist_([H0|T0], [H|T], Goal) :- call(Goal, H0, H), maplist_(T0, T, Goal).
- meta_predicate +Head, ...
- Define the predicates referenced by the comma-separated list Head
as meta-predicates. Each argument of each head is a
meta argument specifier. Defined specifiers are given below.
are interpreted; the mode declarations
- The argument is a term that is used to reference a predicate with N
more arguments than the given argument term. For example:
- The argument is module sensitive, but does not directly refer to a
predicate. For example:
- The argument is not module sensitive and unbound on entry.
- The argument is not module sensitive and the mode is unspecified.
- The argument is not module sensitive and the mode is unspecified. The
is equivalent to
. It is accepted for compatibility reasons. The predicate predicate_property/2 reports arguments declared using
- The argument is not module sensitive and bound (i.e., nonvar) on entry.
- This extension is used to denote the possibly
^-annotated goal of setof/3, bagof/3, aggregate/3 and aggregate/4. It is processed similar to `0', but leaving the
- The argument is a DCG body. See phrase/3.
Each argument that is module sensitive (i.e., marked 0..9,
) is qualified with the context module of the caller if it is not already qualified. The implementation ensures that the argument is passed as <module>:<term>, where <module> is an atom denoting the name of a module and <term> itself is not a
term where the first argument is an atom. Below is a simple declaration and a number of queries.
:- meta_predicate meta(0, +). meta(Module:Term, _Arg) :- format('Module=~w, Term = ~q~n', [Module, Term]).
?- meta(test, x). Module=user, Term = test ?- meta(m1:test, x). Module=m1, Term = test ?- m2:meta(test, x). Module=m2, Term = test ?- m1:meta(m2:test, x). Module=m2, Term = test ?- meta(m1:m2:test, x). Module=m2, Term = test ?- meta(m1:42:test, x). Module=42, Term = test
The meta_predicate/1 declaration is the portable mechanism for defining meta-predicates and replaces the old SWI-Prolog specific mechanism provided by the deprecated predicates module_transparent/1, context_module/1 and strip_module/3. See also section 5.15.