CLIPS:一次性模式匹配多时隙的值
CLIPS: One-time pattern matching a value of a multislot
我读过 所以回答
When an instance is created or deleted, all patterns applicable to
that object are updated. However, when a slot is changed, only those
patterns that explicitly match on that slot are affected.
现在我遇到了以下问题:
随着时间的推移,我有一个多槽接收越来越多的项目。
我有一个规则 R1
,如果 "some_value"
包含在多槽中,该规则就会触发。当我将 "some_value"
添加到多槽时,一切都按预期工作。但是,如果我添加另一个项目,对多槽说 "another_value"
,R1
会再次触发。这与我上面引用的一致,但这不是我想要的。如果 "some_value"
包含在多槽中,我希望 R1
仅触发一次,并且我不希望 R1
在将另一个值添加到多槽时再次触发。
我该怎么做?
我可以使用多个槽而不是一个多槽,但如果我不知道可能值的数量,这将不起作用。
如果您不能将值分配给不同的槽——这是您通常处理选定更改的触发规则的方式——那么您需要跟踪哪些更改已被处理。跟踪已处理的规则或值将是执行此操作的最直接方法。如果每个规则只处理一个值,那么跟踪规则会更好,这样您就可以为相同的值更改触发多个规则。这是一个示例,其中规则 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>
我读过
When an instance is created or deleted, all patterns applicable to that object are updated. However, when a slot is changed, only those patterns that explicitly match on that slot are affected.
现在我遇到了以下问题: 随着时间的推移,我有一个多槽接收越来越多的项目。
我有一个规则 R1
,如果 "some_value"
包含在多槽中,该规则就会触发。当我将 "some_value"
添加到多槽时,一切都按预期工作。但是,如果我添加另一个项目,对多槽说 "another_value"
,R1
会再次触发。这与我上面引用的一致,但这不是我想要的。如果 "some_value"
包含在多槽中,我希望 R1
仅触发一次,并且我不希望 R1
在将另一个值添加到多槽时再次触发。
我该怎么做?
我可以使用多个槽而不是一个多槽,但如果我不知道可能值的数量,这将不起作用。
如果您不能将值分配给不同的槽——这是您通常处理选定更改的触发规则的方式——那么您需要跟踪哪些更改已被处理。跟踪已处理的规则或值将是执行此操作的最直接方法。如果每个规则只处理一个值,那么跟踪规则会更好,这样您就可以为相同的值更改触发多个规则。这是一个示例,其中规则 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>