Поскольку факты не могут быть дублированы, вы можете иметь условие проверки правил для любого факта и затем действия правила утверждают, как:
(defrule oilIfAndOnlyIfBlackAndFlammable
(or (Object (type oil))
(Object (color black) (flammable yes)))
=>
(assert (Object (type oil))
(Object (color black) (flammable yes))))
В качестве альтернативы, вы можете написать общее правило (который является более сложным), что соответствует факту (в более простом представлении), представляющем тогда и только тогда, когда отношения:
(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))))
'(Объект (тип масло)) (Объект (черный цвет) (воспламеняются да))' все еще написано дважды в этом правиле. Можно ли еще более упростить его? –
Я также добавил подход, который использует более сложное общее правило для сопоставления более простых фактов, представляющих отношения if и only if. –