3.1.2 Forward Chaining Syntax

Forward chaining rule bodies are defined by:

<body> ::=
          [:context <context-name>]
          [:priority <priority-number>]
          <forward-condition>* --> <expression>*)

where <context-name> is the name of a context which has already been defined (see Control Flow) defaulting to default-context , and <priority-number> is a number (see Control Flow) defaulting to 10 .

The syntax for forward-conditions is :

<forward-condition> ::=
     |  (test <lisp-expr>)
     |  (not <forward-condition>+)
     |  (logical <forward-condition>+)
<object-condition> ::=
     (<class-name> <variable> [<object-slot-condition>]*)
<object-slot-condition> ::=
     <slot-name> <term>

<object-condition> is an object-base match where the variables (introduced by "?") in <term> are bound (via destructuring) to the corresponding data in the slot named by <slot-name>. <variable> is a single variable bound to the object matched.

Note: "?" on its own denotes an anonymous variable which always matches.

(test <lisp-expr>) is a Lisp test where <lisp-expr> is any Lisp expression using the variables bound by other conditions, and which must succeed (return non- nil ) for the condition to match. Computationally cheap Lisp tests can frequently be used to reduce the search space created by the object base conditions. Lisp tests, and any functions invoked by them, should not depend on any dynamic global data structures, as changing such structures (and hence the instantiations of the rule) will be invisible to the inference engine. Lisp tests can depend on the values of slots in objects matched by preceding object-base conditions only if the values are bound to variables in the rule using the <object-slot-condition> syntax. They cannot depend on values obtained by calling slot-value or a reader function.

(not <forward-condition>+) is simply a negated condition. A negated condition never binds any variables outside its scope. Variables not bound before the negation will remain unbound after it.

(logical <forward-condition>+) is used to indicate clauses that describe the logical dependencies amongst objects. See Logical Dependencies and Truth Maintenancefor more details.

Note that if a forward chaining rule contains any conditions at all then it must contain at least one object base reference of the form

(<class-name> <variable> ...)

The syntax for expressions is:

<expression> ::=
         |(erase <variable>)
         |(assert (<class-name> <variable> 
                   [<slot-name> <term>]*))
         |(context <context-list>)
         |(<lisp-expr> <term>*)

<forward-condition> is a forward condition which must succeed for execution of the action part of the rule to continue.

(erase <variable>) removes the instance bound to <variable> from the knowledge base. It is an error if <variable> is bound to anything but a KnowledgeWorks instance.

(assert (<class-name> <variable> [<slot-name> <term>]*)) is an assertion which modifies the contents of the object base, where if <variable> is unbound a new object of the given class with the given slot-values is created, and if it is bound, the object to which it is bound has its slots modified to the given values.

(context <context-list>) adds the given list of contexts to the top of agenda (see Control Flow).

(return) passes control to the top context on the agenda and removes it from the agenda (see Control Flow).

(<lisp-expr> <term>*) binds the result or results of calling <lisp-expr> to the <term> s with execution of the rule terminating if any bindings fail (if no <term> s are given execution will always continue).

<goal> may be any backward chaining goal expression (see Backward Chaining).

Note that in the action part of a rule, only backward chaining goals and object base matches invoke the backward chainer. Example

KnowledgeWorks and Prolog User Guide (Macintosh version) - 29 Feb 2008