Extension of target modules passed to library meta predicates

Using SWI-Prolog (multi-threaded, 64 bit, version 7.3.5), we continue step by step:

  • Define nonterminal a//1 in the dcgAux module (pronounced: "di-SEE-goh"):

      : - module (dcgAux, [a // 1]).
    
     a (0) -> [].
     a (s (N)) -> [a], a (N).
    
  • Run the following queries: phrase/2 and apply:foldl/4 :

      ? - use_module ([library (apply), dcgAux]).
     true
    
     ? - phrase (foldl (a, [s (0), s (s (0))]), [a, a, a]).
     true
    
     ? - phrase (foldl (dcgAux: a, [s (0), s (s (0))]), [a, a, a]).
     true
    
     ? - phrase (apply: foldl (dcgAux: a, [s (0), s (s (0))]), [a, a, a]).
     true
    
     ? - phrase (apply: foldl (a, [s (0), s (s (0))]), [a, a, a]).
     ERROR : apply: foldl_ / 4: Undefined procedure: apply: a / 3
    

    no! Absolutely unexpected - and not very good. Did we miss the unknown unknown?

  • To get rid of the above annoying behavior, we must first find out the cause (s) causing it:

      ? - import_module (apply, M), M = user.
     false
    
     ? - phrase (apply: foldl (a, [s (0), s (s (0))]), [a, a, a]).
     ERROR : apply: foldl_ / 4: Undefined procedure: apply: a / 3
    
     ? - add_import_module (apply, user, end).
     true
    
     ? - import_module (apply, M), M = user.  % sic!
     M = user .  % `? - import_module (apply, user) .` fails!
    
     ? - phrase (apply: foldl (a, [s (0), s (s (0))]), [a, a, a]).
     true
    

What's happening? As I see it:

  • The extension of the target module passed to foldl/4 is limited.
  • Quote from the SWI-Prolog manual page on import_module/2 :

    All normal modules import only the user who imports from the system.

  • SWI library(apply) only "inherits" from system , but not user .

  • If we clone the apply module into apply (and propagate the new module name), we observe:

      ? - use_module (applY).
     true
    
     ? - phrase ( applY : foldl (a, [s (0), s (s (0))]), [a, a, a]).  % was: ERROR
     true  % now: OK!
    

Share your ideas on how I could / should continue!

(I have not yet conducted a similar experiment with other Prolog processors.)

+5
source share
1 answer

This is an integral feature / error of predicate-based module systems in the Quintus tradition. That is, this modular system was first developed for Quintus Prolog. Then it was adopted by SICStus (after 0.7 1 ), then (more or less) at 13211-2, then by YAP and (with some changes) SWI.

The problem here is exactly what explicit qualification means. As long as the goal is not a meta predicate, things are trivially decidable: take the module of the most internal qualification. However, as soon as you have meta-predicates, meta-arguments should be informed about this module; or not. If the meta arguments are informed, we say that the colon sets the calling context, if not, then other means are needed for this purpose.

The Quint tradition takes meta arguments into account. As a result, you see. As a result, you cannot directly compare two implementations of the same meta predicate in the same module. There are other approaches, the most important IF and ECLiPSe, which do not change the calling context through the colon. This has its advantages and disadvantages. It is best to compare them in each case.

Here is a recent case. Take lambdas and how they fit into a module in SICStus, in SWI and in ECLiPSe .

As for the Quintus / SICStus / YAP / SWI module system, I would prefer to use it most conservatively. I.e:

  • there is no explicit qualification, consider infix : as something internal

  • clean, verified meta-declarations - insert the undefined predicate to see if the cross reference can detect the problem (in the SWI, which is check or make ).

  • use a common subset, avoid many bells and whistles - there are many well-marked extensions ...

  • make more universal things on foot: reload by adding the appropriate module and adding a dummy definition. Similarly, instead of renaming, import things from the interface module.

  • always remember that in modular systems there are substantial limitations. No matter how you twist or rotate it. There is no completely seamless modular system; for the very purpose of the modules, it is necessary to separate code and problems.


1: To be precise, the SICStus adaptation of Quintus modules included only : for module-sensitive arguments in meta_predicate . The integers 0..9 , which are so important for higher order call/N based programming, were introduced only 20 years later. 4.2.0 was released on 2011-03-08 .

+6
source

All Articles