Drools Konstanz

From Training Material
Jump to navigation Jump to search

Drools solutions

Basic

EX1

rule "List Salaries" enabled true
when 
	$sal : Salgrade()
then    
  	System.out.println($sal.grade + "/t" + $sal.losal + "/t" + $sal.hisal)
end

EX2

Suggestion

rule "employees who earn between 1000 and 2000" enabled true
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 );
end

Output

7934 ELISON	CLERK   	7782	1982 1300 10
7876 FORD	CLERK   	7788	1983 1100 20
7521 WALTON	SALESMAN   	7698	1981 1250 30
7844 GATES	SALESMAN   	7698	1981 1500 30
7499 BAROSSO	SALESMAN   	7698	1981 1600 30
7654 CHIRACK	SALESMAN   	7698	1981 1250 30

EX3

rule "3" enabled true
 when
 e : Emp( deptno == 20 && job == "CLERK")
 then
     System.out.println(
       e.id + " " +        e.name + "\t" +        e.job + "   \t" +       e.mgr  + "\t" +       e.hiredate + " " +        e.sal + " " +        e.deptno );
  end

Output

7876 FORD	CLERK   	7788	1983 1100 20
7369 THATCHER	CLERK   	7902	1980 800 20

EX4

Suggestion 1

 rule "Exercise4" enabled true
 when
     $e : Emp(mgr > 0 )
 then    
     System.out.println($e.id + " " + $e.name + " " + $e.job + "\t" + $e.mgr + " " + $e.hiredate + " " + $e.sal + " " + $e.deptno )
 end

Suggestion 2

rule "Select employees who have a boss." enabled true
when 
	e : Emp($bossId : mgr)
	Emp(id == $bossId)
then    
  	System.out.println(e.id + " " + e.name + "\t" + e.job  
    + "   \t" +  e.mgr  + "\t" + e.hiredate + " " + e.sal
     + " " + e.deptno );
end

OUTPUT

7934 ELISON CLERK	7782 1982 1300 10
7876 FORD CLERK	7788 1983 1100 20
7788 CARNEGIE ANALYST	7566 1982 3000 20
7369 THATCHER CLERK	7902 1980 800 20
7902 TOOSK ANALYST	7566 1981 3000 20
7521 WALTON SALESMAN	7698 1981 1250 30
7900 BUFFETT CLERK	7698 1981 950 30
7844 GATES SALESMAN	7698 1981 1500 30
7499 BAROSSO SALESMAN	7698 1981 1600 30
7654 CHIRACK SALESMAN	7698 1981 1250 30
7566 PUTIN MANAGER	7839 1981 2975 20
7782 MERKEL MANAGER	7839 1981 2450 10
7698 BLAIR MANAGER	7839 1981 2850 30

EX5

Suggestion

rule "Select manager’s annual remuneration." enabled true
when 
	e : Emp(job == "MANAGER", $sal : sal)
then    
  	System.out.println(e.id + " " + e.name + "\t" + e.job  
    + "   \t" +  e.mgr  + "\t" + e.hiredate + " " + $sal*12
     + " " + e.deptno );
end

Output

7566 PUTIN	MANAGER   	7839	1981 35700 20
7782 MERKEL	MANAGER   	7839	1981 29400 10
7698 BLAIR	MANAGER   	7839	1981 34200 30

EX6

rule "Exercise 6" enabled false
when
	 $e : Emp( name matches ".LA.*" )
then
    annual = 12 * $e.sal
	System.out.println($e.id + " " + $e.name + " " + $e.job + " " + $e.mgr + " " + $e.hiredate + " " + $e.sal + " " + $e.deptno + " " +annual);
end
7698 BLAIR MANAGER 7839 1981 2850 30 34200

EX7

rule "Exercise 7" enabled false
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 + " " + e.mgr + " " + e.deptno ); 
end

Output

7521 WALTON	SALESMAN   	7698	1981 1250 7698 30
7566 PUTIN	MANAGER   	7839	1981 2975 7839 20

EX8

Suggestion 1

 rule "Sample8" //enabled false
 when 
  e :  Emp((job == 'MANAGER' && deptno != 10) || (job != 'MANAGER' && deptno == 10))
 then    
   System.out.println(e.name + " " + e.deptno  + " " + e.job)
 end

Suggestion 2

rule "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 
	e: Emp((deptno == 10 && job != "MANAGER"))
