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>