Skip to content
Ken Bowen edited this page Nov 18, 2015 · 17 revisions

ALS Prolog provides a module system to facilitate the creation and maintenance of large programs. The main purpose of the module system is to partition procedures into separate groups to avoid naming conflicts between those groups. The module system provides controlled access to procedures within those groups. The ALS module system only partitions procedures, not constants. This means that the procedure foo/2 may have different meanings in different modules, but that the constant bar is the same in every module.

###3.1 Declaring a Module

New modules are created when the compiler sees a module declaration in a source file for the first time during a consult or reconsult. Every module has a name which must be a non-numeric constant. Here are a few valid module declarations:

module dingbat.
module parser.
module compiler.

Following a module declaration, all clauses will be asserted into that module using assertz until the end of the module or until another module declaration is encountered. In addition, any commands that appear within the scope of the module will be executed from inside that module. The end of a module is signified by an endmod. The following example defines the predicate test/0 in two different modules. The definitions don’t conflict with each other because they appear in different modules.

module mod1.
test :- write(’Module #1’), nl.
endmod.
module mod2.
test :- write(’Module #2’), nl.
endmod.

Clauses which are not contained inside an explicit module declaration are added to the default module user.

If a module declaration is encountered for a module that already exists, the clauses appearing within that declaration are simply added to the existing contents of that module, following the clauses which have already been inserted in that module. In this way, the code for a single module can be spread across multiple files ---- as long as each file has the appropriate module declaration and ends with a corresponding end mod.

The end of a file does not signal the end of the module as shown in the following conversation with the Prolog shell:

?- [user].
Consulting user ...
module hello.
a.
b.
c.
user consulted
yes.
?- [user].
Consulting user ...
module hello.
d.
endmod.
user consulted
yes.
?- listing(hello:_).
% hello:a/0
a.
% hello:b/0
b.
% hello:c/0
c.
% hello:d/0
d.

If module hello had been closed by the EOF of the user file, then the d/0 fact would have appeared in the user module instead of the hello module. Consequently, it is important to always terminate a module with endmod. That is, module and end mod should always be used in matched pairs.

###3.2 Sharing Procedures Between Modules By default, all the procedures defined in a given module are visible only within that module. This is how name conflicts are avoided. However, the point of the module system is to allow controlled access to procedures defined in other modules. This task is accomplished by using export declarations and use lists . Export declarations render a given procedure visible outside the module in which it is defined, while use lists specify visibility relationships between modules. Each module has a use list.

###3.3 Finding Procedures in Another Module

Whenever the Prolog system tries to call a procedure, it first looks for that procedure in the module where the call occured. This is done automatically, and independently of use list and inheritance declarations. If the called procedure p/n is not defined in some module, say M, from which it is called, then the system will search the use list of M for a module M1 that exports the procedure (p/n) in question. If such a module M1 is found, then all occurrences of the procedure p/n in the calling module M will be ‘forwarded’ to the procedure p/n defined in the module M1. After the procedure p/n has been forwarded from module M to another module M1, all future calls to procedure p/n from within M will be automatically routed to the proper place in M1 without further intervention of the module system. The forwarding process is determinate. That is, once a call on procedure p/n has been forwarded to p/n in module M1, even if backtracking occurs, ALS Prolog will not attempt to locate another module M2 containing a procedure to which p/n can be forwarded. Finally, if no module on the use list for M exports the procedure in question (p/n), then the procedure p/n is undefined in M, and the call fails.

####3.3.1 Export Declarations

Clone this wiki locally