then    
  	System.out.println(e.id + " " + e.name + "\t" + e.job  
    + "   \t" +  e.mgr  + "\t" + e.hiredate + " " + e.sal
     + " " + e.deptno );
end

Output

7566 PUTIN	MANAGER   	7839	1981 2975 20
7698 BLAIR	MANAGER   	7839	1981 2850 30
7934 ELISON	CLERK   	7782	1982 1300 10
7839 BUSH	PRESIDENT   	0	1981 5000 10

Advanced

EX31

Suggestion 1

  rule "Exercise 31" enabled false
  when 
    $dep : Dept()
    $e : Emp(deptno == $dep.deptno)
  then
    System.out.println($e.name + "\t" + $dep.loc);
  end

Suggestion 2

rule "31. Select the name of the employee and the city (LOC column in DEPT table) in which they work" enabled false
when 
	$e : Emp($dep : deptno)
	Dept(deptno == $dep, $city : loc)
then    
  	System.out.println($e.name + "\t" + $city)
end

EX32

Suggestion 1

rule "32. Select the names of the employees, and the name and number of their department." enabled true
when 
	$e : Emp($dep : deptno)
	$d : Dept(deptno == $dep, $depName : dname)
then    
  	System.out.println($e.name + "\t\t" + $depName + "\t\t" + $dep)
end

Output

ELISON		ACCOUNTING		10
FORD		RESEARCH		20
CARNEGIE		RESEARCH		20
THATCHER		RESEARCH		20
TOOSK		RESEARCH		20
WALTON		SALES		30
BUFFETT		SALES		30
GATES		SALES		30
BAROSSO		SALES		30
CHIRACK		SALES		30
PUTIN		RESEARCH		20
MERKEL		ACCOUNTING		10
BLAIR		SALES		30
BUSH		ACCOUNTING		10

EX33

rule "33"
when
 s : Salgrade()
 e : Emp(e.sal > 2000, e.sal <= s.hisal , e.sal >= s.losal)
then
     System.out.println(
       e.name + "\t" + e.sal+ "\t" + s.grade);
end

Output

ename sal grade
BLAIR 2850 4
MERKEL 2450 4
PUTIN 2975 4
TOOSK 3000 4
CARNEGIE 3000 4
BUSH 5000 5

EX34

rule "34"
when
 d : Dept()
 e : Emp(e.deptno == d.deptno, d.loc == "LONDON")
then
     System.out.println(
       e.name + "\t" + d.loc);
end

Output

ename loc
PUTIN LONDON
TOOSK LONDON
THATCHER LONDON
CARNEGIE LONDON
FORD LONDON

EX35

 rule "Exercise 35" 
 when 
   $e : Emp()
   $d : Dept(loc != 'LONDON' && deptno == $e.deptno)
   $s : Salgrade(losal <= $e.sal && hisal >= $e.sal)
 then
   System.out.println($e.name + "\t" + $d.loc + "\t" + $s.grade);
 end

EX36

Suggestion 1

rule "36. Find departments without employees." enabled false
when 
	$d : Dept($dep : deptno)
	not Emp($dep == deptno)
then    
  	System.out.println($d.dname + "\t" + $dep)
end

Output

OPERATIONS	40

EX37

Suggestion 1

rule "37. Select an employee’s name and his/her boss’s name" enabled true
when 
	$emp : Emp($mgr : mgr)
	$boss : Emp(id == $mgr)
then    
  	System.out.println($boss.name + " is boss of " + $emp.name)
end

Output

BUSH is boss of BLAIR
BUSH is boss of MERKEL
BUSH is boss of PUTIN
BLAIR is boss of CHIRACK
BLAIR is boss of BAROSSO
BLAIR is boss of GATES
BLAIR is boss of BUFFETT
BLAIR is boss of WALTON
PUTIN is boss of TOOSK
TOOSK is boss of THATCHER
PUTIN is boss of CARNEGIE
CARNEGIE is boss of FORD
MERKEL is boss of ELISON

EX38

Suggestion 1

rule "38. Select employees who doesn't have a boss." enabled true
when 
	$emp : Emp($mgr : mgr)
	not Emp(id == $mgr)
then    
  	System.out.println($emp.name)
end

Output

BUSH

EX39

Suggestion 1

rule "39. Show all employees who have no subordinates." enabled true
when
	$emp : Emp($id : id)
	not Emp(mgr == $id)
then    
  	System.out.println($emp.name)
end

Output

CHIRACK
BAROSSO
GATES
BUFFETT
WALTON
THATCHER
FORD
ELISON

EX41

