我在this中读到了回答
创建或删除实例时,所有模式都适用于 该对象已更新。但是,当一个插槽改变时,只有那些 在该插槽上明确匹配的模式会受到影响。
现在我遇到以下问题: 我有一个多时隙,随着时间的推移会收到越来越多的项目。
如果多时隙中包含R1
,则会触发规则"some_value"
。当我向多区域添加"some_value"
时,一切都按预期工作。但是,如果我添加另一个项目,对多区域说"another_value"
,R1
会再次触发。这与我上面引用的一致,但它不是我想要的。如果多时隙中包含R1
,我希望"some_value"
仅触发一次,如果在多时隙中添加了其他值,我也不希望再次触发R1
。
我该怎么做?
我可以使用多个插槽而不是多插槽,但如果我不知道可能的值的数量,这将无效。
答案 0 :(得分:1)
如果您无法将值分配给不同的插槽 - 这是您通常处理所选更改的触发规则的方式 - 那么您需要跟踪已处理的更改。跟踪已处理的规则或值将是最直接的方法。如果每个规则只处理一个值,那么跟踪规则会更好,这样您就可以为同一个值更改触发多个规则。这是一个示例,其中规则R1和R2仅限于单个更改,规则R3显示您当前遇到的行为:
CLIPS> (clear)
CLIPS>
(defclass XAMPL
(is-a USER)
(multislot properties)
(multislot processed))
CLIPS>
(definstances initial
([x1] of XAMPL))
CLIPS>
(defrule add_some_value
(declare (salience -1))
?o <- (object (name [x1])
(properties $?p&:(not (member$ some_value ?p))))
=>
(modify-instance ?o (properties some_value ?p)))
CLIPS>
(defrule add_another_value
(declare (salience -2))
?o <- (object (name [x1])
(properties $?p&:(not (member$ another_value ?p))))
=>
(modify-instance ?o (properties another_value ?p)))
CLIPS>
(defrule R1
?o <- (object (name [x1])
(properties $?properties&:(member$ some_value ?properties))
(processed $?processed&:(not (member$ R1 ?processed))))
=>
(modify-instance ?o (processed ?processed R1))
(printout t "Rule R1 fires" crlf))
CLIPS>
(defrule R2
?o <- (object (name [x1])
(properties $?properties&:(member$ some_value ?properties))
(processed $?processed&:(not (member$ some_value ?processed))))
=>
(modify-instance ?o (processed ?processed some_value))
(printout t "Rule R2 fires" crlf))
CLIPS>
(defrule R3
(object (name [x1])
(properties $?properties&:(member$ some_value ?properties)))
=>
(printout t "Rule R3 fires" crlf))
CLIPS> (reset)
CLIPS> (run)
Rule R2 fires
Rule R1 fires
Rule R3 fires
Rule R3 fires
CLIPS>