next up previous contents index
Next: The Compiler Up: System Description Previous: Memory Management   Contents   Index


Compiling and Consulting

In XSB, both compiled and interpreted code are transformed into SLG-WAM instructions. The main differences are that compiled code may be more optimized than interpreted code, and that compilation produces an object code file.

This section describes the actions of the standard predicate consult/[1,2] (and of reconsult/[1,2] which is defined to have the same actions as consult/[1,2]). consult/[1,2] is the most convenient method for entering rules into XSB's database. Though consult comes in many flavors, the most general form is:

consult(+FileList, +CompilerOptionList)
At the time of the call both of its arguments should be instantiated (ground). FileList is a list of filenames or module names (see section 3.3) and CompilerOptionList is a list of options that are to be passed to the compiler when (and if) it should be invoked. For a detailed description of the format and the options that can appear in this list see Section 3.8.

If the user wants to consult one module (file) only, she can provide an atom instead of a list for the first argument of consult/2. Furthermore, if there isn't any need for special compilation options the following two forms:

[FileName].
consult(FileName).
are just notational shorthands for:
consult(FileName, []).

Consulting a module (file) generally consists of the following five steps which are described in detail in the next paragraphs.

Name Resolution
: determine the module to be consulted.
Compilation
: if necessary (and the source file is not too big), compile the module using predicate compile/2 with the options specified.
Loading
load the object code of the module into memory.
Importing
import all the exported predicates of that module to the current working module ( usermod).
Query Execution
: execute any queries that the module may contain.

There are two steps to name resolution: determination of the proper directory prefix and determination of the proper extension. When FileName is absolute (i.e. in UNIX contains a slash '/') determination of the proper directory prefix is straightforward. However, the user may also enter a name without any directory prefix. In this case, the directory prefix is a directory in the dynamic loader path (see section 3.4) where the source file exists. Once the directory prefix is determined, the file name is checked for an extension. If there is no extension the loader first checks for a file in the directory with the .P extension, (or .c for foreign modules) before searching for a file without the extension. Note that since directories in the dynamic loader path are searched in a predetermined order (see section 3.4), if the same file name appears in more than one of these directories, the compiler will consult the first one it encounters.

Compilation is performed if the update date of the the source file ( *.P) is later than that of the the object file ( *.O), and if the source file is not larger than the default compile size. This default compile is set to be 20,000 bytes (in cmplib/config.P), but can be reset by the user. If the source file is larger than the default compile size, the file will be loaded using load_dyn/1, and otherwise it will be compiled ( load_dyn/1 can also be called separately, see the section Asserting Dynamic Code for details. While load_dyn gives reasonibly good execution times, compilation can always be done by using compile/[1,2] explicitly. Currently (Version 2.2), a foreign language module is compiled when at least one of files *.c or *.H has been changed from the time the corresponding object files have been created.

Whether the file is compiled or dynamically loaded, the byte-code for the file is loaded into XSB's database. The default action upon loading is to delete any previous byte-code for predicates defined in the file. If this is not the desired behavior, the user may add to the file a declaration

:- multifile <Predicate_List> .
where Predicate_List is a list of predicates in functor/arity form. The effect of this declaration is to delete only those clauses of predicate/arity that were defined in the file itself.

After loading the module, all exported predicates of that module are imported into the current environment (the current working module usermod). For non-modules (see Section 3.3), all predicates are imported into the current working module.

Finally any queries -- that is, any terms with principal functor ':-'/1 that are not directives like the ones described in Section 3.8 -- are executed in the order that they are encountered.


next up previous contents index
Next: The Compiler Up: System Description Previous: Memory Management   Contents   Index
Baoqiu Cui
2000-04-23