I believe we can inject in Refraction capabilities into Drools Rule Engine using a simple Agenda Filter. I have tested this with test cases against JRules and Drools and get similar results. Without the Refraction Agenda Filter it loops infinitely as expected.
Please try it out and tell me what you think. I believe refraction is a much needed feature of a forward chaining rule engine for commercial purposes. Any feedback is deeply appreciated. Here is what the code looks like ---------Agenda Filter--------------------------- package test; import java.util.ArrayList; import java.util.List; import org.drools.runtime.rule.Activation; import org.drools.runtime.rule.AgendaFilter; /** * This custom agenda filter injects refraction behavior into the rule engine * @author Mukundan Agaram * */ public class RefractionAgendaFilter implements AgendaFilter { private List encounteredActivations = new ArrayList(); @Override public boolean accept(Activation act) { //Check for a Refraction if (encounteredActivations.contains(act)) { //Remove from encountered activations for future firing encounteredActivations.remove(act); //return false so the rule is not selected as part of the refraction return false; } //Otherwise add the rule to check for potential refractions in the future encounteredActivations.add(act); //select the rule to be part of the agenda return true; } } -----------------DRL------------------------ //created on: Jan 15, 2013 package test dialect "mvel" rule testFooBar1 salience 100 when $foo : Foo() $bar : Bar(y > 0) then $foo.setX(($foo.getX() + $bar.getY())); System.out.println("Fired "+drools.getRule().getName()) update($foo); end rule testFooBar2 salience 150 when $foo : Foo(x >= 6) then System.out.println("Fired "+drools.getRule().getName()) end rule testFooBar3 salience 50 when $foo : Foo(x >= 7) then System.out.println("Fired "+drools.getRule().getName()) end ----------------Runtime execution code-------------------------- package test; import org.drools.KnowledgeBase; import org.drools.KnowledgeBaseFactory; 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; public class TestFooBarMain { private static void test() { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); kbuilder.add( ResourceFactory.newClassPathResource( "TestFooBar.drl", TestFooBarMain.class ), ResourceType.DRL ); if ( kbuilder.hasErrors() ) { System.out.println( kbuilder.getErrors().toString() ); } else { System.out.println("DRL parsing - success!"); } KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() ); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); Foo foo1 = new Foo(); foo1.setX(6); Bar bar1 = new Bar(); bar1.setY(3); ksession.insert(foo1); ksession.insert(bar1); ksession.fireAllRules(new RefractionAgendaFilter()); } /** * @param args */ public static void main(String[] args) { test(); } } ----------------Facts------------------------- package test; public class Foo { private int x; private int y; public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } } package test; public class Bar { public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } private int x; private int y; } Thanks, Mukundan Agaram -- View this message in context: http://drools.46999.n3.nabble.com/Implementing-Refraction-with-Drools-tp4021705.html Sent from the Drools: User forum mailing list archive at Nabble.com. _______________________________________________ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users