I've been doing rulebased systems (RBS) since 1989. I even worked for Neuron Data way back when the only "real" tool that they had was Nexpert, a full opportunistic backward chaining system. Anyway, I've picked up a few tricks along the way.
Jess (along with OPSJ, drools, Mandarex, JEOPS and others) are tools for programmers, not for business analysts; much like C++ and Java. There are other, must more expensive systems, that have extensive debugging tools, GUI screens for business analysts and special language processors for the business analysts. Some are scalable; some are not.
Also, the thought process jump from OO to declarative languages is akin to the thought process jump from procedural to OO. It's still bits and bytes on the computer, the change is the approach and the view of the logic. The "Jess In Action book" is good and does an excellent job of teaching Jess, but it only goes so far. There are many other books that might help, but not many programmers have the time to read and understand these books. See http://www.kbsc.com/aibooks.html for a suggested list. Many of these go more into the technical, statistical, theory, etc. than most programmers or users have a need.
I suppose that the main thing to consider is that the rules are declarative and each rule must be incrementally independent; it must contain the logic that it needs and not depend on another rule to fire first before it fires. We get around that by using either goal-driven rules or priorities, but priorities are something that should be used with great discretion - no more than three levels if possible. Setup priority rules, logic priority rules and clean-up priority rules.
Take care and remember, it's a long, long road with lots of study on your own. The time problem is something that management rarely understands so you have to "sell" that concept to the management. Working with rules is 70% thought and design and only 30% implementation. I just go off the phone with the Maricopa County Attorney's office who have implemented a rulebased system over a three year period, but they spend a lot of time up front considering all of the requirements, constraints, etc. BEFORE writing the first line of code. And they follow that same process for any new project that comes along that needs rules. Something well worth thinking about.
SDG jco
Mitch Christensen wrote:
Thanks All.
DeMorgan's laws is what I was trying to remember last night (and couldn't). I knew there was a way to transpose/normalize logic, but couldn't recall the specifics.
However, ;)
I did do a truth table, and I did change the logic to fix my rule before posting my question. My problem is that now I am having a hard time explaining *why* it works. In other words, it works now, but looking at the rule, I would insist that it shouldn't.
Here is my truth table.
StmtA : (not (and A B)) which is equivalent to (or (not A)(not B)) StmtB : (and (not A)(not B))
+---+---+-------+-------+ | A | B | StmtA | StmtB | +---+---+-------+-------+ | 0 | 0 | 1 | 1 | +---+---+-------+-------+ | 1 | 0 | 1 | 0 | +---+---+-------+-------+ | 0 | 1 | 1 | 0 | +---+---+-------+-------+ | 1 | 1 | 0 | 0 | +---+---+-------+-------+
Now, whenever my CE is true (i.e. StmtX is 1), my rule should fire. Since I was incorrectly using StmtA instead of StmtB, I would expect my rule to fire occasionally when it shouldn't (i.e. false positives). The symptom I was getting was that my rule wasn't firing when it otherwise should as all the previous patterns were matched. I simply converted to the StmtB form and the rule fired. How can that be?
To address Ernest's warning, this CE is the last statement prior to the "=>", so ?rowAmt is declared outside of the CE.
I apologize if I'm just noising up the list. It's great that it works, but it worries me that I can't explain why.
-Mitch
P.S. Here is the complete rule in case that helps:
(defrule find-ncp-row-partic-name "Find all NCP records" (column (type amount)(x ?xc)(y ?yc)(width ?wc)(height ?hc)) ?amt <- (word (text ?tAmt&:(not (regex-match ?tAmt "^\\p{Punct}+$"))) (x ?xAmt&:(and (>= ?xAmt ?xc)(< ?xAmt (+ ?xc ?wc)))) (y ?rowAmt&:(and (>= ?rowAmt ?yc)(< ?rowAmt (+ ?yc ?hc)))) (width ?wAmt&:(and (> ?wAmt 5)(<= ?wAmt ?wc)))) ?name1 <- (word (text ?tName1&:(regex-match (upcase ?tName1) "^[A-Z][A-Z\\-]+,?$")) (x ?xName1) (y ?rowName1&:(same-row ?rowName1 ?rowAmt))) ?name2 <- (word (text ?tName2&:(regex-match (upcase ?tName2) "^[A-Z][A-Z\\-]+,?$")) (x ?xName2&:(> ?xName2 ?xName1)) (y ?rowName2)) (adjacent (left ?name1)(right ?name2)) ?partic <- (word (text ?tPartic&:(regex-match ?tPartic "[0-9]{4,9}")) (x ?xPartic&:(and (> ?xPartic ?xName2)(< ?xPartic ?xAmt))) (y ?rowPartic&:(same-row ?rowPartic ?rowAmt))) (adjacent (left ?name2)(right ?partic)) (process-page (page ?p)) (and (not (allocation-amount (page ?p)(row ?rowAa&:(same-row ?rowAa ?rowAmt))(x ?xAmt))) (not (word (x ?xOther&:(< ?xOther ?xName1)) (y ?yOther&:(same-row ?yOther ?rowAmt))))) => (printout t "Allocation entity found: ocr " ?tName1 " " ?tName2 " " ?tPartic " " ?tAmt " at " ?xAmt ","?rowAmt crlf) (assert (allocation-entity (source ocr)(page ?p)(row ?rowAmt) (firstName ?name2) (lastName ?name1) (particid ?partic)) ) (assert (allocation-amount (page ?p)(row ?rowAmt)(x ?xAmt)(value ?tAmt)(word ?amt))))
P.P.S I still need to take advantage of the new regular expression pattern matching instead of using my regex-match user function.
-----Original Message----- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Dusan Sormaz Sent: Wednesday, March 09, 2005 12:01 AM To: jess-users@sandia.gov Subject: Re: JESS: Reversing logic
First morning shot on it:
De Morgan's laws: (not ( and a b)) == (or (not a) (not b))
Dusan Sormaz
At 08:17 PM 3/8/2005, you wrote:
Ok, I know that I should know this, but I'm having trouble reasoning through it. Why do the following two CEs versions produce significantly different results? The only difference is that I'm reversing the and/not order, but this results significantly different activation results.
(not (and (allocation-amount (page ?p)(row ?rowAa&:(same-row ?rowAa ?rowAmt))(x ?xAmt)) (word (x ?xOther&:(< ?xOther ?xName1))(y ?yOther&:(same-row ?yOther ?rowAmt)))))
(and (not (allocation-amount (page ?p)(row ?rowAa&:(same-row ?rowAa ?rowAmt))(x ?xAmt))) (not (word (x ?xOther&:(< ?xOther ?xName1))(y ?yOther&:(same-row ?yOther ?rowAmt)))))
Thanks.
-Mitch
*********************************************************************
* Du9an )ormaz, PhD, Associate Professor * Ohio University
* Industrial and Manufacturing Systems Engineering Department
* 277 Stocker Center, Athens, OH 45701-2979
* phone: (740) 593-1545 * fax: (740) 593-0778 * e-mail: [EMAIL PROTECTED] * url: http://www.ent.ohiou.edu/~sormaz *********************************************************************
-------------------------------------------------------------------- To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]' in the BODY of a message to [EMAIL PROTECTED], NOT to the list (use your own address!) List problems? Notify [EMAIL PROTECTED] --------------------------------------------------------------------
-------------------------------------------------------------------- To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]' in the BODY of a message to [EMAIL PROTECTED], NOT to the list (use your own address!) List problems? Notify [EMAIL PROTECTED] --------------------------------------------------------------------