Jess The Rule Engine for the Java Platform - Version 7.1p2

Jess The Rule Engine for the Java Platform - Version 7.1p2

Lượt xem: 116,384Lượt tải: 2Số trang: 198

Mô tả tài liệu

Jess is a rule engine for the Java platform. To use it, you specify logic in the form of rules using one of two formats: the Jess rule language (prefered) or r XML . You also provide some of your own data for the rules to operate on. When you run the rule engine, your rules are carried out. Rules can create new data, or they can do anything that the Java programming language can do.

Tóm tắt nội dung

2. The JessDE XE "Jess the JessDE XE "Jess 7 Using the JessDE XE "Jess 8 4. Defining Functions XE in facts XE "Fact: shadow" : reasoning about Java Making Your Own Rules XE "Rule" rules XE "Rule" 45 Java Objects in working memory XE "Working memory" 63 The jess.Rete XE "Rete" XE "Value" XE jess.Fact XE "Fact" Jess XE your own rules XE "Rule" Rules XE "Rule" from and XML XE "XML" XE "Rule" <fact XE "Fact" <variable XE > XE "Fact" [<module name> | <variable XE > <fact XE "Fact" (<slot XE "Slot" -name> <router XE "Router" XE "progn" XE "Rule" [ | * XE 159 Jess – the Rule Engine XE "Rule engine" - use it, you specify logic in the form of rules XE "Rule" using one of two formats: the Jess rule language or XML XE "XML" Jess can run as a program \l "cli​), usually you will embed the Jess library in your Java code and it using its own Java API or the basic offered by the XE "Rule" API can develop Jess language code in any text editor, but Jess comes with a full featured based on the Eclipse XE "Eclipse" platform use the JessDE XE "Jess you'll need version 3.1 or later of the Eclipse XE "Eclipse" SDK from Jess language is a highly form of Lisp XE "Lisp" . I will describe the entire Jess language, so no with Lisp XE "Lisp" is required (although some is helpful.) I will attempt to describe, to the extent possible, the important concepts of systems as they apply to single file contains XE all you need to use Jess on Windows, UNIX, or the Macintosh (except for a JVM, which you must install directory of small example programs in JessML, Jess's XML XE "XML" rule this directory is present, it contains XE the full source for the Jess rule engine and including an Ant script for building it. Jess, the Rule Engine XE "Rule engine" for the Java the Rule Engine XE "Rule engine" for the Java details of doing these tasks are system and but setting the class path usually involves modifying an variable XE , and a standard extension simply means copying jess.jar into your no rules XE "Rule" will fire. 2. The JessDE XE "Jess 7 includes an Eclipse XE "Eclipse" -based the JessDE XE "Jess The Jess (JessDE XE "Jess ) is supplied as a set of plugins for the popular IDE Eclipse XE "Eclipse" ; in these are plugins for Eclipse version 3.1 or later. To install the JessDE XE "Jess , simply exit Eclipse XE "Eclipse" , unzip all the files from into the top-level Eclipse you're updating from a previous version of the JessDE XE "Jess , you must launch Eclipse XE "Eclipse" with the "-clean" switch to force it to update the it caches regarding the JessDE the JessDE XE "Jess is installed properly, you'll find three or four plugins in the list -- in my copy of Eclipse, they appear near the on for more about the other features of the JessDE XE "Jess . The JessDE XE "Jess editor creates problem markers to point out syntax errors and warnings in your Jess the JessDE XE "Jess The JessDE XE "Jess editor can edit ".clp" JessDE uses your Java project's class path to resolve XE of values" Java class names used in Jess language code -- i.e., in a call to the defclass \l can change the default XE "default value" colors using the "Jess Editor" tab of the Eclipse XE "Eclipse" global can invoke Eclipse XE "Eclipse" 's "Content Assist" feature in many different places within the JessDE XE "Jess editor; JessDE will make it much easier to enter Jess you type a '(' or '"' JessDE XE "Jess insert the matching character as help for Jess functions and XE via "hovers" You have quick access to the Jess manual of every function and construct XE type. If you hold your mouse over the name of a XE or XE , anywhere in the code, JessDE XE "Jess will show a "tooltip" about that template XE or can run or debug a Jess program using the normal Eclipse XE "Eclipse" "Run..." menu or by right clicking on Navigator items or in the edit one *.clp file depends on code in some other *.clp file having been read first; for example, rules XE "Rule" .clp might need the in templates XE .clp. If a file rules XE "Rule" .clp depends on Jess commands being executed from Java, you can deal with this by creating a special file just for this purpose (you might call it "require" mechanism replaces the "Source property sheet from earlier versions of JessDE XE "Jess , which is no longer can instantly see a graphical of the Rete XE "Rete" network derived from any rule using the JessDE XE "Jess 's "Rete Network Jess debugger XE The JessDE XE "Jess debugger XE lets you debug a Jess program defined in a .clp of the time, you'll write Jess rules XE "Rule" in the Jess rule you've never used Lisp XE "Lisp" , the Jess rule language may look a bit odd at first, but it doesn't take long to learn. In chapters, we'll learn how to define concepts like facts XE "Fact" and rules XE "Rule" , but here, we'll just be looking at the nuts and first element of a list (the car of the list in Lisp XE "Lisp" parlance) is often called the list's head in supports two kinds of comments: Lisp XE "Lisp" -style line comments and C-style block XE "Comment" can appear anywhere in a Jess program, including inside XE like templates XE and rules XE "Rule" . As in Lisp XE "Lisp" , all code in Jess (control (​" \l (​" \l procedure calls) takes the form of a function call. A variable XE can refer to a single symbol, number, or string, or it can refer to a list. You can assign a value to to a variable XE using the bind \l "bind​) function: To see the value of a variable XE at the Jess> prompt, you can simply type the name. A dotted variable XE looks like ?x.y. Jess always this as referring to the slot XE "Slot" y of the fact XE "Fact" in variable the value of a dotted variable XE results in a call to fact XE "Fact" -slot XE "Slot" -value \l while using bind \l "bind​) to set such a variable will result in a call to modify \l create global variables that are not destroyed by reset \l "reset​), you can use the defglobal XE construct XE . Jess> XE ?*x* = 3) Each of these functions works similarly to the Java construct XE of the same name. 4. Defining Functions XE in Jess You can define your own functions in the Jess rule language using the XE construct XE . It can either be an explicit XE use of the return \l "return​) function or it can be any value or XE max (?a ?b) Jess> XE max (?a ?b) The defadvice \l XE construct XE lets you write some Jess code which will be executed before or after each time a given Jess function is XE before + (bind $?argv (create$ $?argv XE before + (return 1)) Jess> XE after + (return (- ?retval 1))) Each Jess rule engine holds a of knowledge nuggets called facts XE "Fact" . Some facts XE "Fact" are pure facts defined and created entirely by facts are shadow facts (​" \l XE "Fact: shadow" connected to Java objects you facts act as "bridges" that let Jess reason about things that happen outside of working memory XE "Working memory" . The template has a name and a set of slots XE "Slot" , and each fact gets these things from its template is like the class of a Java object, or like a database XE table. In Jess, there are three kinds of facts XE "Fact" : unordered facts XE "Fact: , shadow facts XE "Fact: shadow" and ordered XE "ordered" facts XE "Fact: ordered" . Just so you know, as we learn about working memory XE "Working memory" : you can see a list of all the facts XE "Fact" in working memory using the facts \l "facts​) modify \l "modify​) function lets you change the slot XE "Slot" values of facts already in working memory. A fact gets its name and its list of slots XE "Slot" from its usually create templates XE yourself using the \l XE construct XE or the defclass \l times, templates are created for you, either while you're defining a defrule \l XE "defrule" or when you use the add \l "add​) function or the jess.Rete XE "Rete" \l default XE "default value" slot qualifier gives a value to use for a slot when the fact XE "Fact" is first created, if no other value is the default is the symbol nil for a regular slot, and the empty list for a multislot XE XE is similar but the the given will be evaluated each time a new fact using this template XE is type slot XE "Slot" qualifier is accepted but not currently enforced by Jess; in theory it specifies what data type the slot is allowed to hold. If you specify both and default XE "default value" , Jess checks to make sure they're it shouldn't be a common you can remove a defined template XE using the jess.Rete XE "Rete" \l you can create unordered facts XE "Fact: , you have to define the slots XE "Slot" they have using the \l XE construct XE . Jess> XE XE "Fact" -1> Jess> (facts XE "Fact" ) f-0 XE "Fact" ) For a total of 2 facts XE "Fact" in module note that any number of could also be asserted onto the fact list using this template XE . Note also that we can specify the slots XE "Slot" of an unordered fact XE "Fact" in any order (hence the name.) Jess our inputs into a canonical order so that they're always the same. You can remove an fact from the working memory XE "Working memory" using the retract \l (facts XE "Fact" ) f-0 XE "Fact" ) For a total of 1 facts XE "Fact" in module MAIN. The fact XE "Fact" is asserted by the reset \l "reset​) XE box (slot XE "Slot" location) XE XE "Fact" saving the fact XE "Fact" returned by (assert) in the variable XE ?id, for use below.) A multislot XE has the default XE "default value" value () (the empty list) if no other default is can change the values in the slots XE "Slot" of an unordered fact XE "Fact" using the modify \l "modify​) XE "Fact" -2> Jess> (facts XE "Fact" ) f-0 XE "Fact" ) For a total of 2 facts XE "Fact" in module XE used-auto extends XE extends" facts XE "Fact: shadow" : reasoning about Java using shadow facts XE "Fact" , you can put any Java object into Jess's working memory XE "Working memory" . Like all other facts XE "Fact" , shadow facts XE "Fact: shadow" need to have a template XE , In this case, though, rather than the slots XE "Slot" we want to let Jess create the template by looking at a Java XE defclass \l function can be used instead to create a shadow fact XE "Fact: shadow" template XE ; it looks XE Java objects to working memory XE "Working memory" Once you've created an template XE , you can add some Java objects to working memory XE "Working memory" , creating shadow facts XE "Fact: shadow" to link them to with our Account example, imagine that you want to create an Account, and you want to add this object to working memory because rules XE "Rule" will be working with it. <Fact XE "Fact" -0> Jess> (facts XE "Fact" ) For a total of 1 facts XE "Fact" in module MAIN. The add \l "add​) function creates a shadow fact XE "Fact: shadow" and links it to our Account explore the nature of that link in the following section, but before we do that, I want to point out two things about add \l "add​) and about shadow fact XE "Fact" templates XE in shadow fact XE "Fact: shadow" templates have this shadow fact XE "Fact" created from this template will use that slot to hold a reference to the Java object reverse mapping (given a Java object, finding its shadow fact) is also available using the method jess.Rete XE "Rete" \l the add \l "add​) function the template XE naming discussed in the previous with our Account example, we can use the modify \l "modify​) function to change the fact XE "Fact" , and the Java object will be modified XE "Fact" -0> Jess> (facts XE "Fact" ) For a total of 1 facts XE "Fact" in module (facts XE "Fact" ) For a total of 1 facts XE "Fact" in module (facts XE "Fact" ) For a total of 1 facts XE "Fact" in module \l "update​) tells Jess to refresh the slot XE "Slot" values of the shadow fact XE "Fact: shadow" linked to the given Java reset \l "reset​) function, which resets working memory XE "Working memory" , updates the slots of all shadow facts XE "Fact" in the can also actively tell Jess to refresh its knowledge of the of objects using the jess.Rete XE "Rete" \l you want to have your shadow facts XE "Fact: shadow" stay up to date, Jess needs to be notified whenever a Bean XE "Bean" property Beans that fulfill this Jess will arrange for working memory XE "Working memory" to be updated every time a property of the Bean whenever an Account balance is modified, Jess will be notified and the shadow fact XE "Fact: shadow" will be updated and shadow facts XE "Fact: shadow" seem magical to some people; the flow of control can be and the notion of things happening sometimes makes people forget that no code executes in Java unless invokes it. When you add an instance of this class to working memory XE "Working memory" , Jess will usually call on it, where listener is a Jess object designed to respond to change list is managed by the object that the holds as a member (Why If you use \l to add the object to working memory and specify static as the final argument, then Jess will skip this step.) Of course, many (most) Java classes don't allow you to add to them, and so for many of the Java objects you'll add to working memory XE "Working memory" , Jess doesn't register itself with the object in any are now two main scenarios of interest: an object in working memory XE "Working memory" can be modified from Jess code, or from Java code. Bad things may happen as a result: Jess's working memory XE "Working memory" indices may need to be you should always call the jess.Rete XE "Rete" \l method to tell Jess when an object is changed in this way. Jess will examine the object that receives as an argument and update working memory XE "Working memory" you use modify \l "modify​) (or the Java to modify a shadow fact XE "Fact: shadow" , then Jess will call the "setter" methods on the object, and update working memory XE "Working memory" . When Jess receives the change event, it will update working memory XE "Working memory" in course, for a shadow fact template to extend a plain template, the Java class must have property names that match the plain slot XE "Slot" final note about Java Beans XE "Bean" used with Jess: Beans are often operating in a and so it's important to protect their data with blocks or of the time, you will use unordered facts XE "Fact: (or their cousins, shadow facts XE "Fact: shadow" .) They are nicely and they're the most efficient kind of fact XE "Fact" in facts XE "Fact: ordered" are simply Jess lists, where the first field (the head of the list) acts as a sort of category for the fact XE "Fact" . Here are some examples of ordered XE "ordered" facts: You can add ordered XE "ordered" facts XE "Fact: ordered" to the working memory XE "Working memory" using the assert \l "assert​) function, just as with unordered facts XE "Fact: . If you add a fact XE "Fact" to working memory whose head hasn't been used before, Jess assumes you want it to be an ordered fact and creates an template XE XE is so strong, that in fact this is how ordered facts XE "Fact: ordered" are in Jess. If you assert an ordered fact, Jess generates a template XE for separate assert \l "assert​) commands for each of many facts XE "Fact" is rather make life easier in this regard, Jess includes the deffacts \l XE construct XE . The facts in all defined deffacts are asserted into the working memory XE "Working memory" whenever a reset \l "reset​) command is (deffacts XE my-facts XE "Fact" "Some useless (facts XE "Fact" ) f-0 XE "Fact" ) For a total of 3 facts XE "Fact" in module fact XE "Fact" , shadow or to a single instance of the jess.Fact \l Templates XE are by instances of which you can read about here. 6. Making Your Own Rules XE "Rule" Now that we've learned how to populate Jess's working memory XE "Working memory" , we can answer the obvious question: what is it good for? then are executed at a specific time and in a specific order, according to how the writes them, Jess rules XE "Rule" are executed whenever their if parts (their or LHSs) are given only that the rule engine is XE person (slot XE "Slot" (slot lastName) (slot XE "Rule" are defined in Jess using the defrule XE "defrule" construct XE . Jess> (defrule XE "defrule" you're new to Jess, it can be hard to tell the due to the LISP-like syntax, but the LHS of a rule consists of patterns XE "Pattern" which are used to match facts XE "Fact" in the working memory XE "Working memory" , while the RHS contains XE function LHS of a rule (the "if" part) consists of patterns XE "Pattern" that match facts XE "Fact" , NOT function (defrule XE "defrule" Jess will try to find a fact XE "Fact" in the working memory XE "Working memory" that looks like (eq 1 1). If you want to fire a rule based on the of a function that is not related to a pattern, you can use the test CE (​" \l XE "test CE" . Our example rule, then, will be activated when an (person) fact XE "Fact" appears in the working memory XE "Working memory" . Jess> XE person (slot XE "Slot" (slot lastName) (slot age)) ==> f-0 XE "Fact" ) Jess> (defrule XE "defrule" XE "Fact" -1> We see first of all how issuing the reset \l "reset​) command asserts the fact XE "Fact" should always issue a reset \l "reset​) command when working with rules XE "Rule" . This tells you something about how the rule is by Jess (see The Rete XE "Rete" Algorithm for more When the fact (person (age 2)) is asserted, we see the : rules XE "Rule" only fire while the rule engine is running (although they can be activated while the engine is not running.) To start the engine running, we issue the run \l "run​) final number "1" is the number of rules XE "Rule" that fired (it is the return value of the run \l "run​) command.) The run \l "run​) function returns when there are no more activated rules to fire. A rule will be activated only once for a given set of facts XE "Fact" ; once it has fired, that rule will not fire again for the same list of facts. A pattern is always a set of including the name of the fact XE "Fact" to be matched plus zero or more slot XE "Slot" (defrule XE "defrule" there is one very easy and very important thing you can do with the old-style syntax that we'll need right away: you can declare XE "declare rule" a variable XE to refer to the contents of a pattern will match any person fact XE "Fact" . When the rule fires, Jess will assign the contents of the "age" slot XE "Slot" to a variable XE "?a", the firstName slot to a variable "?f", and the lastName slot to "?l". The slot XE "Slot" we'll talk about in this section are Java-like Boolean (infix using the following Jess> (defrule XE "defrule" variable XE "?p" is a pattern binding (​" \l XE "Binding" ; it's bound to the whole fact XE "Fact" that matches this how we use the dotted variable \l syntax to get the the value of the "age" slot XE "Slot" . Jess> (defrule XE "defrule" can use to group in Java patterns XE "Pattern" ; for example: Jess> (defrule XE "defrule" rules XE "Rule" have more than one pattern -- often many more. To compare the two facts XE "Fact" , we need to bind variables to them so we can refer to them; then we use a special "dot notation" to refer to the slots XE "Slot" of the first fact: Jess> (defrule XE "defrule" XE (slot XE "Slot" x) (slot y)) Jess> (defrule XE "defrule" literal value (in which case the variable XE matches only that value); for example, the value 1.0 in (x will constrain the field to contain the same value as the variable was first bound to; for example, (x ?x) (y ?x)) will only match facts XE "Fact" with equal x and y are called predicate for example, (x ?x&:(> ?x 10))) matches facts XE "Fact" with x greater 10.  A Java regular XE "Regular by "/" a foo fact XE "Fact" with a single field either an odd number less than 100, or 0. Jess> (defrule XE "defrule" first pattern will match an ordered XE "ordered" fact XE "Fact" with head with exactly two fields such that the first is not b and the second is not c. If you match to a defglobal XE with a pattern like (foo ?*x*), the match will only consider the value of the defglobal when the fact XE "Fact" is (defrule XE "defrule" XE "Fact" -0> Jess> (defrule XE "defrule" XE "Fact" -0> Jess> (defrule XE "defrule" XE "Fact" you need a handle to an actual fact XE "Fact" that helped to activate a (defrule XE "defrule" variable XE (?fact XE "Fact" , in this case) is bound to the fact that activated the that ?fact XE "Fact" is a \l XE "Value" object XE "Value object" of type RU.FACT, not an (defrule XE "defrule" t (call ?fact XE "Fact" getName) that once a fact XE "Fact" is asserted, Jess will always use the same jess.Fact object to represent it, even if the original fact is new regular XE "Regular facility builds on Java's (defrule XE "defrule" XE "defrule" first rule matches a "foo" fact XE "Fact" with a single field of the form "xyz", "xyyz", second rule matches a "foo" fact with two fields: the symbol "a" followed by a string or symbol of the form "ef", "def", this string is bound to the variable XE ?x and matched to the only field in the second (defrule XE "defrule" comes with two "depth" (the default XE "default value" ) and In the "depth" strategy, the most recently activated rules will fire before others of the same can see the list of but not yet fired, rules XE "Rule" with the agenda \l "agenda​) XE "Agenda" (defrule XE "defrule" the latter case, Jess will rearrange the patterns XE "Pattern" so that there is a single or at the top (defrule XE "defrule" (defrule XE "defrule" that if the right hand side of a rule uses a variable XE defined by matching on the left hand side of that rule, and the variable is defined by one or more branches of an or pattern but not all branches, then a runtime error may occur. In this case, the pattern is to match if a fact XE "Fact" (or set of facts) which matches the pattern is not (defrule XE "defrule" that a not pattern cannot define any variables that are used in patterns XE "Pattern" (since a not pattern does not match any facts XE "Fact" , it cannot be used to define the values of any You can introduce variables in a not pattern, so long as they are used only within that pattern; i.e, Jess> (defrule XE "defrule" not CE is evaluated only when either a fact XE "Fact" matching it exists, or when the pattern before the not on the rule's LHS is the fact created by the reset \l "reset​) command is necessary to the proper of some not patterns XE "Pattern" . For example, suppose you want a rule to fire once if for every fact XE "Fact" (a ?x), there is a fact (b (defrule XE "defrule" (defrule XE "defrule" pattern with test as the head is special; the body consists not of a pattern to match against the working memory XE "Working memory" but of a Boolean XE person (slot XE "Slot" (defrule XE "defrule" that a test pattern, like a not, cannot define any variables for use in later patterns XE "Pattern" . A test CE XE "test CE" is evaluated every time the preceding pattern on the rule's LHS is (defrule XE "defrule" (defrule XE "defrule" rule_2 In fact XE "Fact" , starting with Jess 7.1, the functions in a test CE XE "test CE" are simply added to the previous pattern's you need to evaluate a function during pattern matching, a test CE is often clearer than the slot XE "Slot" test. You should now why, for rules XE "Rule" in which a test CE XE "test CE" is the first pattern on the LHS or the first pattern in a branch of an or CE, the pattern XE "Fact" ) is inserted to become the pattern" for the test. The fact is therefore also important for the proper of the test element XE element (CE)" ; the caution about reset \l "reset​) in the preceding section (​" \l "not_ce​) applies equally to test. For example, imagine that you've got two Java classes, A and B, and that A has a method contains XE which takes a B as an argument and returns imagine that you've defined shadow fact XE "Fact: shadow" templates XE for both these classes and are writing rules XE "Rule" to work with them. If the return value of contains XE changes, the match will be and Jess's internal data may be correct way to express this same set of patterns XE "Pattern" is to use the test element XE element (CE)" , like this: All the facts asserted on the RHS of a rule become dependent on the matches to the logical patterns XE "Pattern" on that rule's (defrule XE "defrule" XE "Fact" -0> Jess> (facts XE "Fact" ) For a total of 2 facts XE "Fact" in module (watch facts XE "Fact" ) Jess> (retract (fact XE "Fact" -id 0)) In a future version of Jess, it will be possible for a shadow fact to provide logical support based on any of slot XE "Slot" Jess language functions \l and \l let you query XE "Query" the logical among facts XE "Fact" . Jess> (defrule XE "defrule" XE employee (slot XE "Slot" salary) (slot (defrule XE "defrule" (defrule XE "defrule" <- (bind ?list (new XE )) ;; general, you might want to declare XE "declare rule" a large value for a rule that was likely to generate many partial matches (prime numbers are the best choices:) Jess> (defrule XE "defrule" the of the \l XE function for a full of this value and what it can now include a "declare XE "declare rule" " section just as defrules can. A template XE with this will be matched in a special way: if a fact XE "Fact" , created from such a template, which matches the of a rule is modified, the result depends on whether the modified slot is named in the pattern used to match the XE D (declare XE "declare rule" (slot XE "Slot" -specific XE TRUE)) (slot A) (slot B)) Jess> (defrule XE "defrule" R Without the "slot XE "Slot" -specific XE " this rule would enter an endless loop, because it modifies a fact XE "Fact" matched on the LHS in such a way that the modified fact will still rules XE "Rule" You can undefine a rule with the jess.Rete XE "Rete" \l use backward chaining XE "Backward chaining" in Jess, you must first declare XE "declare rule" that certain fact XE "Fact" templates XE will be backward chaining XE you can use the \l XE "Backward chaining" function after the template XE is defined: Jess> XE "Backward chaining" you can define rules XE "Rule" which match such patterns XE "Pattern" . Note that templates XE must be declared to be backwards chaining reactive before you define any rules which use the (defrule XE "defrule" the rule compiler sees that a pattern matches a backward chaining XE "Backward chaining" reactive template XE , it rewrites the rule and inserts some special code into the internal of the rule's LHS. This code asserts a fact XE "Fact" onto the fact-list that looks like Now, you can write rules XE "Rule" which match these need- XE (x) facts XE "Fact" . Jess> (defrule XE "defrule" XE factorial ?x ?) The rule compiler rewrites rules XE "Rule" like this too: it adds a negated match for the factorial pattern itself to the rule's LHS. The end result is that you can write rules XE "Rule" which match on and if they are close to firing except they need a fact XE "Fact" to do so, any (need- XE rules may be will chain backwards through any number of reactive patterns XE "Pattern" . Jess> XE "Backward chaining" XE "Backward chaining" (defrule XE "defrule" (defrule XE "defrule" XE foo $?) Jess> (defrule XE "defrule" this example, none of the rules XE "Rule" can be activated at sees that rule-1 could be activated if there were an foo fact XE "Fact" , so it generates the request (need- XE foo nil for CLIPS users: Jess's defmodule XE construct XE is similar to the CLIPS construct by the same name, but it is not XE XE WORK::job (slot XE "Slot" XE XE bus (slot XE "Slot" (defrule XE "defrule" implied template XE was created in the COMMUTE module, because that's where the rule was module defines a namespace for templates XE and rules XE "Rule" . Given this fact XE "Fact" , there is the question of how Jess decides which template the of a rule or query XE "Query" is referring to. When Jess is compiling a rule or deffacts XE it will look for templates XE in three places, in order: 3. If the template XE is not found in the rule's module, the module MAIN is searched XE "Fact" -0> Jess> XE XE job (slot XE "Slot" XE XE hobby (slot XE "Slot" name) (slot (defrule XE "defrule" finds the WORK::job template XE because the rule is defined in the WORK that many of the commands that list XE (facts \l "facts​) XE "Fact" , \l rules \l "rules​) XE "Rule" , etc) accept a module name or "*" as an optional general, although any Jess rule can be activated at any time, only rules XE "Rule" in the focus XE "focus" module will XE (defrule XE "defrule" the example above, the rule doesn't fire because the DRIVING module doesn't have the focus XE "focus" . Jess> (focus XE "focus" that you can call focus \l "focus​) XE "focus" from the of a rule to change the focus while the engine is actually maintains a focus XE "focus" stack an arbitrary number of XE (defrule XE "defrule" (defrule XE "defrule" XE "Fact" -1> <Fact XE "Fact" -2> Jess> (focus XE "focus" call the module from a rule's RHS using focus \l "focus​) XE "focus" and you return from the call using return \l stop executing a rule's actions without popping the focus XE "focus" stack, use break \l "break​) should not be a common but you can remove a module from the engine using the jess.Rete XE "Rete" \l there are any templates XE or rules XE "Rule" defined in the module, you'll get an working memory XE "Working memory" is similar to a database XE ; it's filled with indexed, supports this kind of search of Java objects in working memory XE "Working memory" using the can implement and then pass an instance of your filter to the jess.Rete XE "Rete" \l method, which will return an over the selected the we run a Jess program that deals in Payment objects, then query XE "Query" working memory for all the Payment objects and call process() on each one: The defquery \l XE construct XE lets you create a special kind of rule with no a rule is activated once for each matching set of facts XE "Fact" , a query XE "Query" gives you a XE object which gives you access to a list of all the XE person (slot XE "Slot" (slot lastName) (slot age)) We write a pattern which matches the facts XE "Fact" that we're in. We declare XE "declare rule" the variable XE ?ln, which makes it a parameter to the query, and we also include variables ?fn and ?age bound to the firstName and age slots XE "Slot" , (defquery XE XE "declare rule" (deffacts XE we define a query XE "Query" , we can call it using the \l function in Jess, or the jess.Rete XE "Rete" XE ) \l method in (bind ?result XE "Query" * arguments to run-query XE "Query" * \l are the name of the query and values for each function returns a XE object, which we store in the variable XE that we've created a XE , it's time to iterate over all the matches and process them however we'd like. The interface of the XE class is very similar to that of use \l "next()​) to advance to the next result, and we use the set of getXXX() methods to return the values bound to the variables defined in the query XE "Query" . You have already realized that two different kinds of variables can appear in a query XE "Query" : those that are to the query, like ?age in the query above, and those that are or to be specified in the \l command when the query is executed, like ?ln. Jess assumes all variables in a query are internal by default XE "default value" ; you must declare XE "declare rule" any external variables using the syntax (declare XE "declare rule" ?X ?Y ...)) For this to be useful, jess.Rete XE "Rete" .run() \l "run()​) must be called while the query XE "Query" is being to allow the backward chaining to generated by rules XE "Rule" fired during this run may appear as part of the query obtain just the number of matches for a query XE "Query" , you can use the \l function.