Условный элемент или работает путем создания нескольких правил, по одному для каждой перестановки всех возможных комбинаций условных элементов, найденных в условных элементах или в условиях правила. Каждое из сгенерированных правил использует те же действия, что и исходное правило. Таким образом, ваше правило 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 не предоставляет такой возможности. Однако вы можете использовать функцию запроса для всех фактов для перебора группы фактов в действиях правила:
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. Если вы хотите, чтобы все номера productNumber были обязательными, вы должны написать шаблоны следующим образом:
(exists (Product (productNumber 1))
(Product (productNumber 2))
(Product (productNumber 3)))
Действия правила используйте функцию do-for-all-fact, чтобы перебрать каждый факт Product и добавить интервал количества к промежуточной сумме.