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@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