首页 > 解决方案 > 如何停止对已修改事实的规则重复激活?

问题描述

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

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

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

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

标签: 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))))

推荐阅读