RE: JESS: [EXTERNAL] Jess asserts fact that is not true
"Dwight Hare" <[email protected]> Wed, 27 Jun 2012 08:46:26 -0700
| Newsgroups | gmane.comp.java.jess |
|---|---|
| Message-ID | <B96DD689550AE14286D5886F15063C5001E0F7037FCE@MAILSERVER-2.office.paritycomputing.com> |
Duh. I had early on gotten into the habit of assigning the LHS clause to = a variable (as I did below in "?r <- ...") and then accessing the slots u= sing dotted vars that I had completely forgotten this alternative way of = assigning a slot value to a var in a rule. It works correctly now without= the global and it retracts the fact when I change the value representing= the current time. Apologies for wasting everyone's time with this stupid question. Dwight -----Original Message----- From: [email protected] [mailto:[email protected]] On= Behalf Of Wolfgang Laun Sent: Tuesday, June 26, 2012 9:59 PM To: [email protected] Subject: Re: JESS: [EXTERNAL] Jess asserts fact that is not true On 26/06/2012, Dwight Hare <[email protected]> wrote: > I am trying to reason about the passage of time in my rules. I would=20 > like to write the following rule: > > (defrule Test > ?r <- (logical (CurrentTime)) > (logical (Condition (time ?time&:(> (+ ?time 5) > ?r.t)))) > =3D> > (assert (Condition-met)) > ) > > Where "CurrentTime" is a fact that holds the current time, and I=20 > change the slot value "t" as time progresses. The rule fires if the=20 > "time" slot in the Condition plus 5 is greater than the current time=20 > (that is, is true within the last 5 time increments). But this syntax=20 > is not allowed because you cannot access a dotted variable (the "?r.t")= here. Why not simply (defrule Test (logical (CurrentTime ?ct)) (logical (Condition (time ?time&:(> (+ ?time 5) ?ct))= )) =3D> (assert (Condition-met)) ) which avoids all that global rigmarole? More below. > > My first alternative was to declare a defglobal called "*time*" and=20 > have that change value as time progresses. But there is no way to make=20 > the global a "logical" dependency of the asserted condition-met so it=20 > doesn't get retracted when the global changes in value sufficient to=20 > make the rule no longer be true. > > I came up with a workaround where in addition to the defglobal=20 > "*time*" I assert a Fact called CurrentTime that holds the same value i= n the "t" slot. > Now my rule is: > > (defrule Test > ?r <- (logical (CurrentTime (t ?t&:(=3D ?t ?*time*)= ))) > (logical (Condition (time ?time&:(> (+ ?time 5) =20 > ?*time*)))) ; Note I use the global here instead of the dotted var but= the value is the same > =3D> > (assert (Condition-met (globtime ?*time*)(facttime > ?r.t))) > ) The fallacy is buried in the second pattern which compares the (unchanged) Condition with the value in the global *time*. You know that = this has changed, but the Jess Engine doesn't. It works in the first patt= ern because you change the CurrentTime fact, and so this pattern is re-ev= aluated. Don't use globals in LHS patterns unless they are immutable. -W > > This says that if there is a CurrentTime fact whose slot "t" has the=20 > same value as the global "*time*" and there is a Condition whose=20 > "time" slot plus > 5 is greater than that time, then assert the Condition-met. My java=20 > code sets the global to "4", asserts the fact "(CurrentTime (t 4))",=20 > and then asserts the fact "(Condition (time 0))". Since all the=20 > conditions are met the rules engine asserts the fact=20 > "(MAIN::Condition-met (globtime 4) (facttime 4))". All is well though=20 > a bit clumsy. Now I want to move time forward where the=20 > "Condition-met" should no longer be true. I change the global to 10=20 > and modify the CurrentTime fact and set the "t" slot to 10 too. > > Then I run the rules engine and it retracts the "(MAIN::Condition-met=20 > (globtime 4) (facttime 4))" but then mysteriously asserts=20 > "(MAIN::Condition-met (globtime 10) (facttime 10))". Since the=20 > Condition time of 0 plus 5 is not greater than 10, it should not have a= sserted this. > Here is a dump of the facts in the rules engine at the end: > > 0: (MAIN::CurrentTime (t 10)) > 1: (MAIN::Condition (time 0)) > 3: (MAIN::Condition-met (globtime 10) (facttime 10)) > > I see no justification for the 3rd fact given the only rule I have. > > Is there a better way of accomplishing this? > > Dwight > -------------------------------------------------------------------- To unsubscribe, send the words 'unsubscribe jess-users [email protected]' in the BODY of a message to [email protected], NOT to the list (use yo= ur 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]= . --------------------------------------------------------------------