conditional 'or' just generates a rule per possible logic outcome, called a sub rule, each rule behaves completely independantly of the other sub rules - there is no shortcutting.

I'll investigate the error over the weekend.

Mark
Juergen wrote:
First, I would like to know how field bindings behave when used together with or, like in the following drl:

HelloWorld.drl:
---------------
package HelloWorld
import java.lang.String;
import org.drools.integrationtests.helloworld.A;

rule "rule"
    when
        A(x : a, b=="b") || A(a=="a", x : b)
    then
        assert(x);
        System.out.println("assert=" + x);
end

Of course it could be put in separate rules, but its allowed, and it yields ArrayIndexOutOfBoundsException. (Drools 3, Rev. 3505 (or 3502))

If A(x : a, b=="b") is evaluated and b fails, is x then "unbound" and free to be used in A(a=="a", x : b) again? + I assume "or" uses shortcut-evaluation, so if A(x : a, b=="b") holds, then A(a=="a", x : b) is not evaluated at all and x is therefore not bound to b (assuming A(a=="a", x : b) would hold too) but remains bound to a.

what if the second or operand has another binding? like A(a=="a", x : b, y : c) (assuming A has member c). y would be not bound if the second operand is never evaluated. Does drools check at when loading rules only when unbound variable is encountered during rule execution?

A.java:
-------
package org.drools.integrationtests.helloworld;
public class A{
    String a;
    String b;
    public A(String a, String b) {this.a = a;this.b = b;}
    public String getA() {return a;}
    public void setA(String a) {this.a = a;}
    public String getB() {return b;}
    public void setB(String b) {this.b = b;}
}

HelloWorldTest.java:
---------------------
...
    public void testSomething() {
        try {

            //load up the rulebase
            RuleBase ruleBase = readRule();
            WorkingMemory workingMemory = ruleBase.newWorkingMemory();
            workingMemory.assertObject(new A("x", "y"));
            workingMemory.fireAllRules();
            workingMemory.assertObject(new A("a", "Y"));
            workingMemory.fireAllRules();
            workingMemory.assertObject(new A("X", "b"));
            workingMemory.fireAllRules();
            //assertTrue( message.isFired() );
        } catch (Throwable t) {
            t.printStackTrace();
            fail(t.getMessage());
        }
    }
...

This dsl causes:
org.drools.spi.ConsequenceException: java.lang.ArrayIndexOutOfBoundsException: 1
    at org.drools.common.Agenda.fireActivation(Agenda.java:323)
    at org.drools.common.Agenda.fireNextItem(Agenda.java:299)
at org.drools.reteoo.WorkingMemoryImpl.fireAllRules(WorkingMemoryImpl.java:248) at org.drools.reteoo.WorkingMemoryImpl.fireAllRules(WorkingMemoryImpl.java:261) at org.drools.integrationtests.helloworld.HelloWorldTest.testSomething(HelloWorldTest.java:28)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:324)
    at junit.framework.TestCase.runTest(TestCase.java:154)
    at junit.framework.TestCase.runBare(TestCase.java:127)
    at junit.framework.TestResult$1.protect(TestResult.java:106)
    at junit.framework.TestResult.runProtected(TestResult.java:124)
    at junit.framework.TestResult.run(TestResult.java:109)
    at junit.framework.TestCase.run(TestCase.java:118)
    at junit.framework.TestSuite.runTest(TestSuite.java:208)
    at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:436) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:311) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

Caused by: java.lang.ArrayIndexOutOfBoundsException: 1
    at org.drools.reteoo.FactHandleList.get(FactHandleList.java:107)
    at org.drools.reteoo.TupleKey.get(TupleKey.java:90)
    at org.drools.reteoo.ReteTuple.get(ReteTuple.java:153)
    at org.drools.reteoo.ReteTuple.get(ReteTuple.java:160)
at HelloWorld.Rule_0ConsequenceInvoker.evaluate(Rule_0ConsequenceInvoker.java:12)
    at org.drools.common.Agenda.fireActivation(Agenda.java:321)
    ... 19 more

fyi, Juergen




Reply via email to