Next: The Dynamic Loader and
Up: System Description
Previous: The System and its
  Contents
  Index
The Module System of XSB
XSB has been designed as a module-oriented Prolog system. Modules
provide a small step towards logic programming ``in the large''
that facilitates large programs or projects to be put together from
components which can be developed, compiled and tested separately.
Also module systems enforce the principle of information hiding
and can provide a basis for data abstraction.
The module system of XSB, unlike the module systems of most
other Prolog systems is atom-based. Briefly, the main
difference between atom-based module systems and predicate-based ones
is that in an atom-based module system any symbol in a module can
be imported, exported or be a local symbol as opposed to the
predicate-based ones where this can be done only for predicate
symbols 3.1.
Usually the following three files are associated with a particular
module:
- A single source file, whose name is the module name plus
the suffix ``.P''.
- An optional header file, whose name is the module name plus
the suffix ``.H''.
- An object (byte-code) file, whose name consists of the module
name plus the suffix ``.O''.
The header file is normally used to contain declarations and
directives while the source file usually contains the actual
definitions of the predicates defined in that module. The module
hierarchy of XSB is therefore flat -- nested modules are not
possible.
In order for a file to be a module, it should contain one or more
export declarations, which specify that a set of symbols appearing
in that module is visible and therefore can be used by any other module.
A module can also contain local declarations, which specify that
a set of symbols are visible by this module only, and therefore
cannot be accessed by any other module.
Any file (either module or not) may also contain import declarations,
which allow symbols defined in and exported by other modules to be used
in the current module. We note that only exported symbols can be
imported; for example importing a local symbol will cause an environment conflict error.
Export, local, and import declarations can appear anywhere in the source
or header files and have the following forms:
:- export sym1, ..., syml.
:- local sym1, ..., symm.
:- import sym1, ..., symn from module.
where symi has the form
functor/arity.
If the user does not want to use modules, he can simply
bypass the module system by not supplying any export declarations.
Such export-less files (non-modules) will be loaded into the module
usermod, which is the working module of the XSB interpreter.
Currently the module name is stored in its byte code file, which means
that if the byte code file is renamed, the module name is not altered,
and hence may cause confusion to the user and/or the system. So, it
is advisable that the user not rename byte code files generated for
modules by the XSB compiler. However, byte code files generated for
non-modules can be safely renamed. We will try to fix the problem
described above in future releases.
In order to understand the semantics of modules, the user should keep in
mind that in a module oriented system, the name of each symbol is identified
as if it were prefixed with its module name, hence two symbols of the same
functor/arity but different module prefixes are distinct symbols.
Currently the following set of rules is used to determine the module
prefix of a symbol:
- Every predicate symbol appearing in a module (i.e. that appears as
the head of some clause) is assumed to be local to that
module unless it is declared otherwise (via an export or
import declaration). Symbols that are local to a given module
are not visible to other modules.
- Every other symbol (essentially function symbols) in a module is
assumed to be global (its module prefix is usermod) unless declared otherwise.
- If a symbol is imported from another module (via an explicit import
declaration), the module prefix of the symbol is the module it is
imported from; any other symbol takes the module where the symbol
occurs as its module prefix.
- The XSB interpreter is entered with usermod as its
working module.
- Symbols that are either defined in non-modules loaded into the
system or that are dynamically created (by the use of standard
predicates such as read/1, functor/3, '=..'/2, etc) are
contained in usermod3.2.
The following facts about the module system of XSB may not be
immediately obvious:
- If users want to use a symbol from another module, they must
explicitly import it otherwise the two symbols are different
even if they are of the same
functor/arity form.
- A module can only export predicate symbols that are defined in
that module. As a consequence, a module cannot export
predicate symbols that are imported from other modules.
This happens because an import declaration is just a
request for permission to use a symbol from a module where
its definition and an export declaration appear.
- The implicit module for a particular symbol appearing in a
module must be uniquely determined. As a consequence, a
symbol of a specific
functor/arity cannot be declared
as both exported and local, or both exported and imported from
another module, or declared to be imported from more than one
module, etc. These types of environment conflicts are
detected at compile-time and abort the compilation.
- It is an error to import a symbol from a module that does not
export it. This error is not detected at compile-time
but at run-time when a call to that symbol is made. If the
symbol is defined in, but not exported from the module that
defines it, an environment conflict error will take place.
If the symbol is not defined in that module an undefined
predicate/function error will be be reported to the user.
- In the current implementation, at any time only one symbol of
a specific
functor/arity form can appear in a module. As an
immediate consequence of this fact, only one
functor/arity
symbol can be loaded into the current working module ( usermod). An attempt to load a module that redefines that
symbol results in a warning to the user and the newly loaded
symbol overrides the definition of the previously loaded
one.
Next: The Dynamic Loader and
Up: System Description
Previous: The System and its
  Contents
  Index
Luis Fernando P. de Castro
2003-06-27