[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