Archived Website: This website is a static snapshot for archival purposes only. It is no longer maintained or updated.

Home Contents Index Summary Previous Next

5.9 Compatibility of the Module System

The principles behind the module system of SWI-Prolog differ in a number of aspects from the Quintus Prolog module system.

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) (45). 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 (46). The example in figure 3 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 3 : findall/3 using modules

5.9.1 Emulating meta_predicate/1

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.