Drools – Working with Accumulate


This example follows on from Drools5.6 Basic Example

This is a quick example that shows a very simple use of the accumulate statement.

Problem

Write a rule that accumulates and stores the number of iPhone and Android devices owned by students, so that further rules can analyse and act on that information.

The Code

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.skills421.examples.drools</groupId>
<artifactId>DroolsExamples</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<drools-version>5.6.0.Final</drools-version>
</properties>
<dependencies>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>knowledge-api</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>${drools-version}</version>
</dependency>

<!-- JUnit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>

</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

RuleRunner.java

package com.skills421.examples.drools.controller;

import java.util.Collection;

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.definition.KnowledgePackage;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;

public class RuleRunner
{
public RuleRunner()
{
}

public void runRules(String[] rules, Object[] facts)
{

KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();

for (int i = 0; i < rules.length; i++)
{
String ruleFile = rules[i];
System.out.println("Loading file: " + ruleFile);
kbuilder.add(ResourceFactory.newClassPathResource(ruleFile, RuleRunner.class), ResourceType.DRL);
}

Collection<KnowledgePackage> pkgs = kbuilder.getKnowledgePackages();
kbase.addKnowledgePackages(pkgs);
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

for (int i = 0; i < facts.length; i++)
{
Object fact = facts[i];
System.out.println("Inserting fact: " + fact);
ksession.insert(fact);
}

ksession.fireAllRules();
}
}

SimpleFact

package com.skills421.examples.drools.helper;

public class SimpleFact
{
private String name;
private Object value;

public SimpleFact(String name, Object value)
{
super();
this.name = name;
this.value = value;
}

public String getName()
{
return name;
}

public void setName(String name)
{
this.name = name;
}

public Object getValue()
{
return value;
}

public void setValue(Object value)
{
this.value = value;
}

public int intValue()
{
if(value instanceof Number)
{
return ((Number) value).intValue();
}

return -1;
}

@Override
public String toString()
{
return String.format("SimpleFact [name=%s, value=%s]", name, value);
}

}

AccumulateTest.java (JUnit)

package com.examples.drools.examples;

import static org.junit.Assert.*;

import java.util.Arrays;
import java.util.List;

import org.junit.Test;

import com.skills421.examples.drools.controller.RuleRunner;
import com.skills421.examples.drools.model.Student;

public class AccumulateTest
{

@Test
public void test()
{
Student[] students = new Student[]
{
new Student("Jon Doe", 1, 0),
new Student("Jane Doe", 0, 1),
new Student("Mark Smith", 2, 0),
new Student("Alice Jenkins", 1, 2)
};

RuleRunner runner = new RuleRunner();

String[] rules = new String[] { "examples/accumulate.drl" };

runner.runRules(rules, students);
}

}

accumulate.drl

package examples;

import com.skills421.examples.drools.model.Student;
import com.skills421.examples.drools.helper.SimpleFact;

dialect "mvel"

//
// ---------------------------------------------------------------------------------------------------
//

rule "Print all iPhone Students"
when
$student:Student(iPhone>0)
then
System.out.println($student);
end

//
// ---------------------------------------------------------------------------------------------------
//

rule "generate list of androids and iphones owned by students"
when
$iPhones : Number ( ) from accumulate ( Student ( $iPhone : iPhone ), sum ( $iPhone ) )
$androids : Number ( ) from accumulate ( Student ( $android : android ), sum ( $android ) )
then
System.out.println("iPhones: "+$iPhones);
System.out.println("Androids: "+$androids);

insert(new SimpleFact("iPhones",$iPhones));
insert(new SimpleFact("androids",$androids));
end

//
// ---------------------------------------------------------------------------------------------------
//

rule "more iPhones"
when
SimpleFact(name=="iPhones",$iPhones:intValue)
SimpleFact(name=="androids",$androids:intValue < $iPhones)
then
System.out.println("more iPhones - "+$iPhones+" : "+$androids);
end

//
// ---------------------------------------------------------------------------------------------------
//

rule "more androids"
when
SimpleFact(name=="iPhones",$iPhones:intValue)
SimpleFact(name=="androids",$androids:intValue > $iPhones)
then
System.out.println("more androids - "+$androids+" : "+$iPhones);
end

Output

Loading file: examples/accumulate.drl
Inserting fact: Student [name=Jon Doe, iPhone=1, android=0]
Inserting fact: Student [name=Jane Doe, iPhone=0, android=1]
Inserting fact: Student [name=Mark Smith, iPhone=2, android=0]
Inserting fact: Student [name=Alice Jenkins, iPhone=1, android=2]
Student [name=Alice Jenkins, iPhone=1, android=2]
Student [name=Mark Smith, iPhone=2, android=0]
Student [name=Jon Doe, iPhone=1, android=0]
iPhones: 4.0
Androids: 3.0
more iPhones - 4 : 3
Advertisement

One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s