Jess Information

Jess Home
Jess 7 Features
Download Now!

Documentation
FAQ
Manual
Getting Help
Jess Wiki

More information Related Web Sites
User Contributions
JSR94 Info
About This Site

JESS ®, the Rule Engine for the JavaTM Platform

The Zen of Jess II

by Jason Morris

Jess and the Art of Rule-Based Computing

One common issue that I see repeated time and again in the postings is that new Jess users are attempting relatively complicated Jess applications without first having done their homework, and I can imagine Dr. Friedman-Hill getting a bit frustrated in having to answer questions that he has taken great pains to answer elsewhere. I empathize with both sides -- it's easy to get bogged down in the fascinating details when you have no traction in the fundamentals.

So keeping in mind the esoteric nature of rule-based expert systems development, be warned that using Jess is not so simple as dropping some JAR into your application. Jess is in many ways a meta-tool, that is a tool for building tools -- namely rule-based expert systems! For many, this is a completely alien paradigm which should warrant a careful and thoughtful study before attempting to write "live" code.

For example, I have been seriously coding in Jess for three years, and I am now relatively comfortable enough with the basics and the "Zen" of rule based-programming to build what I'd consider commercial quality applications. I have cultivated a healthy respect for what Jess can do and what it takes to learn it well.

For me, Jess is fun, and I'd like to share some newbie suggestions and observations that continue to serve me as I broaden and deepen my Jess skills:

My 8 Steps to Jess Enlightenment -- (Revised)

  1. Get the latest code.
    Go to
    http://www.jessrules.com/jess/ and install the latest binary version of Jess (jess.jar) or the whole JessDE if you're using Eclipse. Updating old versions will help you avoid discussing already covered issues.


  2. Study the online documentation.
    You'll want to keep a link to
    http://www.jessrules.com/jess/docs/70/ as your current background reference on Jess. The Jess manual still provides the single best overview of how Jess functionality is structured. Dr. Friedman-Hill is dedicated to keeping this document up-to-date and full of relevant examples.


  3. Use the Jess Functions page.
    Make a short-cut reference to:
    http://www.jessrules.com/jess/docs/70/function_index.html . I can't tell you how many times that I've used this page while studying, programming, and training. You'll refer to it often. Put a hyperlink to the Jess API javadocs where you can reach them quickly as well.


  4. Purchase a copy of Jess In Action (JIA).
    JIA
    http://www.manning.com/friedman-hill by Jess's author, Dr. E. Friedman-Hill, will be your main tutorial and primer on how to program in Jess. Its ISBIN code is 1930110898. Mine is "dog-eared" and annotated already from use. Eat, sleep, and breathe chapters 1 through 7 -- know them like a soldier knows his rifle. Try everything at the Jess command line using the Jess language first. I recommend not trying to program the Jess API directly until you do this step.

    Yes, this was an unpaid endorsement :-) You can see my full Amazon review at
    http://www.amazon.com/exec/obidos/tg/detail/-/1930110898/


  5. Work the JIA tutorials.
    Now, once you have a grasp of the Jess language, try the tutorials in JIA (chapters 8 and beyond), and type the code samples into Jess so that you can see how they work. Experimental learning is the key with Jess -- take advantage of the fact the Jess language is interpreted to get that immediate feedback. It's very gratifying to write a little code snippet that gives you insight into a larger example.

Some variations on the "what if?" theme that worked for me:

    • Writing many, small deffunctions that print something or calculate something is a great way to practice using Jess's variables and list-based syntax. Practice taking apart and creating lists (multifields). Remember: lists don't just hold primitives, they can hold object references as well.

    • Changing the behavior of a JIA snippet is another fun and useful exercise. If an example writes output to the console, change it to write to a file. If a defquery looks for all (foo (color ?c)) facts, make it look for all (foo (color blue)) facts, or any non-blue foo facts (foo (color ~blue)).

    • Get a little fact-base built with some simple rules and modify the rule LHS patterns a bit after each run. Try all the different pattern constraints (this takes time, but pays huge dividends later). Avoid the performance traps of bad pattern ordering on your LHS of rules.


  1. Participate on the Jess Mailing List and Jess Wiki
    You can join the mailing list at:
    http://www.jessrules.com/jess/mailing_list.shtml
    or participate on the Jess Wiki at
    http://www.jessrules.com/jesswiki/view

    As for posting on the listserver, don't be afraid to ask questions, but do try to exhaust the obvious causes of errors before posting -- you learn more that way. I strongly encourage you to try to replace all questions of the form How do I...? with a simple experimental code snippet.

