Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drools Core DRL - Fire only one rule with the highest salience, skip other rules

Tags:

java

drools

rule

I have simple JAVA bean with two int fields: 'a' and 'b'.

I have two rules:

rule "First rule"
salience 10
when
    $bean : Bean ( a == 1)
then
    $bean.setB(10);
end

rule "Second rule"
salience 20
when
    $bean : Bean ( a == 1)
then
    $bean.setB(20);
end

Actual results: "Second rule" is fired first (higher salience), "First rule" is fired second.

Expected results: Only one rule (with the highest salience) is fired. Other rules are ignored. How to do this? Is it possible in Drools? I am using Drools 6.0.0 Final.

Requirements: 1. I can't use 'activation-group'. 2. I don't want to use 'retract' on each bean.

UPDATE

Really thanks for your answers.

Probably I should describe my problem in details. I have a set of 1500 rules. Each rule:

  • works with the same bean - this bean has a lot of fields (properties),
  • has salience,
  • has a lot of conditions,
  • has only one action - setting one (always the same) boolean flag in my bean.

What I want to get? When I have conflict (the input fact is matched by two or more rules) I want to fire only one rule with the highest salience. Other matched rules for this one fact should be ignored. The most important thing is performance - this should work as fast as possible.

What I do? At the moment I have two solutions but I don't know which one is better or maybe I should solve this problem in different way.

Solution 1 - Statefull session

Java code:

for (Object fact : facts) {
    FactHandle fh = session.insert(fact);
    session.fireAllRules(1);
    session.delete(fh);
}

Solution 2 - Stateless session

Java code:

for (Object fact : facts) {
    session.execute(fact);
}

DRL file for solution 2: I added to each rule the same activation-group:

rule "Rule"
activation-group "group"
salience X
when
    ...
then
    ...
like image 754
user3430447 Avatar asked Mar 17 '14 20:03

user3430447


People also ask

How do you fire a specific rule in Drools?

In any case, the Customer has to be identified by a fact. To associcate a Customer with rules you need: class Customer { private String name; private List<String> rules; //... } So you are saying to create agenda for each customer and fire the rules based on agenda...

How does salience work in Drools?

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.

What is DRL file in Drools?

DRL (Drools Rule Language) rules are business rules that you define directly in . drl text files. These DRL files are the source in which all other rule assets in Business Central are ultimately rendered.

What are drool rules?

Drools is a business rule management system (BRMS) with a forward and backward chaining inference based rules engine, more correctly known as a production rule system, using an enhanced implementation of the Rete algorithm.


1 Answers

Based on your question, I'm worried you might be misunderstanding the point of salience. Salience is a prioritization value. Drools uses it in order figure out which drool to fire first when it is the case that the constraints for more than one rule are satisfied.

The problem of [firing rule P under certain circumstances and NOT rule Q when rule P is fired] is a common one. Your object model should be set up such that this is a natural consequence of reasoning over your concept space. For the literal situation you have listed, you might try inserting a new fact into working memory ("RuleFiredFact" with a value of "2nd", or whatever). You would then check for this fact in your first rule constraints. If it is true, the first rule doesn't fire.

UPDATE: To be clear, "RuleFiredFact" is an abstract placeholder for some concrete fact in your fact model. Part of the point of drools is not using abstract stuff in the drools DSL.

UPDATE:

Whether or not stateful vs. stateless session is appropriate is going to depend a lot on your available computer resources, object model, team, the list goes on. If you don't know which to use, you should refer to a discussion on the topic. You might try this older mailing list post http://drools.46999.n3.nabble.com/Advice-sought-on-choosing-Stateful-or-Stateless-sessions-td57069.html

Whichever you go with, I strongly suspect your object model is too shallow. It is very uncommon to create a drools system which contains one fact, then never creates any more. The point of drools is to reason over a number of facts. The way to tackle this is probably going to be something like moving through your object and inserting the information within it into the drools working memory as facts. You would then write rules which only fire under the constraints you want.

In a circumstance like what I describe, there are many ways of making sure only a single rule fires. Your rules may all be on the lookout for a "factWasAlreadyReasonedOverFact" with a reference to the fact which triggered the execution. This is a pretty rough example. Hopefully it gives you an idea.

like image 61
melchoir55 Avatar answered Nov 02 '22 11:11

melchoir55