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(a)hotmail.com <mailto: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