recursion - Recursive call to a rule -
i have rule fires thousands of other same rule:
(defrule calculate-temperature ?zone <- (object (is-a zone) (id ?id-zone) (dew-temperature ?dew-temperature) (delta-r ?delta-r)) (process-action (is cooling)) => (bind ?supply-temperature (+ ?delta-r ?dew-temperature)) (modify-instance ?zone (supply-temperature ?supply-temperature)) (printout ?*debug-print* "supply-temperature:", ?supply-temperature crlf))
what want modify zone's supply-temperature when can calculate it, i.e. when inside zone defined delta-r , dew-temperature. modification of object keeps on firing in recursice neverendless cycle. best practices avoid these annoying loops, please?
thank nicola
by rule doesn't loop:
clips> (clear) clips> (defclass zone (is-a user) (slot id) (slot dew-temperature) (slot supply-temperature) (slot delta-r)) clips> (definstances start-instances (z1 of zone (id 1) (dew-temperature 100) (delta-r 10))) clips> (deftemplate process-action (slot is)) clips> (deffacts start-facts (process-action (is cooling))) clips> (defglobal ?*debug-print* = nil) clips> (defrule calculate-temperature ?zone <- (object (is-a zone) (id ?id-zone) (dew-temperature ?dew-temperature) (delta-r ?delta-r)) (process-action (is cooling)) => (bind ?supply-temperature (+ ?delta-r ?dew-temperature)) (modify-instance ?zone (supply-temperature ?supply-temperature)) (printout ?*debug-print* "supply-temperature:", ?supply-temperature crlf)) clips> (watch slots) clips> (reset) ::= local slot id in instance z1 <- 1 ::= local slot dew-temperature in instance z1 <- 100 ::= local slot delta-r in instance z1 <- 10 ::= local slot supply-temperature in instance z1 <- nil clips> (run) ::= local slot supply-temperature in instance z1 <- 110 clips>
so it's interactions between rules causing loop.
there 3 general techniques prevent rule looping. first, can remove 1 of facts/instances matching conditions of rule. example, process-action fact:
(defrule calculate-temperature ?zone <- (object (is-a zone) (id ?id-zone) (dew-temperature ?dew-temperature) (delta-r ?delta-r)) ?p <- (process-action (is cooling)) => (retract ?p) (bind ?supply-temperature (+ ?delta-r ?dew-temperature)) (modify-instance ?zone (supply-temperature ?supply-temperature)) (printout ?*debug-print* "supply-temperature:", ?supply-temperature crlf))
second, can modify fact/instance slot value prevent pattern matching. example, delta-r:
(defrule calculate-temperature ?zone <- (object (is-a zone) (id ?id-zone) (dew-temperature ?dew-temperature) (delta-r ?delta-r&~0)) (process-action (is cooling)) => (bind ?supply-temperature (+ ?delta-r ?dew-temperature)) (modify-instance ?zone (supply-temperature ?supply-temperature) (delta-r 0)) (printout ?*debug-print* "supply-temperature:", ?supply-temperature crlf))
third (and applicable object pattern matching), rules triggered changes slots explicitly matched in conditions of rules. if want changes delta-r trigger rule, not changes dew-temperature, you'd write rule this:
(defrule calculate-temperature ?zone <- (object (is-a zone) (id ?id-zone) (delta-r ?delta-r)) (process-action (is cooling)) => (bind ?supply-temperature (+ ?delta-r (send ?zone get-dew-temperature))) (modify-instance ?zone (supply-temperature ?supply-temperature)) (printout ?*debug-print* "supply-temperature:", ?supply-temperature crlf))
Comments
Post a Comment