Как добавить несколько переменных в CLIPS? - PullRequest
0 голосов
/ 16 июня 2020

Я хотел сложить и распечатать общее количество трех Продуктов из фактов. Также мне нужно выполнить проверку продукта 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

Ответы [ 2 ]

1 голос
/ 17 июня 2020

Условный элемент или работает путем создания нескольких правил, по одному для каждой перестановки всех возможных комбинаций условных элементов, найденных в условных элементах или в условиях правила. Каждое из сгенерированных правил использует те же действия, что и исходное правило. Таким образом, ваше правило 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 и добавить интервал количества к промежуточной сумме.

0 голосов
/ 16 июня 2020

Правило sum_of_quantity выражает необходимость по крайней мере одного продукта между продуктами 1, 2, 3. Тем не менее, оно пытается суммировать количество всех трех из них. Это логически неверно.

Это то, что движок пытается вам сказать. Правая сторона (RHS) относится к переменной (quantity1), которая может не быть определена после запуска правила. Это потому, что ваше правило активируется, даже если в нем указано только productNumber 1.

Просто удалите условие or в своем правиле, и оно будет работать. Чтобы увидеть срабатывание правила, просто подтвердите все недостающие продукты с количеством 0.

...