Modules in Forum F-logic

Modules are intended to isolate the different parts of the knowledge base and protect them from unintended inferences. The inferences within any given module depends only on the knowledge specified within that module. However, statements within a module can reference statements in other modules.

The module mechanism is orthogonal to the mechanism of namespaces, which is often confused with the notion of a module. The namespace mechanism is intended to disambiguate the identifiers used in different knowledge bases, while modules are intended to provide containers for sets of statements about such identifiers. For instance, different agents may hold different beliefs about the same set of entities that exist on the Web.

The concept of a module outlined here is a generalization of the similar concepts in FLORA-2 and TRIPLE. The main differences between the two notions (which are partly unified in this proposal) are:

Syntax for Calling a Goal in a Foreign Module

If lit1, ..., litn are literals defined in module foo then one can call them in the body of a rule (that belongs to a different module) as follows:

This is the same as

Attached module specification is allowed only in the literals that occur in the rule body, not in the rule head. This is because if a head of the form lit@foo occurs in the rule head in another module, bar, then it means that module bar includes definitions for the module foo. But this violates the principle of encapsulation. And, of course, it does not make sense to have lit@foo in the module foo itself, since this is redundant.

Complex Module Names

Module names can be complex first-order terms (not HiLog terms). These terms can have variables, which means that depending on the particular instantiation of such variables the call will be made to a different module. For instance,

If during the call ?Arg1 is bound to 1 and ?Arg2 to 2, then the literal p(a,b) is called in module foobar(1,2). If ?Arg1 is bound to f(3) and ?Arg2 to g(4), then p(a,b) is called in module foobar(f(3),g(4)). Note that p(a,b) can have totally different definitions in modules foobar(1,2). and foobar(f(3),g(4)) and the results can thus be totally different.

How Rules and Facts are Put into a Module

In four ways:

  1. Rules can be put in a file and loaded into a particular module
  2. Rules can be inserted into a module at run time using an insertion operation for rules.
  3. Rules can be in a file with a directive Such a file can be loaded only into module foo.
  4. Rules can be previously compiled for a particular module and stored in a permanent storage like a database. Then they can be loaded from that particular storage.

If no module is specified explicitly, facts and rules in the corresponding file are placed into the default module called `main'.

Syntax for loading a file into a module: [file>>module] or load{file>>module}.

Syntax for inserting rules/facts into a module: This syntax is left undefined for now. In FLORA-2, for example, insert{(literals)@module} is used for inserting facts into modules and insertrule{(ruleList)@module} is used for inserting rules.

Optional Extension Feature: Out-of-bound Parameters

Module calls can have parameters that are passed down to the rulebases sitting in those modules. These parameters are passed "out of bound" and are not part of the arguments explicitly mentioned in the literal being called. These parameters can be inspected in the body of the rules (in the module being called). The syntax is as follows:

Here foobar(?Arg1,...,?Argn) is a parameterized family of modules. The actual chosen module will depend on the values to which ?Arg1, ..., ?Argn are bound at the time of the call.

?Param1, ..., ?Paramm are the out-of-bound parameters. If the module name is a string and not a complex term then one needs to use () in order to avoid confusion between the complex module name and the out-of-bound parameters:

With simple module names, foobar and foobar() are treated as being equivalent.

The parameters passed to the rule bases are accessed as follows: In the body of the rule that defines p(...), the parameters are available through a special literal _@, which is bound to a list of the form [moduleName, ?Param1, ?Param2,...]. One can check the actual values of the parameters and act in accordance with the needs of the application.

The same module can be passed a different number of parameters in different calls. For instance,

Here we have two calls to the predicate p(?X,a) in the same module foobar, but in the first case two out-of-bound parameters will be passed and in the second only one. In module foobar, we might have something like this, which takes the parameters into account:

Importing Modules

The directive imports module modulename into the module of the file where the above directive occurs. It has a complementary executable statement which imports modules at run time. Importing a module means that all the exported methods and predicates in the imported module can be referenced in the importing module without having to add @modulename.

Related Issues

Sometimes it is useful to provide pragmas for the compiler such as


The first might be used to allow the compiler to reject a file, if it sees a version that it cannot handle. The second pragma tells how to interpret non-ASCII characters in strings and names of F-logic symbols (classes, methods, etc.).

$Date: 2007/02/21 15:46:33 $