[rules-users] Possible issue regarding 'accumulate' and 'collect' conditions

Álvaro Pantoja alvaropc.nortia at gmail.com
Wed Jun 19 06:16:40 EDT 2013


Hello

I switched recently from Drools 5.5.0 to Drools 6.0.0.Beta3 and some of 
my rule tests failed because Drools started doing weird things.

I've isolated the problem and I figured out that it has to do with the 
combination of "accumulate" and "collect" conditions in the same rule.

See this example here:
> import java.util.ArrayList
>
> declare Item
>     code: int
>     price: int
>     present: boolean
> end
>
> rule "Init"
> when
> then
>     insert(new Item(1,40,false));
>     insert(new Item(2,40,false));
>     insert(new Item(3,40,false));
>     insert(new Item(4,40,false));
> end
>
> rule "CollectAndAccumulateRule"
> when
>     //At least two items that aren't presents
>     objList: ArrayList(size>=2) from collect( Item(present==false))
>     //Total price bigger than 100
>     price: Number(intValue>=100) from accumulate( Item($w:price, 
> present==false), sum($w))
> then
>
>     System.out.println("Sum: "+price);
>     System.out.println("Items size: "+objList.size());
>
>     //Look for the minor price item
>     Item min = null;
>     for(Object obj: objList){
>         if (min!=null){
>             min = (min.getPrice()>((Item)obj).getPrice())?(Item)obj:min;
>         }
>         else {
>             min = (Item)obj;
>         }
>     }
>
>     //And make it a present
>     if (min!=null){
>         modify(min){setPresent(true)};
>     }
> end

It gets a list of items, and when exist at least two of them and the sum 
of its prices is bigger than 100, it makes a present of the cheapest 
one. For this, items have a "present" flag that gets activated when it 
becomes a present. Also, this flag is part of both "collect" and 
"accumulate" conditions, for the rule not to loop over already 
"presented" items.

So, having 4 items with price 40 each (rule "Init" insert them), 
expected result is to have 2 presents of price 40. Rule 
"CollectAndAccumulateRule" gets executed two times and loop stops when 
there are just two remaining items, with sum 80 (<100). Expected output 
would be:

    Sum: 160.0
    Items size: 4
    Sum: 120.0
    Items size: 3

This works fine in Drools 5.5.0, but not in 6.0.0.Beta3. In the latter 
rule "CollectAndAccumulateRule" gets called 3 times, and output is like 
this:

    Sum: 160.0
    Items size: 4
    Sum: 120.0
    Items size: 4
    Sum: 120.0
    Items size: 3

Is there some overall change in 6.0.0.Beta3 that affects this kind of 
rules or conditions? Or could this be an issue?

Furthermore, including this kind of rules in a package along with other 
no-conflictive rules, it makes the hole package start behaving 
unexpectedly. I guess it has to do with the way of the Rete tree is 
bulided when this kind of rules are present.

Note: I know there are alternatives and workwarounds to the scenario 
shown here (like merging both conditions into a single "accumulate"). 
Nevertheless the aim of this post is just to try to determinate wheter 
this must be considered an issue or not

Regards,
--
Alvaro
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20130619/72f8a8d6/attachment.html 


More information about the rules-users mailing list