The principles behind the module system of SWI-Prolog differ in a number of aspects from the Quintus Prolog module system.
system and user
modules are visible in all other modules as well.
The meta_predicate/1 declaration causes the compiler to tag arguments that pass module sensitive information with the module using the :/2 operator. This approach has some disadvantages:
Unfortunately the transparent predicate approach also has some disadvantages. If a predicate A passes module sensitive information to a predicate B, passing the same information to a module sensitive system predicate both A and B should be declared transparent. Using the Quintus approach only A needs to be treated special (i.e., declared with meta_predicate/1) (52). A second problem arises if the body of a transparent predicate uses module sensitive predicates for which it wants to refer to its own module. Suppose we want to define findall/3 using assert/1 and retract/1 (53). The example in figure 4 gives the solution.
:- module(findall, [findall/3]).
:- dynamic
solution/1.
:- module_transparent
findall/3,
store/2.
findall(Var, Goal, Bag) :-
assert(findall:solution('$mark')),
store(Var, Goal),
collect(Bag).
store(Var, Goal) :-
Goal, % refers to context module of
% caller of findall/3
assert(findall:solution(Var)),
fail.
store(_, _).
collect(Bag) :-
...,
|
| Figure 4 : findall/3 using modules |
The Quintus meta_predicate/1
directive can in many cases be replaced by the transparent declaration.
Below is the definition of meta_predicate/1
as available from library(quintus).
:- op(1150, fx, (meta_predicate)).
meta_predicate((Head, More)) :- !,
meta_predicate1(Head),
meta_predicate(More).
meta_predicate(Head) :-
meta_predicate1(Head).
meta_predicate1(Head) :-
Head =.. [Name|Arguments],
member(Arg, Arguments),
module_expansion_argument(Arg), !,
functor(Head, Name, Arity),
module_transparent(Name/Arity).
meta_predicate1(_). % just a mode declaration
module_expansion_argument(:).
module_expansion_argument(N) :- integer(N).
|
The discussion above about the problems with the transparent mechanism show the two cases in which this simple transformation does not work.