将剪辑中的值存储到变量中
storing values in clips into variable
我有一个模板
(deftemplate Product
(slot productId (type INTEGER))
(slot uom (default EA))
(slot quantity (type INTEGER))
(slot amount))
我正在使用
的代码
(defrule sum_of_quantity
(exists (Product (productId 1 | 2 | 3)(amount ?amount)))
=>
(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)))
(if (>= ?amount 5000) then
(printout t "TotalQuantity is " ?totalQuantity crlf)))
这里我收到一条错误消息:
defrule 的 RHS 中引用的未定义变量。
我要检查每个产品的数量是否大于5000,我们该怎么做。
一个简单的事实模式可以与多个不同的事实相匹配,这可能会导致多次激活一条规则:
CLIPS>
(deftemplate product
(slot id)
(slot amount))
CLIPS>
(deffacts products
(product (id 1) (amount 1000))
(product (id 2) (amount 3000))
(product (id 3) (amount 6000)))
CLIPS>
(defrule print-amount
(product (id ?id) (amount ?amount))
=>
(printout t ?id ": " ?amount crlf))
CLIPS> (reset)
CLIPS> (agenda)
0 print-amount: f-3
0 print-amount: f-2
0 print-amount: f-1
For a total of 3 activations.
CLIPS> (run)
3: 6000
2: 3000
1: 1000
CLIPS>
当允许执行每个激活时,从与激活关联的产品事实中检索可变金额。所以有 3 个规则触发,数量分别为 6000、3000 和 1000。
存在的条件元素只匹配一次,而不管它包含的事实模式匹配的次数:
CLIPS>
(defrule exists
(exists (product (id ?id) (amount ?amount)))
=>)
CLIPS> (agenda)
0 exists: *
For a total of 1 activation.
CLIPS>
列出议程时,会显示一个 * 表示模式匹配,但不是根据特定事实匹配。如果您尝试在规则的操作中访问可变数量,您会收到错误消息。这是因为变量 amount 在模式之外没有意义,因为它没有特定的值。如果任意选择与事实模式匹配的事实之一来提供 amount 的值,您将获得不可预测的行为。
重写规则的最简单方法是将金额检查从规则的操作移至现有模式:
(defrule sum_of_quantity
(exists (Product (productId 1 | 2 | 3)
(amount ?amount&:(>= ?amount 5000))))
=>
(bind ?totalQuantity 0)
(do-for-all-facts ((?p Product))
(or (eq ?p:productId 1)
(eq ?p:productId 2)
(eq ?p:productId 3))
(bind ?totalQuantity (+ ?totalQuantity ?p:quantity)))
(printout t "TotalQuantity is " ?totalQuantity crlf))
您的 do-for-all-facts 查询还引用了 productNumber 而不是 productId。
我有一个模板
(deftemplate Product
(slot productId (type INTEGER))
(slot uom (default EA))
(slot quantity (type INTEGER))
(slot amount))
我正在使用
的代码(defrule sum_of_quantity
(exists (Product (productId 1 | 2 | 3)(amount ?amount)))
=>
(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)))
(if (>= ?amount 5000) then
(printout t "TotalQuantity is " ?totalQuantity crlf)))
这里我收到一条错误消息: defrule 的 RHS 中引用的未定义变量。
我要检查每个产品的数量是否大于5000,我们该怎么做。
一个简单的事实模式可以与多个不同的事实相匹配,这可能会导致多次激活一条规则:
CLIPS>
(deftemplate product
(slot id)
(slot amount))
CLIPS>
(deffacts products
(product (id 1) (amount 1000))
(product (id 2) (amount 3000))
(product (id 3) (amount 6000)))
CLIPS>
(defrule print-amount
(product (id ?id) (amount ?amount))
=>
(printout t ?id ": " ?amount crlf))
CLIPS> (reset)
CLIPS> (agenda)
0 print-amount: f-3
0 print-amount: f-2
0 print-amount: f-1
For a total of 3 activations.
CLIPS> (run)
3: 6000
2: 3000
1: 1000
CLIPS>
当允许执行每个激活时,从与激活关联的产品事实中检索可变金额。所以有 3 个规则触发,数量分别为 6000、3000 和 1000。
存在的条件元素只匹配一次,而不管它包含的事实模式匹配的次数:
CLIPS>
(defrule exists
(exists (product (id ?id) (amount ?amount)))
=>)
CLIPS> (agenda)
0 exists: *
For a total of 1 activation.
CLIPS>
列出议程时,会显示一个 * 表示模式匹配,但不是根据特定事实匹配。如果您尝试在规则的操作中访问可变数量,您会收到错误消息。这是因为变量 amount 在模式之外没有意义,因为它没有特定的值。如果任意选择与事实模式匹配的事实之一来提供 amount 的值,您将获得不可预测的行为。
重写规则的最简单方法是将金额检查从规则的操作移至现有模式:
(defrule sum_of_quantity
(exists (Product (productId 1 | 2 | 3)
(amount ?amount&:(>= ?amount 5000))))
=>
(bind ?totalQuantity 0)
(do-for-all-facts ((?p Product))
(or (eq ?p:productId 1)
(eq ?p:productId 2)
(eq ?p:productId 3))
(bind ?totalQuantity (+ ?totalQuantity ?p:quantity)))
(printout t "TotalQuantity is " ?totalQuantity crlf))
您的 do-for-all-facts 查询还引用了 productNumber 而不是 productId。