[rules-users] Using Collections in LHS

Ansgar Konermann ansgar.konermann at googlemail.com
Wed Feb 24 12:32:00 EST 2010


Am 24.02.2010 08:37, schrieb Wolfgang Laun:
> You really ought to read all the pertaining sections in the Drools 
> Expert manual and experiment. Nobody can write complex rules without 
> some exercise.
>
> 2010/2/24 dhari <sdhari at hotmail.com <mailto:sdhari at hotmail.com>>
>
>     Thanks Jeffery.  I'll try this but what if I have more complex
>     condition e.g.
>
>
>     Order ($discount : discount, $items : items)
>     Item(grade > 3 && (quantity < 5 || $discount > 10)) from $items
>
>
> Again, you are using a condition on discount not next to the field in 
> the fact where it occurs (i.e., Order); it's just not possible to 
> write it this way.
>
> Order( discount > 10, $items : items )   # all Orders where discount > 10
> Item( grade > 3, quantity < 5 ) from $items # and each of its Items 
> where grade > 3 and quantity < 5
>
> There is no need to use && to combine two conditions for the same fact.
>
> Now if you need to detect Order Items with grade > 3 where either the 
> quantitiy of the Item is < 5, or  the Order's discount > 10, (or both) 
> you'd have to write
>
> Order( $discount : discount, $items : items )   # all Orders
> Item( grade > 3, $quantity : quantity) from $items # and each of its 
> Items where grade > 3
> eval( $discount > 10 || $quantitiy < 5 ) # and discount > 10 or 
> quantity < 5 (or both)

Hi!

Another technique we commonly use at my employer to break up overly 
complex rules is to "factor out" subexpressions, preferrably using 
locally declared fact types to express the subexpressions, e. g.:

declare ItemPreventingDiscount
   item: Item
   order: Order
   reason: String
end

rule "Prevent discount > 10 for items graded > 3"
when
   $order: Order(discount > 10, $items: items)
   $item: Item(grade > 3) from $items
then
   ItemPreventingDiscount fact = new ItemPreventingDiscount();
   fact.setItem($item); // optional
   fact.setOrder($order); // optional
   fact.setReason("discount percentage > 10 not valid for items graded > 
3");
   insertLogical($fact);
end

// add more rules to prevent other combinations of discount, quantity, 
... whatever

rule "Issue error message if items preventing discount exist"
when
   exists( ItemPreventingDiscount( $reason: reason, $item: item ) )
then
   System.out.println("Discount not allowed: Item '"+ 
$item.getDescription() + "' prevents discount because " + $reason + ".");
end

One might debate whether it is already appropriate to factor out 
subexpressions for this still rather simple example, yet our experience 
is that in general it leads to code with an improved readability. I'd go 
so far to suggest that whenever you're struggling with the syntax of the 
language you're using to solve a problem, ask yourself whether you're 
trying to achieve too much with too little code. The answer is of course 
depending on your level of experience with the language, nevertheless 
you (the author of the code) probably want to be able to read and 
understand the code at any time.

Kind regards

Ansgar
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20100224/bc979515/attachment.html 


More information about the rules-users mailing list