Here's an example: Instead of asking "How do I make Jess switch from one module to the next?", I'd first read a bit about using (focus), then I'd write a little test like

;; test_focus.clp

(clear)

;; Using a fact as a trigger is perfectly acceptable

(deftemplate MAIN::switch-to (slot module-name))

;; Make a rule that looks for this pattern

(defrule MAIN::switch-module

(MAIN::switch-to (module-name ?name))

=>

;; Show me what's happening

(watch all)

;; Hypothesize here... what do you think will happen?

(focus ?name))

;; Need a place to switch to!

(defmodule FOO)

;; A friendly confirmation that we made it OK

(defrule FOO::executing-in-foo

=>

(printout t "Switched to module FOO!" crlf))

(reset)

(assert (switch-to (module-name FOO)))

(run)

... and Jess will print out

<== Focus MAIN

==> Focus FOO

FIRE 2 FOO::executing-in-foo f-0

Switched to module FOO!

<== Focus FOO

==> Focus MAIN

<== Focus MAIN

2

Jess>

Experimenting like this is very serendipitous. One thing that you might notice is that focus returned to the MAIN module automatically when no further rules in the FOO module were activated. You can imagine that doing many, many little such exercises will really boost your Jess understanding. Eventually, when you move beyond trivial examples to real applications, you'll have a whole toolbox of techniques with which to construct your Jess code.

So, when I'm faced with a tough bug, I ask myself, "Ok...what's Ernest going tell me?", and I dig deeper and usually find the answer on my own. Infinitely more satisfying and more educational! If you do discover a useful approach or novel technique, by all means, share it on the Jess Wiki!

  1. Keep a programmer's journal.
    As you experiment and construct your own knowledge, you will accumulate your own tips, tricks, and best-practices. Veteran programmers do this religiously. I continue to have many little epiphanies as I create course content, program my own applications, and study new materials, and you'll want to record your thoughts and discoveries, too. Again, if you can share your learning experiences on the Jess Wiki, that would be great!

  2. Review some LISP and some CLIPS.
    Learning LISP is to learning CLIPS and Jess what learning Latin is to learning English -- it will give you a better sense of where certain concepts originated and help you with the list-based syntax.

    CLIPS is the inspiration for Jess, and Jess owes a good deal of its syntax to CLIPS. Therefore, much (but not all) of what you see in CLIPS is similar to Jess.

    Expert Systems: Principles and Programming, by Giarratano & Riley, is a good companion volume to JIA for reviewing CLIPS syntax, and it will reinforce your study of Jess. For Common LISP, there is the very good and FREE online reference
    http://www.gigamonkeys.com/book/

All of these techniques continue to help me tremendously, but in order to really put them into practice, I had to first study what tools like Jess are meant to do.

A Jess Mantra

Before I tried to build something of my own in Jess (and even before I began studying the Jess language), I put hundreds of hours into studying exactly what types of problems rule-based expert systems are intended to solve.

