6.
Making Your Own Rules

Now that we've learned how to populate Jess's working memory, we can answer
the obvious question: what is it good for? The answer is that
defquerys can search it to find
relationships between facts, and defrules
can take actions based on the contents of one or more facts.

A Jess rule is something like an if... then statement
in a procedural language, but it is not used in a procedural
way. While if... then statements are executed at a specific
time and in a specific order, according to how the programmer writes
them, Jess rules are executed whenever their if parts (their
left-hand-sides or LHSs) are satisfied, given only that
the rule engine is running. This makes Jess rules less deterministic
than a typical procedural program. See the chapter on the Rete algorithm for an explanation of why this
architecture can be many orders of magnitude faster than an equivalent
set of traditional if... then statements.

In this chapter we're going to make
a lot of use of a "person" template that looks like this:

This rule has two parts, separated by the "=>" symbol (which you can
read as "then".) The first part consists of the LHS pattern(person {age < 3}). The second part consists of the RHS
action, the call to println. If you're new to Jess,
it can be hard to tell the difference due
to the LISP-like syntax, but the LHS of a rule consists of patterns which
are used to match facts in the working memory, while the RHS contains
function calls.

The LHS of a rule (the "if" part) consists of patterns that match
facts, NOT function calls. The actions of a rule (the "then"
clause) are made up of function calls. The following rule does
NOT work:

This rule will NOT fire just because the function call (eq 1 1)
would evaluate to true. Instead, Jess will try to find a fact in the
working memory that looks like (eq 1 1). Unless you have previously
asserted such a fact, this rule will NOT be activated and will
not fire. If you want to fire a rule based on the evaluation of a
function that is not related to a pattern, you can use the
test CE.

Our example rule, then, will be activated when an appropriate
(person) fact appears in the working memory. When the rule
executes, or fires, a message is printed.
Let's turn this rule into a complete program. The function
watch all tells Jess to print some useful diagnostics as we
enter our program.

Some of these diagnostics are interesting. We see first of all how
issuing the reset command asserts the fact
(initial-fact). You should always issue a reset
command when working with rules. When the rule itself is entered, we
see the line "+1+1+t". This tells you something about how the rule is
interpreted by Jess internally (see The Rete
Algorithm for more information.) When the fact
(person (age 2)) is asserted, we see the diagnostic "Activation:
MAIN::welcome-toddlers : f-1". This means that Jess has noticed that the rule
welcome-toddlers has all of its LHS conditions met by the given
list of facts ("f-1").

After all this, our rule didn't fire; why not? Jess rules only fire
while the rule engine is running (although they can be
activated while the engine is not running.) To start the engine
running, we issue the run command.

Jess> (run)

FIRE 1 MAIN::welcome-toddlers f-1
Hello, little one!
<== Focus MAIN
1

As soon as we enter the run command, the activated rule
fires. Since we have watch all, Jess prints the diagnostic
FIRE 1 welcome-toddlers f-1 to notify us of this. We then see the
output of the rule's RHS actions. The final number "1" is the number of
rules that fired (it is the return value of the run command.)
The run function returns when there are no more activated
rules to fire.

What would happen if we entered (run) again? Nothing. A rule
will be activated only once for a given set of facts; once it has
fired, that rule will not fire again for the same list of facts. We
won't print the message again until another toddler shows up.

Rules are uniquely identified by their name. If a rule named
my-rule exists, and you define another rule named
my-rule, the first version is deleted and will not fire
again, even if it was activated at the time the new version was
defined.

A pattern is always a set of parentheses including the name of the fact
to be matched plus zero or more slot descriptions. There are now two kinds of
slot descriptions in Jess: the new-style "simplified" or
"Java" syntax, and the old-style,
more complex but more powerful syntax. New-style slot descriptions are enclosed in
curly braces, like the one in our welcome-toddlers rule:

Old-style slot descriptions use parentheses instead of curly braces. The syntax
allowed for the two kinds of descriptions are different. We'll talk mostly
about the new simplified
syntax in this section, and save most of the old-style syntax for the next section.
However, there is one very easy and very important thing you can do with the old-style
syntax that we'll need right away: you can declare a variable to refer to the contents
of a slot. For example, look at the following pattern:

