meta_predicate
DeclarationSometimes 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, 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 respect to the module containing the call to the sort routine. Suppose that the sort routine is
mysort(CompareProc, InputList, OutputList)
An appropriate meta_predicate
declaration for this is
:- meta_predicate mysort(:, +, -).
The significant
argument in the mysort/3
term is the `:', which indicates that
module name expansion is required for this argument. This means that
whenever a goal mysort(
A,
B,
C)
appears in a clause, it will be
transformed at load time into mysort(
M:
A,
B,
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 (see library(samsort)
for the full program):
:- module(samsort, [samsort/3]). :- meta_predicate samsort(:, +, ?), sam_sort(+, :, +, +, ?). samsort(_, [], []) :- !. samsort(Order, List, Sorted) :- sam_sort(List, Order, [], 0, Sorted). . . .
Normally, the 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 samsort/3
,
which also has a meta_predicate
declaration. Therefore it is
not useful to attach the module name (samsort
) to Order in the call of
sam_sort/5
.
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:
The reason for `+', `-' and `*' is simply so that the information
contained in a DEC-10 Prolog-style “mode” declaration may be represented
in the meta_predicate
declaration if you wish. There are many examples of
meta_predicate
declarations in the library.