The main things that I always try to keep in mind are:

  1. Am I choosing the right tool for the job?
    Just because I can use Jess or other tools doesn't necessarily mean that I should use them. If there is simpler solution to my problem, if it can be implemented algorithmically (like solving a quadratic equation), then I don't need an expert system. Now, assuming that Jess is the right tool for my job...


  2. Am I driving the application with data?
    Facts are the primary means of passing data in Jess. Facts reside in Jess's working memory, and changes to facts drive the execution of rules. Too often, new Jess programmers want to pass a value to Jess for some computation. Resist that urge. Instead, simply assert a fact with that data and have a rule that fires when that data appears. This is how Jess is meant to work. This is not to say that you can't or shouldn't pass values to or get values from Jess, but rather try to think in terms of facts driving the rules. The presence or modification of facts can cause rules to fire, which can then change other facts causing more rules to fire, until at some point the working memory is in such a state that no further rules are activated (no patterns fully match). Hopefully, this state represents my desired solution!


  3. Am I allowing my rules to be opportunistic?
    Programmatically, I never explicitly tell a rule when to fire. Period. In general, rules should be allowed to freely react to changes in the fact base. Changes to facts can occur every engine cycle, so rules that were inactive before may become active and those that were active may become deactivated. I don't aim to control this heavy-handedly - it defeats the purpose of using rules.


  4. Am I using proper rule-based control techniques?
    Because of #3 above, some programmers have trouble grasping that the rule-engine actually controls the firing of rules, not the programmer. I specify what should cause them to fire, but not actually when they should fire. In other words, rule-based programming is not, in a strict sense, procedural or algorithmic -- it is not like the coding that you are probably used to in other high-level languages like C, C++, FORTRAN, or others (since even within objects, method code is still procedural and algorithmic, right?) That said, procedural code does exist in the rules themselves (typical looping and conditional branching statements for example). I continue to study many of the proper ways to guide the control and flow of a rule-based program (goal-seeking, hill-climbing, using modules, using salience, using control patterns, etc.) I'm convinced that mastery of these topics is the crux of understanding and implementing useful rule-based architectures.


  5. Am I forming my patterns and actions correctly?
    Rules have two parts to them: a left-hand side (LHS) and right-hand side (RHS). The LHS is strictly for matching fact patterns. Many error-causing implementations that Ernest is quick to admonish come from developers breaking this important principle. Jess has many different ways to group patterns -- I continue to study and experiment with them. The RHS is a list of actions to perform if the pattern(s) of the LHS is (are) satisfied. The actions are typically method calls. Two great capabilities of Jess that are easy to overlook and cannot be overstated are:

    • The LHS can contain patterns that match on external Java objects, not just garden-variety facts.

    • The RHS can call not only native Jess methods, but instance methods of externally referenced Java objects, and static class methods. Via Java JNI, you could even call functions in other languages like C.


Think critically for a minute on the flexibility that this gives your code.

  1. Am I accounting for changes in state?
    Sometimes it helps to think of a rule-based program as a "state-machine", where the addition or subtraction of data (facts) from Jess's working memory moves the machine (your program) through different states. Your job as a rules programmer then is to figure out rules to transition between the states and what to do when a state is reached. This topic feeds back into #4 above.


  2. Am I following good coding practice?
    All other rules of good software engineering always apply to rule-based programming (think about architecture, automated-testing, documentation, goals, interface-design, modularized development, etc.)

Beyond the Temple

Since I last described my experiences about presenting Jess with a fellow programmer at my local Java users group, I've been actively involved in providing Jess training. From teaching and working with customers, I've often noted that in order to extract the most benefit from Jess you need two catalysts:

  1. Purpose
    You need to have a clear reason for using Jess above all other available options. This only comes from performing a needs-analysis, a reasonably thorough technical due-diligence, and a comparison of your needs to Jess's capabilities. This is not unique to Jess, but rather a general observation about expert systems.

    If you are approaching Jess from academia, then I recommend that you should strive for a simple project as your goal. Take time to experiment, but try to train yourself to be practical as you learn. This will help transform your Jess knowledge into a marketable skill when you move to professional programming, and it will be easier to package what you learned into a story that you can communicate in an interview.

    If you are approaching Jess from a professional context, then odds are that you don't have the luxury of experimenting because you have the added burden of being productive while you learn. For you, having clearly defined functional goals within your organization will be vital to your success. In this case, keeping a programmer's journal is not only useful for learning, it also serves to positively document your progress and activity when your productivity does become impacted due to the inevitable learning curve.


  2. Procedure
    You need a clear method for studying the reams of information that you will uncover once you've identified Jess as the right tool for the job. Academically, learning in a vacuum (by yourself), in my experience, is not as much fun nor is it as productive as learning with others who share your interests. Seek out those people.

    In a professional context, the pipelines by which we share tacit or expert knowledge are the relationships that we form with our fellow employees. Part of any Jess development procedure therefore should include a mechanism for rapidly sharing, archiving, and searching knowledge related to the project and building those relationships. How you choose to implement your plan to achieve your purpose is up to you of course. My caution is that if, statistically speaking, the majority of software projects fail, then a project that includes developing an expert system is even more frangible, and it requires considerable planning and management to be successful.

    Of course, part of the procedure is to have all the prerequisites in-place before you add to your learning load. In all cases, trying to learn Java and Jess simultaneously is huge task, and I strongly recommend that you at least cover the equivalent of a basic and intermediate Java course before attempting to seriously use Jess either academically or professionally.

I hope that this helps in your study of Jess and that you have as much fun programming in it as I do.

Happy inferring!

Jason Morris
Morris Technical Solutions
consulting@morristechnicalsolutions.com
www.morristechnicalsolutions.com
fax/phone: 503.692.1088

Last modified: Thu Oct 20 21:15:04 EDT 2005