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
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
View Events Video Library
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
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

Migrate, Modernize and Build Java Web Apps on Azure: This live workshop will cover methods to enhance Java application development workflow.

Modern Digital Website Security: Prepare to face any form of malicious web activity and enable your sites to optimally serve your customers.

Kubernetes in the Enterprise: The latest expert insights on scaling, serverless, Kubernetes-powered AI, cluster security, FinOps, and more.

A Guide to Continuous Integration and Deployment: Learn the fundamentals and understand the use of CI/CD in your apps.

Related

  • How To Handle 100k Rows Decision Table in Drools (Part 3)
  • How To Handle 100k Rows Decision Table in Drools (Part 2)
  • Using Maven and Without Drools Eclipse Plugin
  • Drools With Mule 4

Trending

  • Understanding PDF Standards: What Developers Should Know
  • Evolution of Software Architecture: From Monoliths to Microservices and Beyond
  • Instant Microservices: Rules for Logic and Security
  • Ultimate Guide to Kubernetes StatefulSets With a MongoDB Example

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.

Shamik Mitra user avatar by
Shamik Mitra
·
Dec. 09, 16 · Tutorial
Like (4)
Save
Tweet
Share
11.5K 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 Shamik Mitra, DZone MVB. 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)
  • Using Maven and Without Drools Eclipse Plugin
  • Drools With Mule 4

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
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: