On 02/18/2013 02:35 PM, Geoffrey De Smet wrote:

Op 18-02-13 14:00, Willem van Asperen schreef:
On 02/18/2013 11:11 AM, Willem van Asperen wrote:
Hi All,

Just wanted to share with you an easy mistake. This is done running Drools 5.5.0.Final.

Imagine a fact

Cheese (
    creationTick : double
    preservationTicks : double
)

Then the following does not do what you expect:

rule "dump old cheese"
    when
        $c : Cheese( $sbd : creationTick + preservationTicks )
        CurrentTime( tick >= $sbd )
    then
        System.out.println("we have to dump "+$c);
end

You would expect that $c is dumped when current time has passed creationTick + preservationTicks. But no. The variable $sbd is bound to creationTick before the preservationTicks are added!! I must say that I do not quite understand how ($sbd : creationTick) + preservationTicks resolves to "true" to make the premise succeed... Maybe because it is != 0?

I found that it should be:

rule "dump old cheese"
    when
        $c : Cheese( $sbd : (creationTick + preservationTicks) )
        CurrentTime( tick >= $sbd )
    then
        System.out.println("we have to dump "+$c);
end

This makes sense. Now $sbd is bound to the result of the addition. But it is an easy trap!!

Regards,
Willem
Hi All,

Coming back to this... What will be evaluated in the following snippet:

rule "dump old cheese"
    when
        CurrentTime( $tick : tick )
        $c : Cheese( $tick >= creationTick + preservationTicks )
    then
        System.out.println("we need to dump "+$c);
end

I assume this evaluates if $tick is larger or equal to (creationTick + preservationTicks), right?
I think so too.
It looks like the : operator has a higher precedence then + (and therefor >= too), which is a bit surprising indeed.
Personally, I never mix the : operator with other operators, to avoid having to worry about the precendence.
So you would write:

rule "dump old cheese"
    when
        $c : Cheese( $ct : creationTick, $p : preservationTicks )
        CurrentTime( tick >= $ct + $p )
    then
        System.out.println("we have to dump "+$c);
end
       
Assuming + takes precedence over >=.

The reason I am binding the sum to creationTick and preservationTicks to a variable is that I am using that variable in multiple places and do not want the engine to have to calculate the sum for every occurrence. Also: it makes the rule more readable in my view.
Otherwise it would say

step 1:    $tick > creationTick + preservationTicks
step 2:    true + preservationTicks

which would fail, obviously because you cannot add a double to a boolean.

Regards,
Willem


_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users