Source-level stateles modules

(module)/1
current_module/1
is_module/1          - checks/generates an existing module-name
module_call/2, ':'/2 - calls a predicate hidden in a module
module_name/3        - adds the name of a module to a symbol
module_predicate/3   - adds the name of a module to a goal
modules/1            - gives the list of existing modules

The following example:

:-module m1.
:-public d/1.

a(1).
a(2).
a(3).
a(4).

d(X):-a(X).

:-module m2.

:-public b/1.

b(X):-c(X).

c(2).
c(3).
c(4).
c(5).
c(6).

:-module m3.

:-public test/1.

test(X):-b(X),d(X).

:-module user.

go:-modules(Ms),write(Ms),nl,fail.
go:-test(X),write(X),nl,fail.

Executiong ?-go. will generate the following output:

[user/0,m1/0,m2/0,m3/0]
2
3
4

Starting with version 3.30, predicates in the BinProlog system itself which are not intended to be used by applications, are hidden in the module prolog but can be accessed by calling them with 'prolog:my_predicate'(...).

Explicit naming of the module where the hidden predicate is defined should be used when call/1, findall/3 etc. uses a hidden predicate, even if it is in the module itself.

This draconian constraint is motivated by simplicity of BinProlog's stateless purely source-level module system. Basically predicates in a module have their names prefixed as in 'my_current_module:my_predicate' in a preprocessing step, except if they are declared \verbpublic  or are known to the system as being so (i.e. in the case of builtins).

This basic concept of modules (essentially the same as what can be achieved with extern and static declarations in C) covers only compiled code, and is mostly intended to ensure multiple name spaces with a very simple semantics and no aditional space or time overhead. On the other hand use of linear and intutionistic implication is suggested for dynamic modular and hypothetical reasoning constructs.

Meta-predicate declarations are not supported at this time (mostly because they are at least as cumbersome as just puting the right name extension in argument positions which require it :-)), but they might be added in the future if a significant number of users will ask to have them.

Note that builtins and predicates defined in a special module user are always public. A public predicate keeps its name unchanged in the global name space while hidden predicates have their names prefixed by the name of the module in their definitions and in all their statically obvious (first-order) uses.

Alternatively, module/2 allows to define a module and its public predicates with one declaration as in:

:-module(beings,[cat/4,dog/4,chicken/2,fish/0,maple/1,octopus/255]).