I'm having troubles understanding why doesn't this clips code get trapped in an infinite loop
(defrule rule0
=>
(assert (my-fact))
)
(defrule rule1
?f <- (my-fact)
=>
(retract ?f)
)
As far as I know, rule0
is executed asserting my-fact
then rule1
is executed retracting it. Why doesn't rule0
execute again now?
Here are my thoughts:
Note: I abstracted this piece of code from another small program that uses templates instead of facts.
Wikipedia has a good overview of how the Rete Algorithm works. One of the key concepts to understand is that rules do not seek the data that satisfy them, rather data seeks out the rules they satisfy. The Rete Algorithm assumes that most data remains the same after each rule firing, so having the rules seek out data would be inefficient since only a fraction of the data changes after each rule firing. Instead rules save the state of what has already been matched and when changes to data is made that effects that state, it is updated.
When rule rule0 is defined, it is activated because it has no conditions. When rule rule1 is defined, it is not activated because my-fact does not yet exist. When rule rule0 is executed, the fact my-fact is asserted, and then rule rule1 has its state updated and is activated. When rule rule1 is executed, my-fact is retracted and the state of rule rule1 is updated since it matches my-fact. Rule rule0 is not affected by this retraction because it doesn't have conditions which match my-fact.