Ý

Help with Jess

Debugging

Using a forward chaining rule based system like Jess requires learning a new programming paradigm. A major characteristic which makes the paradigm different from the other paradigms you've mastered is that it is essentially a parallel system. The jess rules are operating concurrently and in parallel, at least conceptually. Programs in concurrent and parallel systems are tricky to write and notoriously difficult to debug.

That's the bad news. Some good news is that Jess is essentially an interactive interpreter, so it's easy to stop the program whenever you want, examine the state (e.g., facts and activated rules), run experiments, modify the state, and then continue.

HOW DO YOU STOP THE PROGRAM?

One way is to run it in small increments, e.g., giving the run command a small argument (e.g., (run 5)) rather than letting it run to completion using (run). You can "single step" your program if necessary by executing (run 1) repeatedly as you step through a situation which seems to be buggy.

You can also call (halt) on the RHS of a rule to stop the engine when a particular rule fires. You can use this technique in rules whose only purpose is to stop the engine under suspicious circumstances so that you can investigate. If you give such rules a salience higher than all of your other rules, you can be sure they will fire first. Consider the following rule, for example:

  (defrule debug-me3 
    ;; halt for debugging if we generate a goal to enter a cave which 
    ;; has a pit or wumpus. 
    (declare (salience 100)) 
    (goal (action ?go)(x ?x)(y ?y)) 
    (or (wumpus (x ?x)(y ?y))(pit (x ?x)(y ?y))) 
    => 
    (printout "DEBUGME: about to enter a cave with a pit or wumpus!" crlf) 
    (halt)) 

ADVICE

Jess allows you to interactively modify a user defined function, adding an expression to call either before ar after the function is called. See defadvice and undefadvice. You can do something like this

  (defadvice before between (printout t "BETWEEN called: " $?argv crlf) 
  (defadvice after between (printout t "BETWEEN returns: " ?retval) 
which would be useful if you are trying to monitor how the between function is behaving.

HOW CAN YOU EXAMINE THE PROGRAM STATE?

Use the function (facts) to see what facts are in the database. Use (agenda) to see the agenda of rules which are ready to fire and their associated salience and times. You can also invoke the (watch ?x) command to turn on or off the printing of tracing/debugging information. The ?X can be any of {all, rules, compilations, activations, facts, focus}. See the users manual for the details.

HOW DO YOU RESTART THE PROGRAM?

Once you've investigated the situation, you can continue processing by issuing a run command, either (run) to run forever or until completion, or (run ?n) to run for ?n rule firings.

HOW DO I GIVE UP AND START OVER?

The (reset) command will delete all facts, removes all rule activations, then asserts the fact (initial-fact), then re-asserts all facts found in deffacts. This should get you back to the initial state. For paranoids and obsessive compulsives (like me), you can always do a (clear) and then reload all of your files with (batch ?f).