Menu

How to replace a contradicting fact

Help
lazd
2010-05-06
2012-11-23
  • lazd

    lazd - 2010-05-06

    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

     
  • Gary Riley

    Gary Riley - 2010-05-09

    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))
    )

     

Log in to post a comment.