Drools Hattingen
Jump to navigation
Jump to search
Drools solutions
Basic
EX1
rule "Select Salgrade" enabled false
when
$s : Salgrade()
then
System.out.println( $s.grade + " " + $s.losal + " " + $s.hisal)
endEX2
rule "e2" enabled false
when
$e : Emp(sal > 1000 && < 2000)
then
System.out.println(
$e.id + " " +
$e.name + "\t" +
$e.job + " \t" +
$e.mgr + "\t" +
$e.hiredate + " " +
$e.sal + " " +
$e.deptno )
endEX3
rule "example 3"
when
$e : Emp(job == "CLERK" && deptno == 20)
then
System.out.println($e.id + "\t" + $e.name + "\t" + $e.job + "\t" + $e.mgr + "\t" + $e.hiredate + "\t" + $e.sal + "\t" + $e.deptno)
endEX4
rule "Excercise 04"
when
$e: Emp(job != "PRESIDENT")
then
System.out.println($e.id + " " + $e.name + " " + $e.job + " " + $e.mgr + " " + $e.hiredate + " " + $e.sal + " " + $e.deptno)
endEX5
rule "5a" enabled true
when
$e : Emp(job == "MANAGER" && $y: (sal*12))
then
System.out.println($e.name + " " + $y)
end
rule "5b" enabled false
when
$e : Emp(job == "MANAGER")
then
System.out.println($e.name + " " + ($e.sal *12))
endEX6
rule "Find employees with second letter “L” and third “A”." enabled true
when
$e : Emp(name matches ".LA.*")
then
System.out.println($e.name)
endEX7
rule "Select ends with N and contains T"
when
e : Emp(name matches ".*T.*N")
then
System.out.println(
e.id + " " +
e.name + "\t" +
e.job + " \t" +
e.mgr + "\t" +
e.hiredate + " " +
e.sal * 12 + " " +
e.deptno );
endEX8
rule "e8"
when
$e : Emp(job == "MANAGER" && deptno != 10) or
$e : Emp(job != "MANAGER" && deptno == 10)
then
System.out.println(
$e.id + " " +
$e.name + "\t" +
$e.job + " \t" +
$e.mgr + "\t" +
$e.hiredate + " " +
$e.sal + " " +
$e.deptno )
endrule "Find employees who either work as managers or work in department no 10, but not both." enabled true
when
$e : (Emp(job == "MANAGER" , deptno != 10 ) or Emp(job != "MANAGER" , deptno == 10 ))
then
System.out.println($e.name + " " + $e.job + " " + $e.deptno)
endAdvanced
EX31
rule "Select the name of the employee and the city (LOC column in DEPT table) in which they work. " enabled false
when
$d : Dept()
$e : Emp($d.deptno == deptno)
then
System.out.println($e.name + "\t" + $d.loc)
endEX32
rule "Excercise 32"
when
$e: Emp()
$d: Dept($e.deptno == deptno)
then
System.out.println($e.name + " " + $d.dname + " " + $d.deptno)
endEX33
rule "33" enabled false
when
$e : Emp($e.sal > 2000)
$s : Salgrade($e.sal >= losal && $e.sal <= hisal)
then
System.out.println($e.name + " " + $e.sal +" " + $s.grade)
endEX34
rule "34: Select employees working in London. " enabled true
when
$e : Emp()
$d : Dept(deptno==$e.deptno , loc=="LONDON")
then
System.out.println($e.name+" "+$d.loc)
endEX35
rule "E35"
when
s :Salgrade()
d :Dept(loc != 'LONDON')
e :Emp(d.deptno == deptno && sal >= s.losal && sal <= s.hisal)
then
System.out.println(e.name + "\t" + d.loc + "\t" + s.grade)
endEX36
rule "e36" enabled false
when
d :Dept()
not (Emp(deptno == d.deptno))
then
System.out.println( d.dname )
endEX37
rule "Select an employee’s name and his/her boss’s name " enabled false
when
$e : Emp()
$m : Emp(id == $e.mgr)
then
System.out.println($e.name + " boss is " + $m.name)
endEX38
rule "Excercise 38"
when
$e: Emp()
not Emp($e.mgr == id)
then
System.out.println("E38 " + $e.name)
endEX39
rule "39" enabled false
when
$e : Emp()
not ( Emp($e.id == mgr))
then
System.out.println($e.name )
endEX41
rule "Select employees hired earlier than their bosses." enabled true
when
$e : Emp()
$eb: Emp($e.mgr == id , $e.hiredate < $eb.hiredate)
then
System.out.println($e.name + " was hired in " + $e.hiredate + ", her boss "+$eb.name+" who was hired in "+$eb.hiredate)
endrule "41. Select employees hired earlier than their bosses." enabled true
when
$emp : Emp($mgr : mgr, $empHireDate : hiredate)
$boss : Emp(id == $mgr, $empHireDate < hiredate)
then
System.out.println($emp.name + " hired in " + $empHireDate + " whose boss is " + $boss.name + " hired in " + $boss.hiredate)
endEX44
rule "***Exercise" enabled true
when
$e : Emp(deptno==10)
not (Emp(deptno==20 , job==$e.job))
then
System.out.println($e.job)
endEX23
rule "Find the minimal, maximal and average salaries of people employed in 1981. "
when
accumulate (e :Emp(hiredate == 1981),
$avg : average(e.sal),
$min : min(e.sal),
$max : max(e.sal)
)
then
System.out.println(
"Average salary: " + $avg + "\n" +
"Min salary: " + $min + "\n" +
"Max salary: " + $max + "\n"
)
endEX24
rule "e24" enabled false
when
accumulate (e :Emp(),
$min : min(e.sal),
$max : max(e.sal)
)
then
System.out.println(
"Salary range: " + ($max - $min)
)
endEX26
rule "How many managers work for the company? "
when
accumulate (
$e : Emp(job == "MANAGER"),
$count: count($e.job)
)
then
System.out.println(
"Managers: " + $count + "\n"
)
endEX25
// Excercise 25
declare SalByJob
job : String
end
rule "Excercise 25"
when
$e: Emp(j: job) and
not SalByJob(job == $e.job)
accumulate (e :Emp(job == j), $avg : average(e.sal) )
then
System.out.println("E25 " + $e.job + " " + $avg)
insert(new SalByJob(j))
endEX27
declare DeptNo
no : int
end
rule "27" enabled true
when
Emp(d:deptno) and not DeptNo(no == d)
accumulate (e :Emp(deptno == d), $avgSal : average(e.sal))
then
System.out.println( "Avg salary for deept " + d + " is " + ($avgSal*12) )
insert(new DeptNo(d))
endEX43
declare Jobs
name: String
end
rule "43. *Exercise Find post filled in 1982 and 1983." enabled true
when
e: Emp(hiredate==1982)
e2: Emp(hiredate==1983)
ee: Emp(job==e.job , job==e2.job)
not Jobs(name==ee.job)
then
System.out.println(ee.job)
insert(new Jobs(ee.job))
endrule "43+"
when
e1 : Emp(hiredate == 1982)
e2 : Emp(hiredate == 1983)
exists (Emp(e1.job == job, e2.job == job))
then
System.out.println( e1.job)
endEX28
declare Depts
dept : Integer
end
rule "Find departments with more than 3 workers."
when
Emp(d: deptno) and not Depts(d == dept)
accumulate (e :Emp(deptno == d),
$c : count(e)
)
Number(doubleValue > 3) from $c
then
System.out.println("deptno: " + d + " count: " + $c)
insert(new Depts(d))
endEX45
rule "45. Exercise Find employees earning more than the manager’s (job=='MANAGER') average." enabled true
when
Number(avg : longValue) from accumulate (Emp(job=="MANAGER" , s: sal),average(s))
e: Emp(sal > avg)
then
System.out.println(e.name+' earns '+e.sal)
endrule "Exercise 45 Find employees earning more than the manager’s (job=='MANAGER') average." enabled false
when
Number($avgNumber : longValue) from accumulate (e:Emp(job=='MANAGER'), average(e.sal))
$e:Emp(sal > $avgNumber)
then
System.out.println($e.name + ":" + $e.sal)
endEX46
declare RichJobs
job: String
name: String
end
//Example 46
rule "Select employees earning the maximum salaries in their positions (jobs). "
when
Emp($job: job, $name: name, $sal: sal) and not RichJobs($job == job, $name == name)
accumulate (
$e: Emp(job == $job),
$max: max($e.sal)
)
Number($sal == $max) from $max
then
System.out.println(
$name + " | " + $job + " | " + $max + "\n"
)
insert(new RichJobs($job, $name))
endrule "46. Exercise* Select employees earning the maximum salaries in their positions. " enabled true
when
Emp($job:job,$name:name)
Number($max : longValue) from accumulate (Emp(job==$job, $s: sal),max($s))
$e : Emp(sal==$max, name==$name)
then
System.out.println($e.name+' as '+$e.job+' earns '+$e.sal)
endEX51
rule "e51" enabled false
when
Dept(dn :deptno)
Number($avg : longValue) from accumulate (Emp(s: sal,deptno == dn ), average(s))
e : Emp(deptno == dn,sal > $avg)
then
System.out.println(e.name + " " + e.deptno +" " + e.sal )
endEX55
declare AvgDep
deptno: int
avg: long
end
rule "55.a *Exercise Find the maximum average salary of departments. " enabled true
when
$dept : Dept($deptno:deptno,$dname:dname)
Number($avg : longValue) from accumulate (Emp(deptno==$deptno, $s: sal),average($s))
then
insert(new AvgDep($deptno,$avg))
end
rule "55.b " enabled true
when
Number($max : longValue) from accumulate (AvgDep($avg: avg),max($avg))
AvgDep(avg==$max,$deptno:deptno)
$d: Dept(deptno==$deptno)
then
System.out.println($d.dname+' '+$d.deptno+' '+ $max)
endrule "55. Find the maximum average salary of departments." enabled true
when
Number($max : doubleValue) from accumulate(
$dep : Dept($depId : deptno)
and
Number($avg : doubleValue)
from accumulate($emp : Emp(deptno == $depId),
average($emp.sal)
),
max($avg)
)
d:Dept()
Number($avgOfDept : doubleValue) from accumulate(e:Emp(deptno == d.deptno), average(e.sal))
Number(doubleValue == $max) from $avgOfDept
then
System.out.println(d.deptno + " Salary: " + $max)
endDSL
EX1
[condition][]There are employees earning more than {salary}=e:Emp(sal > {salary})
[*][]Show name and salary=System.out.println("Name: " + e.name + " Salary: " + e.sal)package rules1
import com.nobleprog.FactModel.*;
import java.lang.Math
dialect "mvel"
expander Exercise01.dsl
rule "Rule 1"
when
There are employees earning more than 2000
then
Show name and salary
end[condition][]There are employees=e : Emp()
[condition][]- earning more than {salary}=sal > {salary}
[consequence][]Show name and salary=System.out.println(e.name + "\t" + e.sal)package rules1
import com.nobleprog.FactModel.*;
import java.lang.Math
dialect "mvel"
expander Exercise01.dsl
rule "Rule 1"
when
There are employees
- earning more than 2000
then
Show name and salary
endEX2
[condition][]There is a department which:=d:Dept()
[consequence][]Show department name=System.out.println(d.dname)
[condition][]has at least {c} employees working in it=accumulate(e:Emp(deptno == d.deptno), $countOfEmployees : count(e)) && Number(intValue >= {c}) from $countOfEmployees
[condition][]average salary is greater than {sal}=accumulate(e2:Emp(deptno == d.deptno), $avgSal: average(e2.sal)) && Number(doubleValue > {sal}) from $avgSalpackage rules2
import com.nobleprog.FactModel.*;
import java.lang.Math
dialect "mvel"
expander Exercise02.dsl
rule "Rule 2"
when
There is a department which:
has at least 3 employees working in it
average salary is greater than 2000
then
Show department name
endEX3
[condition][]There are departments where:=d : Dept()
[condition][]there are analysts working in=exists Emp(job == 'ANALYST', deptno == d.deptno)
[consequence][]Show department name=System.out.println(d.dname)package rules3
import com.nobleprog.FactModel.*;
import java.lang.Math
dialect "mvel"
expander Exercise03.dsl
rule "Rule 3"
when
// Make sure that the rule will work for both cases
There are departments where:
// There is a department where:
there are analysts working in
//also there is an anlyst working in it
then
Show department name
endinsertLogical
Ex5.2
rules
declare Department10
emp: Emp
end
declare AccessToSecretFiles
emp: Emp
end
rule "Is in department 10"
when
$e: Emp(deptno == 10)
then
insertLogical(new Department10($e))
end
rule "Gets access to X Files"
when
Department10($e: emp)
then
insertLogical(new AccessToSecretFiles($e))
endjUnit
Emp $blair = new Emp(7698, "BLAIR", "MANAGER", 7839, 1981, 2850, 10);
FactHandle $blairFH = ksession.insert($blair);
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger((KnowledgeRuntimeEventManager) ksession, "/tmp/logicalinsert_exercise");
ksession.fireAllRules();
$blair.setDeptno(30);
ksession.update($blairFH, $blair);
ksession.fireAllRules();Shopping Example 1
JUNIT
Customer customer = new Customer("heinz", 0);
kSession.insert(customer);
Product product1 = new Product("tomaten", 600);
kSession.insert(product1);
Product product2 = new Product("äpfel", 600);
kSession.insert(product2);
Purchase purchase1 = new Purchase(customer, product1);
kSession.insert(purchase1);
Purchase purchase2 = new Purchase(customer, product2);
FactHandle handle = kSession.insert(purchase2);
kSession.fireAllRules();
kSession.delete(handle);
kSession.fireAllRules();RULES
package com.sample
import com.sample.DroolsTest.*;
rule "Notify about Purchase"
when
p : Purchase()
then
System.out.println( "New purchase " + p.getCustomer().getName() + " " + p.getProduct().getName() + " " + p.getProduct().getPrice() );
end
rule "Set Discount"
when
$customer : Customer()
Number($sum : longValue > 1000) from accumulate (Purchase(customer == $customer, $price: product.price),sum($price))
then
System.out.println( "Total purchase is " + $sum + ", add discount" );
insertLogical(new Discount($customer, 10));
end
rule "Notify Discount"
when
d : Discount()
then
System.out.println( "Discount applied to " + d.getCustomer().getName() + " of " + d.getAmount() );
end
rule "Notify Discount removed"
when
not (Discount())
then
System.out.println( "Discount removed" );
endShopping Example 2
JUNIT
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession-rules");
// go !
Customer customer = new Customer("Christian", 99);
kSession.insert(customer);
Product prod1 = new Product("Product 1", 600);
kSession.insert(prod1);
Product prod2 = new Product("Product 2", 600);
kSession.insert(prod2);
Purchase purch1 = new Purchase(customer, prod1);
kSession.insert(purch1);
Purchase purch2 = new Purchase(customer, prod2);
FactHandle handle =kSession.insert(purch2);
kSession.fireAllRules();
kSession.delete(handle);
kSession.fireAllRules();RULES
rule "Notify"
no-loop true
when
c: Customer()
p: Purchase(customer==c)
then
System.out.println(c.name+ " purchased " +p.product.name );
end
rule "2"
when
c: Customer()
accumulate (
u: Purchase(customer == c),
$sum: sum(u.product.price)
)
Number(intValue > 1000) from $sum
then
c.setDiscount(10);
insertLogical(new Discount(c, 10));
System.out.println( "Discount 10 for customer "+c.name );
end
rule "3"
when
c: Customer() and
not Discount()
then
c.setDiscount(0);
System.out.println( "Discount 10 removed for customer "+c.name );
endCEP
rules
package chapter06.cep;
import org.drools.devguide.eshop.events.TransactionEvent;
declare SuspiciousCustomerEvent
@role(event)
customerId: Long
reason: String
end
declare AlarmTriggered
customerId: Long
end
rule "More than 10 transactions in an hour from one client"
when
$t1: TransactionEvent($cId: customerId)
Number(intValue >= 10) from accumulate(
$t2: TransactionEvent(
this != $t1,
customerId == $cId,
this meets[1h] $t1
),
count($t2)
)
not (SuspiciousCustomerEvent(customerId == $cId, reason == "Many transactions"))
then
insert(new SuspiciousCustomerEvent($cId, "Many transactions"));
end
rule "More than 1 transaction of 200 dollars in an hour from the same client"
when
$t1: TransactionEvent($cId: customerId, totalAmount >= 200.0)
$t2: TransactionEvent(
this != $t1,
this meets[1h] $t1,
customerId == $cId,
totalAmount >= 200.0
)
not (SuspiciousCustomerEvent(customerId == $cId, reason == "Two large transactions"))
then
insert(new SuspiciousCustomerEvent($cId, "Two large transactions"));
end
rule "More than 3 suspicious cases in the day and we warn the owner"
when
SuspiciousCustomerEvent($cId: customerId)
not (AlarmTriggered(customerId == $cId))
Number(intValue >= 2) from accumulate(
$s: SuspiciousCustomerEvent(customerId == $cId),
count($s)
)
then
//warn the owner
System.out.println("WARNING: Suspicious fraud case. Client " + $cId);
insert(new AlarmTriggered($cId));
end
rule "More than 10 transactions in an hour from small client portal"
when
$t1: TransactionEvent($cId: customerId) from entry-point "small-client-portal"
Number(intValue >= 10) from accumulate(
$t2: TransactionEvent(
this != $t1,
customerId == $cId,
this meets[1h] $t1
) from entry-point "small-client-portal",
count($t2)
)
not (SuspiciousCustomerEvent(customerId == $cId, reason == "Many transactions"))
then
insert(new SuspiciousCustomerEvent($cId, "Many transactions"));
end
rule "More than 100 transactions in an hour from big client portal"
when
$t1: TransactionEvent($cId: customerId) from entry-point "big-client-portal"
Number(intValue >= 100) from accumulate(
$t2: TransactionEvent(
this != $t1,
customerId == $cId,
this meets[1h] $t1
) from entry-point "big-client-portal",
count($t2)
)
not (SuspiciousCustomerEvent(customerId == $cId, reason == "Many transactions"))
then
insert(new SuspiciousCustomerEvent($cId, "Many transactions"));
endjUnit
package org.drools.devguide;
import org.drools.devguide.eshop.events.TransactionEvent;
import org.junit.Test;
import org.kie.api.runtime.KieSession;
public class CEPRulesTest extends BaseTest {
@Test
public void testCEPRules() {
KieSession ksession = createSession("cepKsession");
Long customerId = 1L;
ksession.insert(new TransactionEvent(customerId, 10.00));
ksession.insert(new TransactionEvent(customerId, 12.00));
ksession.insert(new TransactionEvent(customerId, 14.00));
ksession.insert(new TransactionEvent(customerId, 10.50));
ksession.insert(new TransactionEvent(customerId, 10.99));
ksession.insert(new TransactionEvent(customerId, 9.00));
ksession.insert(new TransactionEvent(customerId, 11.00));
ksession.insert(new TransactionEvent(customerId, 15.00));
ksession.insert(new TransactionEvent(customerId, 18.00));
ksession.insert(new TransactionEvent(customerId, 201.00));
long ruleFireCount = ksession.fireAllRules();
System.out.println(ruleFireCount);
ksession.insert(new TransactionEvent(customerId, 202.00));
ruleFireCount = ksession.fireAllRules();
System.out.println(ruleFireCount);
}
}fact model
package org.drools.devguide.eshop.events;
import java.io.Serializable;
import java.util.Date;
import org.kie.api.definition.type.Expires;
import org.kie.api.definition.type.Role;
import org.kie.api.definition.type.Timestamp;
@Role(Role.Type.EVENT)
@Timestamp("executionTime")
@Expires("2h30m")
public class TransactionEvent implements Serializable {
private static final long serialVersionUID = 1L;
private Date executionTime;
private Long customerId;
private Double totalAmount;
public TransactionEvent() {
super();
}
public TransactionEvent(Long customerId, Double totalAmount) {
super();
this.executionTime = new Date();
this.customerId = customerId;
this.totalAmount = totalAmount;
}
public Date getExecutionTime() {
return executionTime;
}
public void setExecutionTime(Date executionTime) {
this.executionTime = executionTime;
}
public Long getCustomerId() {
return customerId;
}
public void setCustomerId(Long customerId) {
this.customerId = customerId;
}
public Double getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(Double totalAmount) {
this.totalAmount = totalAmount;
}
}