Suggestion 1

rule "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)
end

Output

THATCHER hired in 1980 whose boss is TOOSK hired in 1981

EX44

Suggestion 1

rule "44. Find jobs which are in department 10 but not in department 20." enabled true
when 
	$e : Emp(deptno == 10, $job : job)
	not Emp(deptno == 20, $job == job)
then    
  	System.out.println($job)
end

Output

PRESIDENT

EX23

Suggestion 1

rule "23. Find the minimal, maximal and average salaries of people employed in 1981." enabled true
when 
	accumulate($emp : Emp(hiredate == 1981),
		$min : min($emp.sal),
		$max : max($emp.sal),
		$avg : average($emp.sal)
	)
then    
  	System.out.println("Salary from Employees hired in 1981: avg: " + $avg + " min: " + $min + " max: " + $max)
end

Output

Salary from Employees hired in 1981: avg: 2282.5 min: 950.0 max: 5000.0

EX24

Suggestion 1

rule "24. Find the difference between maximal and minimal salary." enabled true
when 
	accumulate($emp : Emp(),
		$min : min($emp.sal),
		$max : max($emp.sal)
	)
then    
  	System.out.println("Total difference: " + ($max - $min))
end

Output

Total difference: 4200.0

EX26

Suggestion 1

 rule "26. How many managers work for the company?" enabled true
 when
  accumulate ($e :Emp(job == 'MANAGER'), $cnt : count($e.job)) 
 then    
  System.out.println("How many managers work for the company: " + $cnt + "\n");
 end

Suggestion 2

rule "Exercise 26" 
when 
  accumulate (e:Emp(job=='MANAGER'), 
    $count : count(e))
then
  System.out.println("MANAGER:"+($count));
end

Output

Amount of managers: 3

EX25

Suggestion 1

declare SalByJob
   job : String
end

rule "25. Find the average salary for every post." enabled true
when
   	Emp($job: job) and
   	not SalByJob($job == job)
   	accumulate (
   		e :Emp(job == $job),
   		$avg : average(e.sal)
	) 
then    
   System.out.println("Position: " + $job + " average salary: " + $avg)
   insert(new SalByJob($job))
end

EX27

Suggestion 1

declare SalByDep
   id : Integer
end

rule "27. Find the average annual salaries in departments." enabled true
when 
	$dep : Dept($depId : deptno)
	not SalByDep(id == $depId)
	accumulate($emp : Emp(deptno == $depId),
   		$avg : average($emp.sal)
	)
then    
  	System.out.println("Department " + $dep.dname + " has annual average: " + $avg*12)
  	insert(new SalByDep($depId))
end

Output

Department ACCOUNTING has annual average: 35000.0
Department RESEARCH has annual average: 26100.0
Department SALES has annual average: 18800.0
Department OPERATIONS has annual average: 0.0

EX43

Not know why

rule "43+"
when
	e1 : Emp(hiredate == 1982)
	e2 : Emp(hiredate == 1983)
	exists (Emp(e1.job == job, e2.job == job))
then
   System.out.println( e1.job)
end

Suggestion 1

rule "43. Find post filled in 1982 and 1983." enabled true
when 
	Emp($job : job, hiredate == 1982)
	Emp(job == $job, hiredate == 1983)
then    
  	System.out.println("Job: " + $job)
end

Suggestion 2

declare xJob
   name : String
end

rule "Exercise 43" enabled true
when
  $e1:Emp($job:job && hiredate == 1982)
  $e2:Emp(job == $job && hiredate == 1983)
  not(xJob(name == $job))
then
  System.out.println($job)
  insert(new xJob($job));
end

Output

Job: CLERK

EX28

Solution 1

rule "Exercise 28 Find departments with more than 3 workers." enabled true
when
  $d : Dept()
  accumulate(e:Emp(deptno == $d.deptno), $wc : count(e))
  Number(doubleValue > 3) from $wc
then
  System.out.println($d.deptno + ":" + $wc)
end

EX45

Solution 1

rule "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)
end

EX46

Solution 1

rule "Exercise 46 Select employees earning the maximum salaries in their positions (jobs)." enabled false
when
  $e:Emp()
  Number($max : longValue) from accumulate (e:Emp(job==$e.job), max(e.sal))
  Number(doubleValue == $e.sal) from $max
then
  System.out.println($e.name + " " +$e.job + ":" + $e.sal)
end

Solution 2

declare jobPost2
	job: String
	max: Double
end

rule "Exercise 46" 

