如何在 CLIPS 中添加多个变量?

How to add multiple variable in CLIPS?

我想根据事实添加并打印三种产品的总数。如果数量大于 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 规则表达了产品 1、2、3 之间 至少一个 产品的需求。不过,它试图将所有三个产品的数量相加他们中的。这在逻辑上是不正确的。

这就是引擎试图告诉您的内容。右侧 (RHS) 指的是一个变量 (quantity1),一旦您 运行 规则,它可能不会被定义。这是因为即使在 productNumber 1 中声明了 productNumber 1,您的规则也会激活。

只需删除规则中的 or 条件即可。要查看激活的规则,只需声明所有数量为 0.

的缺失产品

or 条件元素通过创建多个规则来工作,每个规则对应 or[=27= 中找到的条件元素的所有可能组合的每个排列] 规则条件中的条件元素。每个生成的规则都使用与原始规则相同的操作。因此,您的 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)) 

查看生成的规则,您可以看到规则的操作中存在未绑定在规则条件中的变量。因此,当使用 条件元素时,规则操作中引用的任何变量都必须绑定在每个排列中。

一些基于规则的语言提供了一个 "collect" 条件元素,允许在规则条件下轻松计算求和,但不幸的是 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> 

在此示例中,exists 条件元素用于规则的条件中,因此无论存在多少产品事实,都只有一个激活。如果存在 productNumber 为 1、2 或 3 的任何 Product fact,则此规则将激活。如果您希望所有 productNumbers 都是必需的,您可以编写如下模式:

(exists (Product (productNumber 1))
        (Product (productNumber 2))
        (Product (productNumber 3)))

规则的操作使用 do-for-all-facts 函数迭代每个产品事实并将数量槽添加到 运行 总数。