I wanted to add and print the total quantity of three Products from facts. Also i need to perform a check too, on product 1 if the quantity is greater than 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
The or conditional element works by creating multiple rules, one for each permutation of all possible combinations of the conditional elements found within the or conditional elements in the conditions of the rule. Each of the generated rules use the same actions as the original rule. Thus your sum_of_quantity rule is translated to the following three rules (which share the same name):
(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))
Looking at the generated rules you can see that there are variables in the actions of the rules that are not bound in the conditions of the rules. So when using the or conditional element, any variables referenced in the actions of the rule must be bound in each permutation.
Some rule-based language provide a "collect" conditional element that allows to easily compute summations in the conditions of a rule, but unfortunately CLIPS does not provide this functionality. You can however use the do-for-all-facts query function to iterate over a group of facts in the actions of a rule:
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>
In this example, the exists conditional element is used in the conditions of the rule so that there is only one activation regardless of how many Product facts exists. This rule will activate if there is any Product fact with a productNumber of 1, 2, or 3. If you wanted all productNumbers to be required, you'd write the patterns like this:
(exists (Product (productNumber 1))
(Product (productNumber 2))
(Product (productNumber 3)))
The actions of the rule use the do-for-all-facts function to iterate over each Product fact and add the quantity slot to a running total.