when 
	Emp(j:job)
	and not jobPost2(j == job)
	Number(max:doubleValue) from accumulate(Emp(s:sal, job==j), max(s)) 
then
	insert(new jobPost2(j, max))
end 

rule "Display"

when
	jp: jobPost2(j: job, m: max)
	e: Emp (e.sal == m, e.job == j)
then
	System.out.println(e.name + " " + e.sal)
end

Solution 3

declare JobToProcess
   job : String
end

rule "46. Select employees earning the maximum salaries in their positions (jobs). - Create jobs" enabled true
when 
	Emp($job : job)
	not JobToProcess(job == $job)
then    
  	System.out.println("Found job: " + $job)
  	insert(new JobToProcess($job))
end

rule "46. Select employees earning the maximum salaries in their positions (jobs). - Select based on declared type" enabled true
when 
	$jobToProcess : JobToProcess($job : job)
	Number($max : longValue) from accumulate($emp : Emp(job == $job),
   		max($emp.sal)
	)
	$empWithMax : Emp(job == $job, sal == $max)
then   
  	System.out.println("Employee: " + $empWithMax.name + " salary: " + $empWithMax.sal + "  position: " + $job + " top: " + $max)
end

EX51

Solution 1

rule "Ex 51 Find employees earning more than the average salary in their department."
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 + "\t" + e.deptno + "\t" + e.sal)
end

EX55

Solution 1

declare AvgSalaryOfDeptno
   avgSalary : double
   deptno : int
end

rule "Exercise 55 Find the maximum average salary of departments. 1" enabled false
when
  $e:Emp()
  accumulate (empOfDept:Emp(deptno == $e.deptno), $avgDep : average(empOfDept.sal))
  not(AvgSalaryOfDeptno(deptno == $e.deptno))
then
  insert(new AvgSalaryOfDeptno($avgDep, $e.deptno));
end

rule "Exercise 55 Find the maximum average salary of departments. 2" enabled false
when
  $avod : AvgSalaryOfDeptno()
  accumulate (depToCheck:AvgSalaryOfDeptno(), $maxAverage : max(depToCheck.avgSalary))
  Number(doubleValue == $avod.avgSalary) from $maxAverage
then
  System.out.println($avod.deptno + ":" + $avod.avgSalary);
end

Solution 2

rule "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)
end

Output

10 Salary: 2916.6666666666665

DSL

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

EX2

[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 $avgSal
package 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
end

EX3

[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
end

ShoppingExample

Solution 1

package rules;
import com.nobleprog.*;
dialect "mvel" 

 
rule "Notify about Purchase"
   no-loop true
when
  p:Purchase()
then
 System.out.println("Purchase of "+p.customer.name+" for "+p.product.name);
end

rule "Apply Discount of 10% if over 1000"
when
  c:Customer()
  accumulate (p:Purchase(), $allPurchases : sum(p.product.price))
  Number(doubleValue > 1000) from $allPurchases
then
  insertLogical(new Discount(c, 0.1*$allPurchases));
  c.discount = 0.1*$allPurchases;
  System.out.println("Create new Discount for "+c.name+" over "+0.1*$allPurchases);
end

rule "Notify when discoutn is awarded"
when
  c:Customer()
  exists(Discount(customer == c))
then
  System.out.println("Customer "+c.name+ " is awarded");
end

rule "Notify when customer has no more discount"
when
  c:Customer()
  not (Discount(customer == c))
then
  System.out.println("Customer "+c.name+ " has no discount");
end

Solution 2

rule "List Purchases" enabled true
when 
	Purchase($customer : customer, $product : product)
then    
  	System.out.println("Customer " + $customer.name + " just purchased " + $product.name)
end

rule "Give Discount" enabled true
when 
	$customer : Customer($customerName : name)
	Number($sum : doubleValue, doubleValue > 1000) from accumulate(
		Purchase(customer == $customer, $product : product),
		sum($product.price)
	)
then    
  	System.out.println("Customer " + $customer.name + " receives discount for buying for a total amount of " + $sum)
  	insert(new Discount($customer, 10))
end

rule "Take discount" enabled true
when 
	$discount : Discount($customer : customer, $customerName : customer.name)
	Number($sum : doubleValue, doubleValue < 1000) from accumulate(
		Purchase(customer == $customer, $product : product),
		sum($product.price)
	)
then    
  	System.out.println("Discount of " + $customer.name + " is not available anymore, because of a total purchase sum of "+ $sum)
  	retract($discount)
end