The qualification of arguments with their module described in section 5.4 is realised using transparent predicates. Direct use of this underlying mechanism is now deprecated, but its understanding may still contributed to understanding modules in SWI-Prolog, while in some respects the transparent mechanism is more powerful than the meta-predicate mechanism.
Each predicate of the program is assigned a module, called its definition module. The definition module of a predicate is always the module in which the predicate was originally defined. Each active goal in the Prolog system has a context module assigned to it.
The context module is used to find predicates from a Prolog term. By default, the context module is the definition module of the predicate running the goal. For transparent predicates however, this is the context module of the goal is inherited from the parent goal. Below, we implement maplist/3 using the transparent mechanism. The code more maplist/3 and maplist_/3 is the same as in section 5.4, but now we must both the main predicate and the helper as transparent to avoid changing the context module when calling the helper.
:- module(maplist, maplist/3). :- module_transparent maplist/3, maplist_/3. maplist(Goal, L1, L2) :- maplist_(L1, L2, G). maplist_([], [], _). maplist_([H0|T0], [H|T], Goal) :- call(Goal, H0, H), maplist_(T0, T, Goal).
Note that any call that translates terms into predicates is
subject to the transparent mechanism, not just the terms passed to
module-sensitive arguments. For example, consider the code below that
counts the number of unique atoms returned as binding for a variable.
Defined using :- meta_predicate count_atom_results(-,0,-).
,
this works as expected. If we define count_atom_results/3
as transparent,
atom_result/2
is called wrongly in the module calling
count_atom_results/3.
This can be solved using strip_module/3
to create a qualified goal and a non-transparent helper predicate that
is defined in the same module.
:- module(count_atom_results, count_atom_results/3). count_atom_results(A, Goal, Count) :- setof(A, atom_result(A, Goal), As), !, length(As, Count). count_atom_results(_, _, 0). atom_result(Var, Goal) :- call(Goal), atom(Var).
The following predicates support the module-transparent interface: