.\" ------------------------------ sec9.t ------------------------------ .sh 1 "Modules" .pp To describe how modules (or maybe more properly, just libraries) are currently supported in our system, we must describe the \fI_\|$undefined_\|pred\fR/1 interrupt handler. The system keeps a table of modules and routines that are needed from each. When a predicate is found to be undefined, the table is searched to see if it is defined by some module. If so, that module is loaded (if it hasn't been previously loaded) and the association is made between the routine name as defined in the module, and the routine name as used by the invoker. .pp The table of modules and needed routines is: .(l C defined_\|mods(\fIModname\fR, [\fIpred\fR\*<1\*>/\fIarity\fR\*<1\*>, ..., \fIpred\*\fR/\fIarity\*\fR]). .)l where \fIModname\fR is the name of the module. The module exports \fIn\fR predicate definitions. The first exported pred is of arity \fIarity\fR\*<\*>1, and needs to be invoked by the name of \fIpred\fR\*<1\*>. .pp The table of modules that have already been loaded is given by .(l loaded_\|mods(\fIModname\fR). .)l A module is a file of predicate definitions, together with a fact defining a list of predicates exported by that module, and a set of facts, each of which specifies, for some other module, the predicates imported from that module. For example, consider a module name `\fIp\fR'. It contains a single fact, named \fIp_\|export\fR, that is true of the list of predicate/arity's that are exported. E.g. .(l p_\|export([p1/2, p2/4]) .)l indicates that the module \fIp\fR exports the predicates \fIp1\fR/2 and \fIp2\fR/4. For each module \fIm\fR which contains predicates needed by the module \fIp\fR, there is a fact for \fIp_use\fR, describing what module is needed and the names of the predicates defined there that are needed. For example, if module \fIp\fR needs to import predicates \fIip1\fR/2 and \fIip2\fR/3 from module \fIq\fR, there would be a fact .(l p_\|use(q,[ip1/2, ip2/3]) .)l where \fIq\fR is a module that exports two predicates: one 2-ary and one 3-ary. This list corresponds to the export list of module \fIq\fR. .pp The correspondence between the predicates in the export list of an exporting module, and those in the import or \fIuse\fR list of a module which imports one or more of them, is by position, i.e. the predicate names at the exporting and importing names may be different, and the association between names in the two lists is by the position in the list. If the importing module does not wish to import one or more of the predicates exported by the exporting module, it may put an anonymous variable in the corresponding position in its \fIuse\fR list. Thus, for example, if module \fIp\fR above had wished to import only the predicate \fIip2\fR/3 from module \fIq\fR, the corresponding use fact would be .(l p_\|use(q, [_\|\|, ip2/3]). .)l .pp The initial set of predicates and the modules from which they are to be loaded is set up by an initial call to \fI$prorc\fR/0 (see the SB-Prolog system file \fImodlib/src/$prorc.P\fR). This predicate makes initial calls to the predicate $define_\|mod which set up the tables described above so that the use of standard predicates will cause the correct modules to be loaded in the \fI_\|$undefined_\|pred\fR routine, and the correct names to be used. .\" ---------------------- end of section sec9.t --------------------