(person (age ?a) (firstName ?f) (lastName ?l))

This pattern will match any person fact. When the rule fires, Jess will
assign the contents of the "age" slot to a variable "?a", the firstName slot to
a variable "?f", and the lastName slot to "?l". You'll be able to use these variables
elsewhere in the same rule, both on the left-hand side and on the right-hand side.

The simplified slot descriptions we'll talk about in this section are Java-like Boolean
expressions (infix expressions) using the following operators:

< (less than)

<= (less than or equal to)

> (greater than)

<= (greater than or equal to)

== (equals)

!= (not equal to)

<> (not equal to, alternate syntax)

&& (and)

|| (or)

These operators are used in infix format, like Java operators. Within a simplified pattern,
a symbol stands for the value of the slot in that pattern with the same name. The syntax is
simple and a few examples will serve to document it. The first example matches any person
who is between the ages of 13 and 19, inclusive:

The variable "?p" is a pattern binding; it's bound
to the whole fact that matches this pattern. Note how we
use the dotted
variable syntax to get the
the value of the "age" slot. We declared a variable for
the firstName slot in an old-style slot description.

Most rules have more than one pattern -- often many more. What's more, patterns relate
to one another. For example, we might want to find two unrelated people who are the same age. To do
this sort of task, you simply match one person, then match a second person and compare
them to the first. To compare the two facts, we need to bind variables to them so
we can refer to them; then we use a special "dot notation" to refer to the slots of the first fact:

The curly-brace notation we looked at in the previous section is a
simplified way of writing patterns that fills many basic needs. But Jess actually supports
a richer syntax that gives you more capabilities. One limitation of the curly-brace notation is that
it can only be used with unordered facts. It is this richer syntax
that we'll cover here. Whereas the simplified slot patterns use curly braces, the richer
syntax uses parentheses to enclose slots.

As previously shown, you can specify a variable name for a field in any of
a rule's patterns (but not the pattern's head). A variable matches any
value in that position within a rule. For example, the rule:

will be activated once for every coordinate fact.
The variables ?x and ?y matched in the pattern are available in the
actions on the RHS of the same rule.

A slot descriptor can also include any number of
tests to qualify what it will match. Tests follow the variable name and
are separated from it and from each other by an and (&) or or
(|) symbol. (The variable name itself is actually optional.) Tests can be:

A literal value (in which case the variable matches only that
value); for example, the value 1.0 in (coordinate (x 1.0)).

A variable which was assigned earlier on the rule's LHS.
This will constrain the field to contain the same value as the variable
was first bound to; for example, (coordinate (x ?x) (y ?x)) will only match
coordinates facts with equal x and y values.

A colon (:) followed by a function call, in which case the test
succeeds if the function returns the special value TRUE. These
are called predicate constraints; for example, (cordinate (x ?x&:(> ?x 10)))
matches "coordinate" facts with x greater 10. There is a powerful shortcut way to write many predicate
constraints which we'll look at in a minute.

An equals sign (=) followed by a function call. In this case the
field must match the return value of the function call. These are called
return value constraints. Note that both predicate constraints and
return-value constraints can refer to variables bound elsewhere in this
or any preceding pattern in the same rule. Note: pretty-printing
a rule containing a return value contstraint will show that it has been
transformed into an equivalent predicate constraint. An example of a
return-value constraint would be

(coordinate (x ?x) (y =(+ ?x 1)))

which matches coordinates with y one greater than x.

