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

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

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

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

Trending

  • Transforming AI-Driven Data Analytics with DeepSeek: A New Era of Intelligent Insights
  • Unmasking Entity-Based Data Masking: Best Practices 2025
  • AI-Based Threat Detection in Cloud Security
  • How to Practice TDD With Kotlin

Learn Drools (Part 7): Salience

Salience is how Drools determines priorities for your rules. You can use it to filter Drools facts down and lower the overhead of your system.

By 
Shamik Mitra user avatar
Shamik Mitra
·
Jan. 03, 17 · Tutorial
Likes (7)
Comment
Save
Tweet
Share
70.2K Views

Join the DZone community and get the full member experience.

Join For Free

Let's quickly summarize how Drools works. Rules are written on .drl files, facts or POJOs are inserted in the Knowledge Base, then rules are applied on each fact. If a "When" part of a rule satisfies a fact, the "Then" part will execute.

Having said that, one question just popped into my mind. If multiple rules match a fact, in which order will they be fired?

The answer is that they will fire arbitrarily. There is no sequence for executing rules. So, if we need a sequence or want a rule to fire first, how do we go about doing that?

Setting a Priority

In Drools, the answer is salience. Salience is a keyword in the .drl file that we can assign a positive or negative number. The number determines the salience priority. A higher number denotes a higher priority, so rules with a higher salience will be executed first by the Drools engine.

So, if Rule 1 has a salience of 10, Rule 2 has a 1, and Rule 3 has a 5, the order should be:

Rule 1>Rule 3>Rule 2.

The default salience value is 0. So, if we do not mention the salience, all rules get that default figure.

Conflicting Priorities

If multiple rules have the same salience, there won't be an execution order among them, but the engine will execute them at the same level.

So If Rule 1 has salience 10, Rule 2 has 10, and Rule 3 has 5, then Rule 1 or 2 will be executed first, followed by Rule 3. We cannot say which order  Rule 1 or Rule 2 will be executed — as they have the same salience value — but we can say that they will execute before Rule 3.

Negative Salience

It is possible to assign negative value in Salience. But the question is why and when to use a negative value.

The answer is very simple. If we want a rule to be fired last, we provide a negative value. Just think, if salience only accepted positive values, then with a default value of 0, you would have to change the salience of each one in order to guarantee that one would fire last.

Think if a .drl file had 500 entries. We would have to provide positive salience for each rule. But because a negative value is accepted, we just define the rule with negative salience in order to execute last.

Solving Problems With Salience

Let's see salience in action.

Say we want to give a laptop to managers in IT department?

One way to approach this problem is to write a rule to check that if an employee's department is IT and their designation is "manager", then they get a laptop. But this is not efficient. Our setup will run through every fact irrespective of the department. If you've got a huge number of facts, that's going to cause problems.

But we can view this problem in another way. We can filter out facts based on the department first, then based on job designation, then give a laptop to the remaining facts.

So first, give a higher salience to rules that filter departments. Here, we will check if the department is IT. Then, give medium salience to the designation rule, where we check if an employee has been desigated as a manager. Finally, give the lowest or default saliance to the rule that gives laptops out so that it fires last — and only fires on the facts that have been filtered. 

Let's see it in action.

First, we'll check the Drools file employeeSalience.drl:

package com.rules

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

rule "Not IT" salience 10
lock-on-active
   when
      $emp: Employee("IT" != dept.getName());
   then
   System.out.println("filter Dept ::" + $emp.getName());
   $emp.setFilter(true);
   update($emp);
end
rule "Not Manager" salience 5
lock-on-active
   when
      $emp: Employee(manager==false);
   then
   System.out.println("filter Manger ::" + $emp.getName());
   $emp.setFilter(true);
   update($emp);
end
rule "give Manager Laptop"

   when
      $emp: Employee(filter==false);

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


And here's our employee object:

package com.example.droolsExample.pojo;

public class Employee {
   String name;
   boolean manager;
   String message;
   Department dept;
   boolean filter;
   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;
   }


   public boolean isFilter() {
      return filter;
   }
   public void setFilter(boolean filter) {
      this.filter = filter;
   }
   @Override
   public String toString() {
      return "Employee [name=" + name + ", manager=" + manager + ", message="
              + message + ", dept=" + dept + "]";
   }
}


And our department object:

package com.example.droolsExample.pojo;

public class Department {

   String name;

   public String getName() {
      return name;
   }

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


And our DroolsTest Java file:

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 com.example.drools.listener.TrackingRuleFiredEventListener;
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/employeeSalience.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();

   }
}


And our output:

filter Dept ::Samir Mitra
filter Manager ::Swastika Mitra
Shamik Mitra: IT:Give Laptop


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

Partner Resources

×

Comments

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

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • 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: