我想从事实中添加并打印三个产品的总数量。同时我也需要对产品1进行检查,如果数量大于1。
(defrule sum_of_quantity
(or
(Product (productNumber 1)(quantity ?quantity0))
(Product (productNumber 2)(quantity ?quantity1))
(Product (productNumber 3)(quantity ?quantity2)))
=>
(bind ?totalQuantity (integer(+ ?quantity0 ?quantity1 ?quantity2)))
(printout t "TotalQuantity is " ?totalQuantity crlf))
I am actually new to clips and is finding it difficult to write rules
该 或 条件元素的工作方式是创建多条规则,每条规则适用于在条件元素中找到的所有可能的组合。或 规则条件中的条件元素。生成的每条规则都使用与原始规则相同的动作。因此,你的sum_of_quantity规则被翻译成了下面的三个规则(它们有着相同的名字)。
(defrule sum_of_quantity
(Product (productNumber 1)(quantity ?quantity0))
=>
(bind ?totalQuantity (integer(+ ?quantity0 ?quantity1 ?quantity2)))
(printout t "TotalQuantity is " ?totalQuantity crlf))
(defrule sum_of_quantity
(Product (productNumber 2)(quantity ?quantity1))
=>
(bind ?totalQuantity (integer(+ ?quantity0 ?quantity1 ?quantity2)))
(printout t "TotalQuantity is " ?totalQuantity crlf))
(defrule sum_of_quantity
(Product (productNumber 3)(quantity ?quantity2)))
=>
(bind ?totalQuantity (integer(+ ?quantity0 ?quantity1 ?quantity2)))
(printout t "TotalQuantity is " ?totalQuantity crlf))
观察生成的规则,你可以看到,在规则的动作中,有一些变量是不受规则条件约束的。所以当使用 或 条件元素,在规则的动作中引用的任何变量都必须在每个排列中被绑定。
一些基于规则的语言提供了一个 "收集 "条件元素,可以轻松计算规则条件中的求和,但遗憾的是CLIPS没有提供这个功能。不过,你可以使用do-for-all-facts查询函数来迭代规则动作中的一组事实。
CLIPS (6.31 6/12/19)
CLIPS>
(deftemplate Product
(slot productNumber)
(slot quantity))
CLIPS>
(defrule sum_of_quantity
(exists (Product (productNumber 1 | 2 | 3)))
=>
(bind ?totalQuantity 0)
(do-for-all-facts ((?p Product))
(or (eq ?p:productNumber 1)
(eq ?p:productNumber 2)
(eq ?p:productNumber 3))
(bind ?totalQuantity (+ ?totalQuantity ?p:quantity)))
(printout t "TotalQuantity is " ?totalQuantity crlf))
CLIPS>
(assert (Product (productNumber 1) (quantity 10))
(Product (productNumber 2) (quantity 20))
(Product (productNumber 3) (quantity 30))
(Product (productNumber 4) (quantity 40)))
<Fact-4>
CLIPS> (run)
TotalQuantity is 60
CLIPS>
在这个例子中 存在 条件元素用于规则的条件中,因此无论存在多少产品事实,都只有一次激活。如果有任何产品事实的productNumber为1、2或3,该规则将被激活。如果您想让所有的 productNumbers 都是必需的,您可以这样写模式。
(exists (Product (productNumber 1))
(Product (productNumber 2))
(Product (productNumber 3)))
该规则的操作使用do-for-all-facts函数来迭代每个Product fact,并将数量槽添加到运行的总数中。
该 sum_of_quantity
规则是表示需要 至少一个 产品1、2、3之间的产品。然而,它是想把它们三个的数量相加。这在逻辑上是不正确的。
这就是引擎想告诉你的。右手边(RHS)指的是一个变量(quantity1
),而这些规则可能在您运行规则时没有被定义。这是因为您的规则将被激活,即使只是在 productNumber 1
是主张在。
只需将 or
条件,它就会工作。要看到规则激活,只需断言所有缺失的产品都有数量的 0
.