Term_expansion/2 in a module, user or system?

Hi!

I’m experimenting with modules and have the following module:

:-module(
    moduleTest, 
    [
        printSomething/1, 
        op(1200, xfx, ⇐)
    ]
).

system: term_expansion(A ⇐ B, A:- B).

printSomething(X):- format('~w', X).

In another file i then have:

:-use_module('moduleTest.pl').

test ⇐ printSomething(bananas).

which works as expected.

But my question is: Is it correct to use the prefix system: before term_expansion(A ⇐ B, A:- B).? Or should i be using user: ? I am actually not sure about what i’m doing :upside_down_face:

1 Like

term and goal expansion follow the module inheritance path, first doing all work in the current module, than in user and finally in system. SWI-Prolog libraries follow a different inheritance path, going directly from the module to system. The same logic is used for operators.

So, typically you should define such things in user as defining in system may impact library modules and cause the libraries to misbehave.

2 Likes

Thanks for your help Jan!

I’ve noticed that some things are in module prolog … is there a unified documentation of user, prolog, system?

1 Like

For short, user is the place to be if you do not use modules. SWI-Prolog also allows using it for defining stuff that affects all modules, such as global operators and predicates. That has great value for dealing with emulating other Prolog systems, but should probably be handled differently.

system sits above user and is where all built-in predicates reside or are imported to and is the direct super-module of the libraries. Typically, don’t touch. Nothing really prevents you from doing so though.

prolog is a module that have become fashionable for holding hooks. As system should not be touched, this is not the ideal place. Quintus derived systems used user for this, but this pollutes the user module which we should (IMO) normally leave empty (unless you decide not to use modules at all). So, by intend the prolog module only contains multifile predicates. It is not reserved in any way though, so if you want to misuse it for anything else your are free to do so.

Note that module inheritance affects:

  • operators (if the operator is not defined or cancelled locally, look in the super)
  • predicates (if a predicate is undefined, look in the super)
  • Macro expansion (term/goal): expand locally, next feed the result through the expansion rules of the super (pipeline).
3 Likes

Maybe this text could be added as a new section in https://www.swi-prolog.org/pldoc/man?section=modules ?