[rules-users] Unexpected behavior of accumulate() and insertLogical() when the result() goes from matching a constraint to not matching

mikerod mjr4184 at gmail.com
Sat Oct 26 16:32:10 EDT 2013


This is a follow up from my original post @
http://drools.46999.n3.nabble.com/rules-users-Question-about-custom-accumulation-functions-tp3280838p4026505.html

Using Drools version 5.5.0.Final

I am experiencing behavior I did not expect, regarding Drools accumulate
functionality.
The following demonstrates:

With an example (contrived) rule such as:

file <<example.drl>>

package drools

rule "testing"
	dialect "mvel"
	when
		$res : Long() from accumulate( $l : Long(),
							    init( Long highest = null; ),
							    action( highest = ((null == highest) || ($l > highest)) ? $l :
highest; ),
							    result( (highest < 10) ? highest : null; )) 
	then
		insertLogical( new String("inserted " + $res.toString()) );
	
end

endfile <<example.drl>>

I have the following, simple test case:

file <<ExampleDroolsTest.java>>

package drools;

import java.io.IOException;

import org.drools.KnowledgeBase;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;
import org.junit.Test;

public class ExampleDroolsTest {

    @Test
    public void test() throws IOException {
        final KnowledgeBuilder kbuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder();
       
kbuilder.add(ResourceFactory.newClassPathResource("drools/example.drl"),
ResourceType.DRL);
        final KnowledgeBase kbase = kbuilder.newKnowledgeBase();

        final StatefulKnowledgeSession ksession =
kbase.newStatefulKnowledgeSession();

        /** HERE the insertion order of these two facts, will result in
different outcomes for 
         * the rule "testing" in example.drl .
         * In this order, I will get the RHS logic to insert the new
String("inserted" + $res.toString())
         * The accumulate should be getting the max valued Long, in the end
and then the `result` of the
         * `accumulate` should yield a null value.
         *
         * If I flip the inserts, no fact is inserted into the session.
         */
        ksession.insert(new Long(5));
        ksession.insert(new Long(15));

        final int rulesFired = ksession.fireAllRules();

        System.out.println("Rules fired: " + rulesFired);

        System.out.println("Session objs:");
        for (final Object o : ksession.getObjects()) {
            System.out.println(o);
        }
        ksession.dispose();
    }
}

endfile <<ExampleDroolsTest.java>>

As I note in the Java source comment above, the order of the insertions of
the Long's into the session, change the results of the rule execution.  My
initial understanding of accumulate, would be that the LHS would be
invalidated once the highest Long value
was found to be 15 > 10, as the `result` portion of the `accumulate` tests. 
Since the String object is inserted logically, I'd 
expect the fact to be retracted from the working memory once the LHS of the
rule "testing" was found to be false.
If this were the case, the order of insertions above in the test case, would
result in the same working memory after rule execution.

Is this intended behavior of the accumulate node along with the
`insertLogical` operation?  

Thanks!



--
View this message in context: http://drools.46999.n3.nabble.com/Unexpected-behavior-of-accumulate-and-insertLogical-when-the-result-goes-from-matching-a-constraint-g-tp4026507.html
Sent from the Drools: User forum mailing list archive at Nabble.com.


More information about the rules-users mailing list