DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
Building Scalable Real-Time Apps with AstraDB and Vaadin
Register Now

Trending

  • Demystifying SPF Record Limitations
  • DevOps Midwest: A Community Event Full of DevSecOps Best Practices
  • Front-End: Cache Strategies You Should Know
  • Exploring the Capabilities of eBPF

Trending

  • Demystifying SPF Record Limitations
  • DevOps Midwest: A Community Event Full of DevSecOps Best Practices
  • Front-End: Cache Strategies You Should Know
  • Exploring the Capabilities of eBPF

Learn Drools (Part 4): Inferences

Learn how you can set up inferences in Drools to create more modular rules that can be changed on the go.

Shamik Mitra user avatar by
Shamik Mitra
·
Nov. 23, 16 · Tutorial
Like (7)
Save
Tweet
Share
12.21K Views

Join the DZone community and get the full member experience.

Join For Free

As per the dictionary, inference means, "An assumption or conclusion that is rationally and logically made, based on the given facts or circumstances."

An inference is based off of facts, so the reasoning for the conclusion is often logical.

Example: According to a technical interview, we can make an assumption that a candidate is good, bad, or moderate. The thing to notice here is that we don’t know how good the candidate is, as we do not work with them, but according the candidate's answers (facts), we can logically judge and come to a conclusion.

So, how do Drools' inferences work?

Let's try to understand it with a problem statement.

We want to give a laptop to those people who are in IT department whose designation is the manager.

When we get this problem statement, we will try to solve it with a Drools rule. Inputting the logic, we use Ifdepertment=="IT" and isManager=true, then we print "Give laptop."

As simple as that.

Solution

rule "give Laptop"
  when
     $dept: Department(name=="IT");
     $emp: Employee(dept == $dept,manager==true);

  then
  $emp.setMessage("Give Laptop");
  System.out.println($emp.getName()+ ": "+$emp.getDept().getName()+ ":"+$emp.getMessage());
end

Is this an elegant way to solve this problem?

The answer depends. If this IT Manager condition check (depertment=="IT" and isManager=true) is used in several rules, then it is not an elegant way to implement it. We can do it better, and here's the potential where we can use Inference.

