Previous Up Next

4.10 Module System

4.10.1 Overview

The ECLiPSe module system controls the visibility of predicate names, syntax settings (structures, operators, options, macros), and non-logical store names (records, global variables). Predicates and syntax items can be declared local or they can be exported and imported. Store names are always local.

4.10.2 Making a Module

A source file can be turned into a module by starting it with a module directive. A simple module is:

:- module(greeting).
:- export hello/0.

hello :-
        who(X),
        printf("Hello %w!%n", [X]).

who(world).
who(friend).

This is a module which contains two predicates. One of them, hello/0 is exported and can be used by other modules. The other, who/1 is local and not accessible outside the module.

4.10.3 Using a Module

There are 3 ways to use hello/0 from another module. The first possibility is to import the whole ”greeting” module. This makes everything available that is exported from ”greeting”:

:- module(main).
:- import greeting.

main :-
        hello.

The second possibility is to selectively only import the hello/0 predicate:

:- module(main).
:- import hello/0 from greeting.

main :-
        hello.

The third way is not to import, but to module-qualify the call to hello/0:

:- module(main).

main :-
        greeting:hello.

4.10.4 Qualified Goals

The module-qualification using :/2 is also used to resolve name conflicts, i.e. in the case where a predicate of the same name is defined in more than one imported module. In this case, none of the conflicting predicates is imported - an attempt to call the unqualified predicate raises an error. The solution is to qualify every reference with the module name:

:- lib(ic).       % exports $>= / 2
:- lib(eplex).    % exports $>= / 2

    ..., ic:(X $>= Y), ...
    ..., eplex:(X $>= Y), ...

A more unusual feature, which is however very appropriate for constraint programming, is the possibility to call several versions of the same predicate by specifying several lookup modules:

    ..., [ic,eplex]:(X $>= Y), ...

which has exactly the same meaning as

    ..., ic:(X $>= Y), eplex:(X $>= Y), ...

Note that the modules do not have to be known at compile time, i.e. it is allowed to write code like

    after(X, Y, Solver) :-
        Solver:(X $>= Y).

This is however likely to be less efficient because it prevents compile-time optimizations.

4.10.5 Exporting items other than Predicates

The most commonly exported items, apart from predicates, are structure and operator declarations. This is done as follows:

:- module(data).
:- export struct(employee(name,age,salary)).
:- export op(500, xfx, reports_to).
...

Such declarations can only be imported by importing the whole module which exports them, i.e. using import data..

⊙
For more details see the User Manual chapter on Modules.

Previous Up Next