在CLIPS中定义“if if only only”规则

时间:2014-11-13 19:46:15

标签: clips

我在CLIPS专家系统中定义了“if-and-only-if”规则,但它需要两条规则而不是一条规则:

;the rules are doIfOil and doIfBlackAndFlammable
(deftemplate Object
    (slot type)
    (slot color)
    (slot flammable)
)

(defrule doIfOil
    (Object (type oil))
    =>
    (assert (Object (color black) (flammable yes)))
)

(defrule doIfBlackAndFlammable
    (Object (color black) (flammable yes))
    =>
    (assert (Object (type oil)))
)

(deffacts Result
    (Object
        (type oil)
    )
)

是否可以以较少冗余的方式重写此规则?

1 个答案:

答案 0 :(得分:1)

由于事实不可复制,您可以对规则进行检查,然后让规则的操作断言:

(defrule oilIfAndOnlyIfBlackAndFlammable
    (or (Object (type oil))
        (Object (color black) (flammable yes)))
    =>
    (assert (Object (type oil))
            (Object (color black) (flammable yes))))

或者,您可以编写一个通用规则(更复杂),该规则匹配表示if和only if关系的事实(以更简单的表示形式):

(deftemplate Object
   (slot type (default unspecified))
   (slot color (default unspecified))
   (slot flammable (default unspecified)))

(deftemplate iff
   (slot type1 (default unspecified))
   (slot color1 (default unspecified))
   (slot flammable1 (default unspecified))
   (slot type2 (default unspecified))
   (slot color2 (default unspecified))
   (slot flammable2 (default unspecified)))

(deffacts Result
    (Object
        (type oil)))

(deffacts iff
   (iff (type1 oil) (color2 black) (flammable2 yes)))

(defrule iff
   (iff (type1 ?type1) (color1 ?color1) (flammable1 ?flammable1) 
        (type2 ?type2) (color2 ?color2) (flammable2 ?flammable2))
   (Object (type ?type)
           (color ?color)
           (flammable ?flammable))
   (test (or (and (or (eq ?type ?type1) (eq ?type1 unspecified))
                  (or (eq ?color ?color1) (eq ?color1 unspecified))
                  (or (eq ?flammable ?flammable1) (eq ?flammable1 unspecified)))
             (and (or (eq ?type ?type2) (eq ?type2 unspecified)) 
                  (or (eq ?color ?color2) (eq ?color2 unspecified))
                  (or (eq ?flammable ?flammable2) (eq ?flammable2 unspecified)))))
   =>
   (assert (Object (type ?type1) (color ?color1) (flammable ?flammable1))
           (Object (type ?type2) (color ?color2) (flammable ?flammable2))))