A Java regular expression surrounded by "/" characters. The field must
match the given regular expression (regular expressions are available only
when you're using Jess under JDK 1.4 and up.) For example,
the pattern (person (name /A.*/) matches people whose first initial is "A".

Any of the other options preceded by a tilde (~), in which case
the sense of the test is reversed (inequality or false); for example
(coordinate (x ?x) (y ~?x)) matches coordinates in which x and y differ.

Ampersands (&) represent logical "and", while pipes (|) represent
logical "or." & has a higher precedence than |, so that the
following

(foo ?X&:(oddp ?X)&:(< ?X 100)|0)

matches a foo fact with a single field containing either an odd
number less than 100, or 0.

The first pattern will match an ordered fact with head not-b-and-c with
exactly two fields such that the first is not b and the second
is not c. The second pattern will match any fact with head different
and two fields such that the two fields have different values. The third
pattern will match a fact with head same and two fields with identical
values. The fourth pattern matches a fact with head more-than-one-hundred
and a single field with a numeric value greater than 100. The last
pattern matches a fact with head red-or-blue followed by
either the symbol red or the symbol blue.

If you match to a defglobal with a pattern like (foo ?*x*), the
match will only consider the value of the defglobal when the fact is
asserted. Subsequent changes to the defglobal's value will not
invalidate the match - i.e., the match does not reflect the current
value of the defglobal, but only the value at the time the matching
fact was asserted.

Pattern matching in multislots (and in ordered facts, which are
really just facts with a single multislot whose name is hidden) is
similar to matching in regular slots. The main difference is that you
may include separate clusters of tests for each field within a
multislot. The number of clusters implicitly specifies the number of
items in a matching multislot. So, for example, the
grocery-list pattern in the following rule matches only
grocery lists with exactly three items:

Note that, as shown here, you can match a field without binding it
to a named variable by omitting the variable name and using just a
question mark (?) as a placeholder.

You can match any number (zero or more) of fields
in a multislot or ordered fact using a multifield. A
multifield is just a variable constraint preceded by a '$'
character. The matched items are used to construct a list, and the
list is assigned to that variable:

Multifields can be used in combination with other kinds of tests,
and they're a very convenient way of saying "... and some other
stuff." For example, this rule matches grocery lists containing bacon
in any position. It does this by using two blank multifields: one to
match all the items before bacon in the list, and the other (which in
this case, will match zero items) to match all the items after.

Sometimes you need a handle to an actual fact that helped to activate a
rule. For example, when the rule fires, you may need to retract or modify
the fact. To do this, you use a pattern-binding variable:

The variable (?fact, in this case) is bound to the particular
fact that activated the rule.

Note that ?fact is a jess.Value object of type
RU.FACT, not an integer. It is basically a reference to a jess.Fact object. You can convert
an ordinary number into a FACT using the fact-id
function. You can convert a FACT into an integer when necessary by
using reflection to call the Fact.getFactId() function. The
jess.Value.factValue() method can be called on a
FACT Value to obtain the actual jess.Fact object from Java
code. In Jess code, a fact-id essentially is a
jess.Fact, and you can call jess.Fact methods on a
fact-id directly:

Note that once a fact is asserted, Jess will always use the same
jess.Fact object to represent it, even if the original fact
is modified. Therefore, you can store references to fact objects in
the slots of other facts as a way of representing structured data.

The first rule matches a "foo" fact with a single field of the
form "xyz", "xyyz", "xyyyz"... The second rule matches a "foo"
fact with two fields: the symbol "a" followed by a string or
symbol of the form "ef", "def", "ddef"...; this string is bound
to the variable ?x and matched to the only field in the second
pattern. Patterns are always matched against the entire
contents of the field. You can write /.*abc.* to
match for an embedded string "abc".

There is also a function
regexp
which
can be used in procedural code. In this release, it just takes
two arguments, a regular expression and a target string, and
returns a boolean result.

Each rule has a property called salience that is a kind of rule
priority. Activated rules of the highest salience will fire first,
followed by rules of lower salience. To force certain rules to always
fire first or last, rules can include a salience declaration:

Declaring a low salience value for a rule makes it fire after all other
rules of higher salience. A high value makes a rule fire before all rules
of lower salience. The default salience value is zero. Salience values
can be integers, global variables, or function calls. See the
set-salience-evaluation
command for details about when such function calls will be evaluated.

The order in which multiple rules of the same salience are fired is
determined by the active conflict resolution strategy. Jess
comes with two strategies: "depth" (the default) and "breadth." In the
"depth" strategy, the most recently activated rules will fire before
others of the same salience. In the "breadth" strategy, rules fire in
the order in which they are activated. In many situations, the
difference does not matter, but for some problems the conflict
resolution strategy is important. You can write your own strategies in
Java; see the chapter on extending Jess with
Java for details. You can set the current strategy with the
set-strategy command.

Note that the use of salience is generally discouraged, for two
reasons: first it is considered bad style in rule-based programming to
try to force rules to fire in a particular order. Secondly, use of
salience will have a negative impact on performance, at least with the
built-in conflict resolution strategies.

You can see the list of activated, but not yet fired, rules with the
agenda command.

Any number of patterns can be enclosed in a list with and as
the head. The resulting pattern is matched if and only if all of the
enclosed patterns are matched. By themselves, and groups
aren't very interesting, but combined with
or and not
conditional elements, they can be used to construct complex
logical conditions.

The entire left hand side of every rule and query is implicitly
enclosed in an and conditional element.

Any number of patterns can be enclosed in a list with or as
the head. The resulting pattern is matched if one or more of the
patterns inside the or are matched. If more than one
of the subpatterns are matched, the or is matched
more than once:

Jess> (defrule or-example-1
(or (a) (b) (c))
=>)

Jess> (assert (a) (b) (c))

Jess> (printout t (run) crlf)

3

An and group can be used inside of an or group, and vice
versa. In the latter case, Jess will rearrange the patterns so
that there is a single or at the top level. For
example, the rule

Jess> (defrule or-example-2a
(and (or (a)
(b))
(c))
=>)

will be automatically rearranged to

Jess> (defrule or-example-2b
(or (and (a) (c))
(and (b) (c)))
=>)

DeMorgan's second rule of logical equivalence, namely

(not (or (x) (y))) => (and (not (x)) (not (y)))

will be used when necessary to hoist an or up to the top level.

Note that if the right hand side of a rule uses a variable defined by matching
on the left hand side of that rule, and the variable is defined by one
or more branches of an or pattern but not all branches, then
a runtime error may occur.

Note that a not pattern cannot define any variables that are
used in subsequent patterns (since a not pattern does not match
any facts, it cannot be used to define the values of any variables!) You
can introduce variables in a not pattern, so long as they are
used only within that pattern; i.e,

A not CE is evaluated only when either a fact matching it
exists, or when the pattern immediately before the not on the
rule's LHS is evaluated. If a not CE is the first pattern on
a rule's LHS, or is the the first the pattern in an and
group, or is the only pattern on a given branch of an or group,
the pattern (initial-fact) is inserted to
become this important preceding pattern. Therefore, the fact
(initial-fact) created by the reset command
is necessary to the proper functioning of some not
patterns. For this reason, it is especially important to issue a
reset command before attempting to run the rule engine when
working with not patterns.

The not CE can be used in arbitrary combination with the
and and or
CEs. You can define complex logical structures this way. For
example, suppose you want a rule to fire once if for every fact (a ?x),
there is a fact (b ?x). You could express that as

Jess> (defrule forall-example
(not (and (a ?x) (not (b ?x))))
=>)

i.e., "It is not true that for some ?x, there is an (a ?x) and no
(b ?x)". This is actually how the the
forall CE is implemented.

A pattern can be enclosed in a list with exists as the head.
An exists CE is true if there exist any facts that match the pattern,
and false otherwise. exists is useful when you want a rule to fire
only once, although there may be many facts that could potentially activate
it.

If there are any honest men in the world, the rule will fire once and
only once.

exists may not be combined in the same pattern with
a test CE.

Note that exists is precisely equivalent to (and in fact,
is implemented as) two nested not CEs; i.e., (exists
(A)) is the same as (not (not (A))). It is rather common for people to
write something like "(not (exists (A)))," but this is just a
very inefficient way to write (not (A)).

A pattern with test as the head is special; the body consists
not of a pattern to match against the working memory but of a Boolean function.
The result of evaluating this function
determines whether the pattern matches. A test pattern fails if
and only if the function evaluates to the symbol FALSE;
if it evaluates to TRUE or any other value, the pattern
with "match." For example:

Note that a test pattern, like a not, cannot define
any variables for use in later patterns. test and
not may be combined:

(not (test (eq ?X 3)))

is equivalent to:

(test (neq ?X 3))

A test CE is evaluated every time the preceding
pattern on the rule's LHS is evaluated. Therefore the following two
rules are precisely equivalent in behaviour:

Jess> (defrule rule_1
(foo ?X)
(test (> ?X 3))
=>)

Jess> (defrule rule_2
(foo ?X&:(> ?X 3))
=>)

In fact, starting with Jess 7.1, the functions in a test CE are simply added
to the previous pattern's tests. Therefore these are not only equivalent, but they are in
fact identical in every respect. You can use test CEs wherever you'd like without
worrying about performance implications. When you need to evaluate a complicated function
during pattern matching, a test CE is often clearer than the equivalent slot test.

You should now understand why, for rules in which a test CE is the first pattern on the
LHS or the first pattern in a branch of an or CE,
the pattern (initial-fact) is inserted to become
the "preceding pattern" for the test. The fact
(initial-fact) is therefore also important for the
proper functioning of the test conditional element;
the caution about reset in the preceding section applies equally
to test.

One useful property of the test CE is
that it's the only valid place to put tests whose results
might change without the contents of any slot changing. For
example, imagine that you've got two Java classes, A
and B, and that A has a method
contains which takes a B as an argument and
returns boolean. Further, imagine that for any given
B object, the return value of contains will
change over time. Finally, imagine that you've defined shadow
fact templates for both these classes and are writing rules to
work with them. Under these circumstances, a set of patterns
like this:

(A (OBJECT ?a))
(B (OBJECT ?b&:(?a contains ?b)))

is incorrect. If the return value of contains changes, the
match will be invalidated and Jess's internal data structures
may be corrupted. In particular, this kind of construct tends
to cause memory leaks.

The correct way to express this same set of patterns is to use
the test conditional element, like this:

(A (OBJECT ?a))
(B (OBJECT ?b))
(test (?a contains ?b))

The function contains is now guaranteed to be called at most
once for each combination of target and argument, and so
any variation in return value will have no impact.

The test conditional element can be used whenever writing a
test directly in a slot would be unclear. It is also useful with time-varying return
values as described previously. There is no longer any performance penalty associated
with the test conditional element.

The logical conditional element lets you specify
logical dependencies among facts. All the facts
asserted on the RHS of a rule become dependent on the
matches to the logical patterns on that rule's
LHS. If any of the matches later become invalid, the
dependent facts are retracted automatically. In this simple
example, a single fact is made to depend on another single
fact:

f-0 (MAIN::faucet-open)
f-1 (MAIN::water-flowing)
For a total of 2 facts in module MAIN.

Jess> (watch facts)

TRUE

Jess> (retract (fact-id 0))

<== f-0 (MAIN::faucet-open)
<== f-1 (MAIN::water-flowing)
TRUE

The (water-flowing) fact is logically dependent
on the (faucet-open) fact, so when the latter is
retracted, the former is removed, too.

A fact may receive logical support from multiple
sources -- i.e., it may be asserted multiple times with a
different set of logical supports each time. Such a fact
isn't automatically retracted unless each of its logical
supports is removed.

If a fact is asserted without explicit logical support,
it is said to be unconditionally supported. If an
unconditionally supported fact also receives explicit
logical support, removing that support will not cause the
fact to be retracted.

If one or more logical CEs appear in a rule, they
must be the first patterns in that rule; i.e., a
logical CE cannot be preceded in a rule by any other
kind of CE.

Shadow facts are no different than other facts with
regard to the logical CE. Shadow facts can
provide logical support and can receive logical support. In
the current implementation, shadow facts can only
provide logical support as a whole. In a future version of
Jess, it will be possible for a shadow fact to provide
logical support based on any combination of individual slot
values.

The logical CE can be used together with all
the other CEs, including not and exists. A
fact can thus be logically dependent on the non-existence of
another fact, or on the existence of some category of facts
in general.

The "accumulate" CE is complicated, and perhaps hard
to understand, but it's incredibly powerful. It lets you count
facts, add up fields, store data into collections, etc. I will
eventually need to write quite a bit of documentation for it,
but for now, the following should get you started.

The accumulate CE looks like this:

(accumulate <initializer> <action> <result> <conditional element>)

When an accumulate CE is encountered during matching (i.e., when
the preceding pattern is matched, or when the contained CE is
matched), the following steps occur:

A new execution context is created.

The initializer is executed in that context.

If the CE is activated via the left input, all the matching
tokens from the right memory are considered. If it's activated
via the right input, each of the matching left tokens are
visited. As each is visited, all of its matching
right tokens are considered in turn.

For each token considered, the variables it defines are
bound in the execution context, and the action is executed.

If a pattern binding is present, the result is
bound to the given variable.

Finally, the accumulate CE matches successfully and matching
continues at the next conditional element.

What this all means is that "accumulate" lets you execute some
code for every match, and returns the accumulated result. For
example, this rule counts the number of employees making more
than $100,000 per year. A variable is initialized to zero, and
incremented for every match; that variable is then bound to the
pattern binding.

The node index hash value is a tunable performance-related
parameter that can be set globally or on a per-rule basis. A small
value will save memory, possibly at the expense of performance; a
larger value will use more memory but lead to faster rule LHS execution.

In general, you might want to declare a large value for a rule that
was likely to generate many partial matches (prime numbers are the
best choices:)

Deftemplate definitions can now include a "declare" section just
as defrules can. There are several different properties that can
be declared. One is "slot-specific". A template with this
declaration will be matched in a special way: if a fact, created
from such a template, which matches the left-hand-side of a rule is
modified, the result depends on whether the modified slot is
named in the pattern used to match the fact. As an example,
consider the following:

Without the "slot-specific" declaration, this rule would
enter an endless loop, because it modifies a fact matched on the
LHS in such a way that the modified fact will still match. With
the declaration, it can simply fire once. This behavior is
actually what many new users expect as the default; the
technical term for it is refraction.

If a rule includes the declaration
(declare (no-loop TRUE)), then nothing that a rule does
while firing can cause the immediate reactivation of the same
rule; i.e., if a no-loop rule matches a fact, and the rule modifies that
same fact such that the fact still matches, the rule will not be
put back on the agenda, avoiding an infinite loop. This is
basically just a stronger form of "slot-specific."

The rules we've seen so far have been forward-chaining rules, which
basically means that the rules are treated as if... then
statements, with the engine passively executing the RHSs of activated
rules. Some rule-based systems, notable Prolog and its derivatives,
support backward chaining. In a backwards chaining system,
rules are still if... then statements, but the engine seeks
steps to activate rules whose preconditions are not met. This
behaviour is often called "goal seeking". Jess supports both forward
and backward chaining. Note that the explanation of backward chaining
in Jess is necessarily simplified here since full explanation requires
a good understanding of the underlying
algorithms used by Jess.

To use backward chaining in Jess, you must first declare that certain
fact templates will be backward chaining reactive. You can do
this when you define the template:

When the rule compiler sees that a pattern matches a
backward chaining reactive template, it rewrites the rule and inserts
some special code into the internal representation of the rule's
LHS. This code asserts a fact onto the fact-list that looks like

(need-factorial 10 nil)

if, when the rule engine is reset, there are no matches for this
pattern. The head of the fact is constructed by taking the head of the
reactive pattern and adding the prefix "need-".

The rule compiler rewrites rules like this too: it adds a
negated match for the factorial pattern itself to the rule's LHS.

The end result is that you can write rules which match on (factorial),
and if they are close to firing except they need a (factorial) fact to
do so, any (need-factorial) rules may be activated. If these rules
fire, then the needed facts appear, and the (factorial)-matching rules
fire. This, then, is backwards chaining! Jess will chain backwards
through any number of reactive patterns. For example:

In this example, none of the rules can be activated at first. Jess
sees that rule-1 could be activated if there were an
appropriate foo fact, so it generates the request (need-foo
nil nil). This matches part of the LHS of rule
create-foo cannot fire for want of a bar fact. Jess
therefore creates a (need-bar nil nil) request. This matches
the LHS of the rule create-bar,which fires and asserts
(bar C D). This activates create-foo, which fires,
asserts (foo A B), thereby activating rule-1, which
then fires.

There is a special conditional element, (explicit), which you
can wrap around a pattern to inhibit backwards chaining on an otherwise
reactive pattern.

A typical rule-based system can easily include hundreds of
rules, and a large one can contain many thousands. Developing
such a complex system can be a difficult task, and preventing
such a multitude of rules from interfering with one another can
be hard too.

You might hope to mitigate the problem by partitioning a rule
base into manageable chunks. Modules let you divide rules
and templates into distinct groups. The commands for listing
constructs let you specify the name of a module, and can then
operate on one module at a time. If you don't explicitly specify
a module, these commands (and others) operate by default on the
current module. If you don't explicitly define any
modules, the current module is always the main module,
which is named MAIN. All the constructs you've seen so far have
been defined in MAIN, and therefore are often preceded by
"MAIN::" when displayed by Jess.

Besides helping you to manage large numbers of rules, modules
also provide a control mechanism: the rules in a module will
fire only when that module has the focus, and only one
module can be in focus at a time.

Note for CLIPS users: Jess's defmodule
construct is similar to the CLIPS construct by the same name,
but it is not identical. The syntax and the name resolution
mechanism are simplified. The focus mechanism is much the same.

A module defines a namespace for templates and
rules. This means that two different modules can each contain
a rule with a given name without conflicting -- i.e., rules
named MAIN::initialize and
COMMUTE::initialize could be defined simultaneously
and coexist in the same program. Similarly, the templates
COMPUTER::bus and COMMUTE::bus could both be
defined. Given this fact, there is the question of how Jess
decides which template the definition of a rule or query is
referring to.

When Jess is compiling a rule or deffacts definition, it will
look for templates in three places, in order:

If a pattern explicitly names a module, only that module
is searched.

If the pattern does not specify a module, then the
module in which the rule is defined is searched first.

If the template is not found in the rule's module, the
module MAIN is searched last. Note that this makes the MAIN
module a sort of global namespace for templates.

In this example, three deftemplates are defined in three
different modules: MAIN::mortgage-payment,
WORK::job, and HOME::hobby. Jess finds the
WORK::job template because the rule is defined in the WORK
module. It finds the HOME::hobby template because it is
explicitly qualified with the module name. And the
MAIN::mortgage-payment template is found because the MAIN
module is always searched as a last resort if no module name
is specified.

Commands which accept the name of a construct as an argument
(like ppdefrule, ppdeffacts, etc) will search for the
named construct in the same way as is described above.

Note that many of the commands that list constructs (facts, list-deftemplates, rules, etc) accept a module name or "*"
as an optional argument. If no argument is specified, these
commands operate only on the current module. If a module name
is given, they operate on the named module. If "*" is given,
they operate on all modules.

In the previous sections I described how modules provide a
kind of namespace facility, allowing you to partition a
rulebase into manageable chunks. Modules can also be used to
control execution. In general, although any Jess rule can be
activated at any time, only rules in the focus module
will fire. Note that the focus module is independent
from the current module discussed above.

Initially, the module MAIN has the focus:

Jess> (defmodule DRIVING)

TRUE

Jess> (defrule get-in-car
=>
(printout t "Ready to go!" crlf))

TRUE

Jess> (reset)

TRUE

Jess> (run)

0

In the example above, the rule doesn't fire because the
DRIVING module doesn't have the focus. You can move the focus
to another module using the focus
function (which returns the name of the previous focus module:)

Jess> (focus DRIVING)

MAIN

Jess> (run)

Ready to go!
1

Note that you can call focus from
the right-hand-side of a rule to change the focus while the
engine is running.

Jess actually maintains a focus stack containing an
arbitrary number of modules. The focus module is, by
definition, the module on top of the stack. When there are no
more activated rules in the focus module, it is "popped" from
the stack, and the next module underneath becomes the focus
module. You also can manipulate the focus stack with the
functions pop-focuslist-focus-stackget-focus-stack and
clear-focus-stack

The example program dilemma.clp shows a good use of
modules for execution control.

This should not be a common requirement, but you can remove a module from the engine using the
jess.Rete.removeDefmodule(String) method.
You might want to do this during interactive development or experimentation. You won't be able to
remove a module if it's in use. If there are any templates or rules defined in the module, you'll get an exception.