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-tp4...
Sent from the Drools: User forum mailing list archive at
Nabble.com.