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 Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • How To Handle 100k Rows Decision Table in Drools (Part 3)
  • How To Handle 100k Rows Decision Table in Drools (Part 2)

Trending

  • A Scalable Framework for Enterprise Salesforce Optimization: Turning Outcomes Into an Operating System
  • RAG Is Not Enough: Advanced Retrieval Architectures Using Vertex AI Search on GCP
  • Leveraging Apache Flink Dashboard for Real-Time Data Processing in AWS Apache Flink Managed Service
  • Spring Boot Done Right: Lessons From a 400-Module Codebase

Learn Drools (Part 5): Truth Maintenance

Drools handles truth tables via its Truth Maintenance System. As Drools facts change, the system logically inserts the new data, automatically keeping it updated.

By 
Shaamik Mitraa user avatar
Shaamik Mitraa
·
Dec. 09, 16 · Tutorial
Likes (4)
Comment
Save
Tweet
Share
12.3K Views

Join the DZone community and get the full member experience.

Join For Free

In our previous article, we saw how Inferences are useful when we need to repetitively use a condition across our Drools rules. With an Inference, we insert the condition as a POJO and use that fact across the rules. It's a perfect way to separate the condition from its usage.

But think about a condition where two rules are mutually exclusive. In that scenario, it is far better to use Truth maintenance, which is nothing but a truth table. Let's walk through it with an example.

Suppose, for our intrepid IT department, that if someone is designated as a Manager, we give them laptop. But if an employee is not a Manager, we give them a desktop. So in Drools, we have to create two rules:

  1. The first rule checks to see if someone's designation is "Manager", then gives them a laptop if they are.

  2. The second rule checks to see if the designation is not a manager, then gives them a desktop if they aren't one.

These two rules are mutually exclusive. For an employee/Drools fact, only one rule can be true — not both. So, we can maintain a truth table for that. In Drools, we call that the Drools Truth Maintenance System (TMS). Through the TMS, we can logically insert the condition — note that it's not just inserted, but logically inserted. The advantage of logical insertion is that when the condition is false, the fact/POJO is automatically retracted.

To understand the advantage of the TMS, think of a scenario where an employee's current designation is not a manager. So, according to the rule, they got a desktop, and we logically insert the "Not a Manager" condition in the Drools knowledge base for that employee or fact. But say that employee just got a promotion! After some hard work, the employee has been recognized as a leader and is now managing other workers. Now, that fact/condition that we inserted into the Drools knowledge base for that employee has to be retracted, and a new fact/condition ("is Manager") has to be inserted.

Of course, that makes the employee eligible for a laptop. Using the TMS, all that will be done automatically. We don’t have to care about it. You can find the solution to the above problem statement in the code blocks below.

Employee.drl

package com.rules

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

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

rule "IT Employee Inference1"
    when
    $dept: Department(name=="IT");
    $emp: Employee(dept == $dept,manager==false);
    then
    insertLogical(new ITEmployee($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

rule "give Employee Desktop"
    when
    $emp: Employee();
    $itEmployee: ITEmployee(emp == $emp);

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


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

    @Override
    public String toString() {
        return "Employee [name=" + name + ", manager=" + manager + ", message="
        + message + ", dept=" + dept + "]";
    }
}


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


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


ITEmployee.java

package com.example.droolsExample.pojo;

public class ITEmployee {

    private Employee emp;
    public ITEmployee(Employee emp)
    {
        this.emp=emp;
    }
  
    public Employee getEmp() {
        return emp;
    }

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


DroolTest.java

package com.example.droolsExample;

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

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 org.drools.core.event.AgendaEventListener;
import org.kie.api.runtime.process.ProcessInstance;
import org.kie.api.runtime.rule.FactHandle;
import com.example.drools.listener.Activation;
import com.example.drools.listener.TrackingAgendaEventListener;
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.executeDrools();
        droolsTest.executeDroolsEmployee("/com/rules/employeeTruthTable.drl");
    }

    public void executeDroolsEmployee(String ruleFile) throws DroolsParserException, IOException {
        PackageBuilder packageBuilder = new PackageBuilder();
        //String ruleFile = "/com/rules/employee.drl";
        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 emp2 = new Employee();
        emp2.setName("Swastika Mitra");
        emp2.setManager(false);
        emp2.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.insert(emp2);
        workingMemory.fireAllRules();
    }


Output

Shamik Mitra: IT:Give Laptop
Swastika Mitra: IT:Give Desktop


Drools

Published at DZone with permission of Shaamik Mitraa. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • How To Handle 100k Rows Decision Table in Drools (Part 3)
  • How To Handle 100k Rows Decision Table in Drools (Part 2)

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook