如何停止对已修改的事实重复激活规则?

How to stop rule repeating activation on facts that have already been modified?

我在 CLIPS 中制定了一条规则,该规则从多槽字段中删除两个值。尽管它这样做了,但规则会在现在删除了这两个值的相同事实上重复自身,并且这种情况会无限继续下去。

下面是我的事实模板和规则

(deftemplate ar-node
    (slot group
        (type SYMBOL)
        (allowed-symbols grp1 grp2 grp3 grp4) )
    (slot name
        (type SYMBOL)
        (allowed-symbols oc nps ef sef yn))
    (slot direction
        (type SYMBOL)
        (allowed-symbols + -))
    (slot element
        (type INTEGER)
        (range 1 3))
    (slot trip
        (type INTEGER)
        (range 1 4))
    (multislot allowed-values
        (type SYMBOL)
        (allowed-symbols D R L A C S nil)
        (default D))
    (slot value
        (type SYMBOL)
        (allowed-symbols D R L A C S nil)
        (default D)))
(defrule 22_061 
    (ar-node (group ?group)
             (name ?name)
             (direction ?direction)
             (element ?element)
             (trip ?trip)
             (value ?value&R))
    
    =>
    (do-for-all-facts ((?fact ar-node)) (and (eq ?fact:group ?group)
                                             (eq ?fact:name ?name)
                                             (eq ?fact:direction ?direction)
                                             (eq ?fact:element 1)
                                             (> ?fact:trip 1))
    (modify ?fact (allowed-values (delete-member$ ?fact:allowed-values C S))))
)

这里还有一些将导致规则执行的示例事实(该规则只会从此处的第二个事实中删除 C 和 S)

(ar-node (group grp1) (name cool) (direction +) (element 1) (trip 1) (allowed-values L D R A C S) (value R))
(ar-node (group grp1) (name cool) (direction +) (element 1) (trip 2) (allowed-values L D R A C S) (value L))

我曾尝试使用更多参数仅在值存在时删除值,例如 RHS (and) 语句中的 (eq $member ?fact:allowed-values C S) 甚至规则的 LHS。然而,这些要么不起作用,要么规则根本不会执行。

我认为解决方案是通过某种方式来检查事实在 LHS 的多字段中是否有 C 或 S,但我不知道如何像在 RHS 上那样预先搜索所有事实。另外,如果有必要存储一些东西,我也不想编辑事实模板。

欢迎任何意见或建议,我是 CLIPS 的新手,很抱歉,如果这可能是微不足道的,但即使在使用了文档中的一堆功能后,我也感到非常难过。

您可以修改 RHS 中的查询以检查是否存在 C 或 S:

(defrule 22_061 
    (ar-node (group ?group)
             (name ?name)
             (direction ?direction)
             (value R))
    
    =>
    (do-for-all-facts ((?fact ar-node)) (and (eq ?fact:group ?group)
                                             (eq ?fact:name ?name)
                                             (eq ?fact:direction ?direction)
                                             (eq ?fact:element 1)
                                             (> ?fact:trip 1)
                                             (or (member$ C ?fact:allowed-values)
                                                 (member$ S ?fact:allowed-values)))
    (modify ?fact (allowed-values (delete-member$ ?fact:allowed-values C S))))
)

或者您可以在 LHS 中使用模式匹配并允许规则触发多次以修改所有事实:

(defrule 22_061 
    (ar-node (group ?group)
             (name ?name)
             (direction ?direction)
             (value R))
    ?fact <- (ar-node (group ?group)
                      (name ?name)
                      (direction ?direction)
                      (element 1)
                      (trip ?trip&:(> ?trip 1))
                      (allowed-values $?b C | S $?e))
    =>
    (modify ?fact (allowed-values (delete-member$ (create$ ?b ?e) C S))))