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

Wolfgang Laun wolfgang.laun at gmail.com
Wed Jun 19 07:20:46 EDT 2013


This is a bug.

-W


On 19/06/2013, Álvaro Pantoja <alvaropc.nortia at gmail.com> wrote:
> 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
>



More information about the rules-users mailing list