Hey there,
The situation is I've pulled a set of facts from a database and asserted each one. Then, a rule runs that asserts a fact that contradicts a fact pulled from the database, so I want to retract the contradicting fact and assert the new fact.
i.e. the fact (status sX) was pulled from the database and asserted, and a rule fires whose RHS contains (assert (status s1)), but I would like to retract (status sX) before asserting (status s1).
The following loops infinitely, as one would expect:
Furthermore, (status sX) may or may not exist, so the rule doesn't even fire unless (status sX) is present.
I thought maybe using templates and (modify) was the answer, but it requires a fact specifier, which requires me to match the fact on the LHS, and again (status sX) may or may not exist, and this loops infinitely anyway:
So basically, I need a simple way to replace (status sX) with a given (status sY), regardless of what X may be. Also, this rule might assert multiple facts, all of which may need to replace contradicting facts. Does the answer lie in templates?
Any ideas?
Thanks in advance,
Larry
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hey there,
The situation is I've pulled a set of facts from a database and asserted each one. Then, a rule runs that asserts a fact that contradicts a fact pulled from the database, so I want to retract the contradicting fact and assert the new fact.
i.e. the fact (status sX) was pulled from the database and asserted, and a rule fires whose RHS contains (assert (status s1)), but I would like to retract (status sX) before asserting (status s1).
The following loops infinitely, as one would expect:
(assert(status s0))
(assert(someTrigger saysGo))
(defrule modifyStatus
(someTrigger saysGo)
?x <- (status ?)
=>
(retract ?x)
(assert (status s1))
)
Furthermore, (status sX) may or may not exist, so the rule doesn't even fire unless (status sX) is present.
I thought maybe using templates and (modify) was the answer, but it requires a fact specifier, which requires me to match the fact on the LHS, and again (status sX) may or may not exist, and this loops infinitely anyway:
(deftemplate person (slot status))
(assert(person (status s0)))
(assert(someTrigger saysGo))
(defrule modifyStatus
(someTrigger saysGo)
?x <- (person (status ?))
=>
(modify ?x (status s1))
)
So basically, I need a simple way to replace (status sX) with a given (status sY), regardless of what X may be. Also, this rule might assert multiple facts, all of which may need to replace contradicting facts. Does the answer lie in templates?
Any ideas?
Thanks in advance,
Larry
There are a couple of different ways you can prevent the rule from retriggering:
(defrule modifyStatus
(someTrigger saysGo ?v)
?x <- (person (status ?v))
=>
(modify ?x (status s1))
)
(defrule modifyStatus
?f <- (someTrigger saysGo)
?x <- (person (status ?))
=>
(retract ?f)
(modify ?x (status s1))
)
(defrule modifyStatus
(someTrigger saysGo)
?x <- (person (status ~?s1))
=>
(modify ?x (status s1))
)