Search code examples
javadrools

Why does the drools rule engine executes only once even when given inside a loop?


I am trying to learn drools for using in a project which needs to execute many boolean expressions in a loop. My current code is as below. This is just for testing and learning the concepts. The statement kSession.fireAllRules(); should execute the rules file many times as it is inside the for loop, but it only executes once. What am i doing wrong here?

Java code

        List outList = new ArrayList<Boolean>();
        kSession.setGlobal("outList", outList);
        List rulesList = new ArrayList<Boolean>();
        kSession.setGlobal("rulesList", rulesList);

        for (int i = 0; i < 10; i++) {

            rule1=!rule1;
            rule2 =!rule2;
            rule3 =!rule3;
            rulesList.clear();
            rulesList.add(rule1);
            rulesList.add(rule2);
            rulesList.add(rule3);

            kSession.insert(droolsIntroduction);
            kSession.fireAllRules();

            boolean result1 = (boolean) outList.get(0);
            boolean result2 = (boolean) outList.get(1);
            boolean result3 = (boolean) outList.get(2);

        }

Rule file:

global String topicLevel
global java.util.List rulesList
global java.util.List outList

rule "Drools Introduction"
when
$droolsIntro : DroolsIntroduction( measurename == "measure1")
then

boolean result1= (boolean)rulesList.get(0) && (boolean)rulesList.get(1)  && (boolean)rulesList.get(2)
boolean result2= result1 && (boolean)rulesList.get(2);
boolean result3= result1 &&  (boolean)rulesList.get(2);
//outList.clear();
outList.add(result1);
outList.add(result2);
outList.add(result3);

end
function String getDefaultIfNull(String topicLevel) {
return topicLevel == null ? "Moderate" : topicLevel;
}

Solution

  • Rules are not "executed" by calling the Drools engine. It is up to the Drools engine to decide which rules are to be "fired". As long as there is no change to any of the facts evaluated in a rule, the rule will not be fired again.

    You may, however, dispose the session, create another one and execute again, possibly with some variations in your data. This extended loop would include some code you haven't shown, so I can only sketch it here:

    for( int i =... ){
        KieSession kSession = ...;
        List outList = new ArrayList<Boolean>();
        kSession.setGlobal("outList", outList);
        List rulesList = new ArrayList<Boolean>();
        kSession.setGlobal("rulesList", rulesList);
        rule1 = ...;
        kSession.insert(droolsIntroduction);
        kSession.fireAllRules();
        boolean result1 = ...;
        kSession.dispose();
    }
    

    Note I'm not sure whether you are on the right track. Evaluating many boolean expressions isn't necessarily done best with a rule engine.