Drools Waterford

From Training Material
Jump to navigation Jump to search

Basic

EX1

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

EX2

rule "Exercise 2" enabled true
when 
 $e : Emp(sal >= 1000, sal <= 2000) 

then   
  	System.out.println($e.id + "\t" + $e.name + "\t" + $e.job + "\t" + $e.mgr + "\t" + $e.hiredate + "\t" + $e.sal + "\t" + $e.deptno  )
end

EX3

rule "Exercise 3" enabled false
when 
 	$e : Emp(deptno == 20, job == "CLERK") 
then    
	System.out.println($e.name + " " + $e.job + " " + $e.mgr + " " + $e.hiredate + " " + $e.sal + " " + $e.deptno) 
end

EX4

rule "Exercise 4"
when 
 	$e : Emp(id: mgr != "") 
then    
	System.out.println($e.id + " " + $e.name + " " + $e.job + " " + $e.mgr + " " + $e.hiredate + " " + $e.sal + " " + $e.deptno) 
end
rule "Exercise 4 - Select employees who have a boss."
//enabled false
when 
 //$v : Emp(mgr > 0)
 // try rather where mgr id not an employee id
 
 $a : Emp()
 $b : Emp(mgr == $a.id) // only emps with mgrs listed (exists an emp whose id is their mgr id)
  
then    
  // requires an overload toString() in Emp
  System.out.println($b.toString() + "\tmgrNm=" + $a.name )
end

EX5

rule "Exercise 5" enabled false
when 
 	$e : Emp(id: job == "MANAGER") 
then    
	System.out.println($e.id + " " + $e.name + " " + $e.job + " " + $e.mgr + " " + $e.hiredate + " " + $e.sal*12 + " " + $e.deptno) 
end

EX6

rule "Exercise 6"
when 
 $e : Emp(name matches ".L.*" && matches "..A.*")
then    
 System.out.println($e.name);
end
rule "Exercise 6, 2nd=L, 3rd=A"
enabled false
when 
 $v : Emp(name matches ".LA.*")
then    
  System.out.println($v.toString() )
end

EX7

rule "Exercise 7 employees whose name ends with N and contains T." enabled false
when 
 $e : Emp( name matches ".*T.*N" )
then    
  System.out.println($e.id + " " + $e.name + " " + $e.job + " " + $e.mgr + " " + $e.hiredate + " " + $e.sal * 12 + " " + $e.deptno)
end

EX8

rule "Exercise 8 employees who either work as managers or work in department no 10, but not both." enabled true
when 
 $e : Emp ((job == "MANAGER" || deptno == 10) && !(job == "MANAGER" && deptno == 10) )

then    
  System.out.println($e.id + " " + $e.name + " " + $e.job + " " + $e.mgr + " " + $e.hiredate + " " + $e.sal + " " + $e.deptno)
end


rule "Exercise 8"
when 
 $e : Emp( (job == "MANAGER" && deptno != 10) || (deptno == 10 && job != "MANAGER"))
 //fall manager not in dept 10 and all non managers in dept 10
then  
  System.out.println($e.name + " " + $e.job + " " + $e.deptno);
end

Advanced

EX31

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

EX32

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

EX33

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

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

EX34

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

EX35

rule "Exercise 35"
when 
 $s :Salgrade()
 $e :Emp(sal >= $s.losal && <= $s.hisal)
 $d :Dept($d.loc!= "LONDON" && $d.deptno == $e.deptno)
then  
  System.out.println($e.name + " " + $d.loc + " " + $s.grade);
end
rule "Exercise 36 mvel lhs advanced, emp and salgrade when not london :) "
//enabled false
when 
 $d : Dept(loc != "LONDON")
 $e : Emp(deptno == $d.deptno)
 $s : Salgrade(losal <= $e.sal, hisal >= $e.sal)
then    
  System.out.println($e.name +"\t-\t"+ $d.loc +"\t-\t"+ $s.grade)
end

EX36

rule "Exercise 36" 
when
   d :Dept()
   not (Emp(deptno == d.deptno))
then    
  System.out.println( d.dname )
end

EX37

rule "Exercise 37" 	
when
   e :Emp()
   m :Emp(m.id == e.mgr)
then    
  System.out.println( e.name + " boss is " + m.name )
end

EX38

rule "Exercise 38" 	
when
   e :Emp()
   not (Emp(id == e.mgr))
then    
  System.out.println( e.name )
end

EX39

rule "Exercise 39" 	
when
   e :Emp()
   not (Emp(mgr == e.id))
then    
  System.out.println( e.name )
end

EX41

rule "Exercise 41" 	
when
   e :Emp()
   m :Emp(m.id == e.mgr && e.hiredate < m.hiredate)
then    
  System.out.println( e.name + " was hired in " + e.hiredate + ", her boss " + m.name + " who was hired in " + m.hiredate)
end

EX44

rule "Exercise 44" 	
when
   	e :Emp(deptno == 10)
   	not (Emp(job == e.job && deptno == 20))
then    
  System.out.println(e.job)
end

EX23

rule "Exercise 23" enabled false
//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"
  )
end

EX24

rule "Exercise 24" enabled false
//Find the difference between maximal and minimal salary. 
when
  accumulate (e :Emp(), 
  	$min : min(e.sal),
  	$max : max(e.sal)
  	) 	
then
	System.out.println("Salary range: " + ($max - $min))
end

EX26

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

EX25

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

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

EX43

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

// Find post filled in 1982 and 1983
declare jobInYear
	job: String
end

rule "Excercise 43" enabled true
when
	Emp($j: job && hiredate in ('1982', '1983')) and not jobInYear(job == $j);
then
	System.out.println(	  $j )
	insert(new jobInYear($j))
end


declare Job
   job : String
end

rule "Exercise 43" 	enabled false
when
   e: Emp(j: job && hiredate == 1982) and
   exists  (Emp(job == e.job && hiredate == 1983)) and
   not Job(j == job)
then    
   System.out.println(e.job)
   insert(new Job(j))
end

EX28

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

EX45

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

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

EX51

EX55

insertLogical

package _30_mvel
import com.nobleprog.FactModel.*
dialect "mvel" 

declare AccessToSecretFile
    emp : Emp
end

rule "Grant access to employees of Dept. 10"
when 
    e : Emp( deptno == 10 )
then    
    insertLogical( new AccessToSecretFile(e) )
end

Shopping Example

Fact Model

package com.nobleprog;

public class FactModel{
	
	   public static class Customer {
		   private String name;
		   private int    discount;

	        public Customer(String name,
	                        int discount) {
	            this.name = name;
	            this.discount = discount;
	        }

	        public String getName() {
	            return name;
	        }

	        public int getDiscount() {
	            return discount;
	        }

	        public void setDiscount(int discount) {
	            this.discount = discount;
	        }

	    }

	    public static class Discount {
	        private Customer customer;
	        private int      amount;

	        public Discount(Customer customer,
	                        int amount) {
	            this.customer = customer;
	            this.amount = amount;
	        }

	        public Customer getCustomer() {
	            return customer;
	        }

	        public int getAmount() {
	            return amount;
	        }

	    }

	    public static class Product {
	        private String name;
	        private float  price;

	        public Product(String name,
	                       float price) {
	            this.name = name;
	            this.price = price;
	        }

	        public String getName() {
	            return name;
	        }

	        public float getPrice() {
	            return price;
	        }

	    }

	    public static class Purchase {
	        private Customer customer;
	        private Product  product;

	        public Purchase(Customer customer,
	                        Product product) {
	            this.customer = customer;
	            this.product = product;
	        }

	        public Customer getCustomer() {
	            return customer;
	        }

	        public Product getProduct() {
	            return product;
	        }
	    }

}

rules

package _30_mvel
import com.nobleprog.FactModel.*
import java.lang.Math
import java.util.ArrayList
dialect "mvel" 

rule "Purchase notification"
    //salience 10

    when
        $c : Customer()
        $p : Purchase( customer == $c )
    then
        System.out.println( "Customer " + $c.name + " just purchased " + $p.product.name );
end
 
rule "Discount removed notification"
    when
        $c : Customer()
        not Discount( customer == $c )
    then
        $c.discount = 0;
        System.out.println( "Customer " + $c.name + " now has a discount of " + $c.discount );
end

rule "Discount awarded notification"
    when
        $c : Customer()
        $d : Discount( customer == $c )
    then
        System.out.println( "Customer " + $c.name + " now has a discount of " + $d.amount );
end

rule "Apply 10% discount if total purchases is over 100"
    no-loop true
    dialect "java"
    when
        $c : Customer()
        $i : Double(doubleValue > 100) from accumulate (
                Purchase( customer == $c, $price : product.price ),
                sum( $price )
        )
    then
        $c.setDiscount( 10 );
		insertLogical( new Discount( $c, 10 ) );
        System.out.println( "Customer " + $c.getName() + " now has a shopping total of " + $i );
end

jUnit

package com.nobleprog;

import com.nobleprog.*;
import org.junit.Test;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.FactHandle;

import com.nobleprog.FactModel.*;

public class Test01 {
	@Test
	public void test1() {
		KieServices ks = KieServices.Factory.get();
		KieContainer kContainer = ks.getKieClasspathContainer();
		KieSession ksession = kContainer.newKieSession("ksession-rules");
        
		//KieSession ksession = kc.newKieSession("ShoppingKS");

        Customer mark = new Customer( "mark",
                                      0 );
        ksession.insert( mark );

        Product shoes = new Product( "shoes",
                                     60 );
        ksession.insert( shoes );

        Product hat = new Product( "hat",
                                   60 );
        ksession.insert( hat );

        ksession.insert( new Purchase( mark,
                                       shoes ) );

        FactHandle hatPurchaseHandle = ksession.insert( new Purchase( mark,
                                                                      hat ) );

        ksession.fireAllRules();

        ksession.delete( hatPurchaseHandle );
        System.out.println( "Customer mark has returned the hat" );
        ksession.fireAllRules();
	}
}