Jess Information
Jess Home
Jess 7 Features
Download Now!
Online Demo
Documentation
FAQ
Manual
Mailing List
Jess Wiki
More information
Related Web Sites
User Contributions
JSR94 Info
Developer's Log
About This Site
|
®, the Rule Engine for the Java TM 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)
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.
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.
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.
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/
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.
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!
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!
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:
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...
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!
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.
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.
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.
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.
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:
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.
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
|