I am trying to reason about the passage of time in my rules. I would like to 
write the following rule:

(defrule Test
                    ?r <- (logical (CurrentTime))
                    (logical (Condition (time ?time&:(> (+ ?time 5) ?r.t))))
                    (assert (Condition-met))

Where "CurrentTime" is a fact that holds the current time, and I change the 
slot value "t" as time progresses. The rule fires if the "time" slot in the 
Condition plus 5 is greater than the current time (that is, is true within the 
last 5 time increments). But this syntax is not allowed because you cannot 
access a dotted variable (the "?r.t") here.

My first alternative was to declare a defglobal called "*time*" and have that 
change value as time progresses. But there is no way to make the global a 
"logical" dependency of the asserted condition-met so it doesn't get retracted 
when the global changes in value sufficient to make the rule no longer be true.

I came up with a workaround where in addition to the defglobal "*time*" I 
assert a Fact called CurrentTime that holds the same value in the "t" slot. Now 
my rule is:

(defrule Test
                    ?r <- (logical (CurrentTime (t ?t&:(= ?t ?*time*))))
                    (logical (Condition (time ?time&:(> (+ ?time 5) ?*time*)))) 
 ; Note I use the global here instead of the dotted var but the value is the 
                    (assert (Condition-met (globtime ?*time*)(facttime ?r.t)))

This says that if there is a CurrentTime fact whose slot "t" has the same value 
as the global "*time*" and there is a Condition whose "time" slot plus 5 is 
greater than that time, then assert the Condition-met. My java code sets the 
global to "4", asserts the fact "(CurrentTime (t 4))", and then asserts the 
fact "(Condition (time 0))". Since all the conditions are met the rules engine 
asserts the fact "(MAIN::Condition-met (globtime 4) (facttime 4))". All is well 
though a bit clumsy. Now I want to move time forward where the "Condition-met" 
should no longer be true. I change the global to 10 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 (globtime 
4) (facttime 4))" but then mysteriously asserts "(MAIN::Condition-met (globtime 
10) (facttime 10))". Since the Condition time of 0 plus 5 is not greater than 
10, it should not have asserted 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?


Reply via email to