On other hand, if this condition used only one or in a few rules and no future changes will be needed, then make it simple. The above rule is just fine, as I am a big follower of YAGNI (You aren't gonna need it).

Why is the above not a judicious way to define the rules where the same condition is used in several of them?

Let's say the IT manager condition is used in 100 different rules, and based on that condition, we will take different actions. So far, the condition has not changed, so our design is good. But think about if the condition requirements are changed — now the client wants (department=="IT" and isManager=true and experience>15). Now this experience factor is set to greater than 15, and that has to be taken into account.

So, we need to change the condition in 100 rules. A simple change is then hard to implement because the condition has been duplicated over 100 time.

It would be nice if could we design in a such a way that we can define the condition in one place and use that reference in other places — like soft link in Unix or environment variables in Windows.

By doing that , we can use the reference to the condition in every rule. We set JAVA_HOME="C;//java"; and use JAVA_HOME anywhere to declare a Java path, so in case we change the Java path to c://javaone, that will be reflected everywhere.

Fortunately, we can do the same thing in Drools via an Inference. Let's see how to do it step by step.

Step 1

Create a rule where we define the condition  and create a reference to that in the "then" part, so we can use this reference in other rules.

rule "IT Manager Inference"
   when
      $dept: Department(name=="IT");
      $emp: Employee(dept == $dept,manager==true);
   then
   insert(new ITManager($emp));
end


Please note the then part of the rule, where we insert a Java object called ITManager, which takes the employee reference. With this statement, we instruct Drools to insert an ITManager object into the KnowledgeFactory, which holds the "when" parts. It acts as a reference, like the JAVA_HOME key.

Step 2

Let's create other rules where we use this IT Manager reference.

rule "give Manager Laptop"
   when
      $emp: Employee();
      $itManager: ITManager(emp == $emp);

   then
   $emp.setMessage("Give Laptop");
   System.out.println($emp.getName()+ ": "+$emp.getDept().getName()+ ":"+$emp.getMessage());
end


Pay attention to the "when" part here. We check to see if the current employee is matching the  ITManager condition. Here, Drools replaces ITManger with the actual "when" condition stated in the ITManager inference rule.

Step 3

Let's look at our complete Drools rule file.

package com.rules

import com.example.droolsExample.pojo.Employee
import com.example.droolsExample.pojo.Department
import com.example.droolsExample.pojo.ITManager

rule "IT Manager Inference"
   when
      $dept: Department(name=="IT");
      $emp: Employee(dept == $dept,manager==true);
   then
   insert(new ITManager($emp));
end
rule "give Manager Laptop"
   when
      $emp: Employee();
      $itManager: ITManager(emp == $emp);

   then
   $emp.setMessage("Give Laptop");
   System.out.println($emp.getName()+ ": "+$emp.getDept().getName()+ ":"+$emp.getMessage());
end


This setup ensures any changes in we made will be automatically reflected in our "Give Laptop" rule.

Step 4: Java Objects

Employee.java

package com.example.droolsExample.pojo;

public class Employee {

   String name;
   boolean manager;
   String message;
   Department dept;
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public boolean isManager() {
      return manager;
   }
   public void setManager(boolean manager) {
      this.manager = manager;
   }
   public String getMessage() {
      return message;
   }
   public void setMessage(String message) {
      this.message = message;
   }
   public Department getDept() {
      return dept;
   }
   public void setDept(Department dept) {
      this.dept = dept;
   }
}


ITManager.java

package com.example.droolsExample.pojo;

public class ITManager {

   private Employee emp;
   public ITManager(Employee emp)
   {
      this.emp=emp;
   }


   public Employee getEmp() {
      return emp;
   }

   public void setEmp(Employee emp) {
      this.emp = emp;
   }
}


Department.java

package com.example.droolsExample.pojo;

public class Department {

   String name;

   public String getName() {
      return name;
   }

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


DroolTest.java

package com.example.droolsExample;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

import org.drools.compiler.compiler.DroolsParserException;
import org.drools.compiler.compiler.PackageBuilder;
import org.drools.core.RuleBase;
import org.drools.core.RuleBaseFactory;
import org.drools.core.WorkingMemory;

import com.example.droolsExample.pojo.Department;
import com.example.droolsExample.pojo.Employee;



public class DroolsTest {

   public static void main(String[] args) throws DroolsParserException,
          IOException {
      DroolsTest droolsTest = new DroolsTest();
      droolsTest.executeDroolsEmployee("/com/rules/employeeInfernce.drl");
   }

      public void executeDroolsEmployee(String ruleFile) throws DroolsParserException, IOException {

      PackageBuilder packageBuilder = new PackageBuilder();

      InputStream resourceAsStream = getClass().getResourceAsStream(ruleFile);

      Reader reader = new InputStreamReader(resourceAsStream);
      packageBuilder.addPackageFromDrl(reader);
      org.drools.core.rule.Package rulesPackage = packageBuilder.getPackage();
      RuleBase ruleBase = RuleBaseFactory.newRuleBase();
      ruleBase.addPackage(rulesPackage);

      WorkingMemory workingMemory = ruleBase.newStatefulSession();

      Department dep = new Department();
      dep.setName("Civil");

      Department dep1 = new Department();
      dep1.setName("IT");

      Employee emp = new Employee();
      emp.setName("Shamik Mitra");
      emp.setManager(true);
      emp.setDept(dep1);

      Employee emp1 = new Employee();
      emp1.setName("Samir Mitra");
      emp1.setManager(true);
      emp1.setDept(dep);

      workingMemory.insert(dep);
      workingMemory.insert(dep1);
      workingMemory.insert(emp);
      workingMemory.insert(emp1);
      workingMemory.fireAllRules();

   }

}


Step 5: Output

Shamik Mitra: IT:Give Laptop


And that's it! Congratulations, you've set up an inference.

Drools

Published at DZone with permission of Shamik Mitra, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Trending

  • Demystifying SPF Record Limitations
  • DevOps Midwest: A Community Event Full of DevSecOps Best Practices
  • Front-End: Cache Strategies You Should Know
  • Exploring the Capabilities of eBPF

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: