The meta rule protocol (MRP) reifies the internal actions of the forward chainer in terms of backward chaining goals. This allows the user to debug, modify, or even replace the default behavior of the forward chainer. The basic hooks into the Forward Chaining Cycle provided by the MRP include conflict resolution and rule firing. Each context may have a meta-rule defined for it which behaves as a meta-interpreter for that context. For example, if no meta-rule is defined for a context it behaves as if it were using the following meta-rule:
(defrule ordinary-context :backward
((ordinary-context)
<--
(start-cycle)
(instantiation ?instantiation)
(fire-rule ?instantiation)
(cut)
(ordinary-context)))
This rule describes the actions of the forward chaining cycle for this context. Firstly
start-cycle
performs some internal initializations and updates the conflict set. It is essential that this is called at the start of every cycle. Next the preferred
instantiation
is selected from the conflict set by the call to
instantiation
and is stored in the variable
?instantiation
. The rule corresponding to this is fired (by
fire-rule
) and the recursive call to
ordinary-context
means that the cycle is repeated. The
cut
is also essential as it prevents back-tracking upon failure. Failure occurs when there are no more instantiations to fire (the
instantiation
predicate fails) and this causes control to be passed on as normal.
A meta-rule may be assigned to a context with the
:meta
keyword of the
defcontext
form. The argument of the
:meta
keyword is the list of actions to be performed by the context. For example, a context using the above ordinary meta-interpreter can be defined by
(defcontext my-context :meta ((ordinary-context)))
This implicitly defines the rule
(defrule my-context :backward
((my-context)
<--
(ordinary-context)))
and whenever this context is invoked, the rule of the same name is called. The context could equally well have been defined as
(defcontext my-context :meta
((start-cycle)
(instantiation ?instantiation)
(fire-rule ?instantiation)
(cut)
(my-context)))
Sometimes it is useful to manipulate the entire conflict set. For this purpose the action
(conflict-set ?conflict-set)
will return the entire conflict set in the given variable, in the order specified by the context's conflict resolution strategy. The actions
(conflict-set ?conflict-set)
(member ?instantiation ?conflict-set)
(instantiation ?instantiation)
although the latter is more efficient.
Now that the user has access to the instantiations of rules, functions are provided to examine them.