How to implement rule If I want to execute only one rule rather than execute all rules in Drools Rule Engine?

StackOverflow https://stackoverflow.com/questions/20582238

  •  01-09-2022
  •  | 
  •  

Pregunta

I want to implement rule engine in which if only one condition executes then it will not check other specified conditions.

rule "Print out lower-case tokens"
when
    Token ( coveredText == coveredText.toLowerCase )
then
    System.out.println("Found a lower case token with text");
end


rule "Print out long tokens with more than 5 characters"
    when
        Token ( tokenText : coveredText, end - begin > 5 )
    then
        System.out.println("Found a long token with more than 5 characters \"" + tokenText + "\"");
end

In above example, if coveredText and its lowercase are equals then I don't want to check another rule.
How can I implement this kind of nature in Drools Rule Engine ?

¿Fue útil?

Solución 2

This can be achieved by using agenda groups in Drools.

Quote :

Agenda groups are a way to partition the Agenda into groups and to control which groups can execute. By default, all rules are in the agenda group "MAIN". The "agenda-group" attribute lets you specify a different agenda group for the rule. Initially, a Working Memory has its focus on the Agenda group "MAIN". A group's rules will only fire when the group receives the focus.

For example when rule "Print out lower-case tokens" fires, you can set the focus to another group (Not the group of the two rules you mentioned). Of course you want the first rule the be triggered first. This can be done with a higher salience value:

Each rule has an integer salience attribute which defaults to zero and can be negative or positive. Salience is a form of priority where rules with higher salience values are given higher priority when ordered in the Activation queue.

Otros consejos

If you only have a few rules, agenda groups mentioned by @K.C. might be too 'heavy' for your purpose. In simpler cases I'd just add a fact to mark that the rules should not be fired anymore, like this

declare AlreadyProcessed
end

rule "Print out lower-case tokens"
  when
    not AlreadyProcessed()
    Token ( coveredText == coveredText.toLowerCase )
  then
    System.out.println("Found a lower case token with text");
    insert( new AlreadyProcessed() );
end


rule "Print out long tokens with more than 5 characters"
    when
        not AlreadyProcessed()
        Token ( tokenText : coveredText, end - begin > 5 )
    then
        System.out.println("Found a long token with more than 5 characters \"" + tokenText + "\"");
        insert( new AlreadyProcessed() );
end

And as mentioned, you can control the execution order via salience if needed.

The activation-group provides this feature out of the box. Drools wiki

activation-group default value: N/A

type: String

Rules that belong to the same activation-group, identified by this attribute's string value, will only fire exclusively. In other words, the first rule in an activation-group to fire will cancel the other rules' activations, i.e., stop them from firing.

Note: This used to be called Xor group, but technically it's not quite an Xor. You may still hear people mention Xor group; just swap that term in your mind with activation-group.

e.g.: Only us1 will be executed-

rule "us1"
activation-group "1"
dialect "java"
when
      eval ( 1==1 )
then
      System.out.println("us1" );
end

rule "us2"
activation-group "1"
dialect "mvel"
when
      eval ( 1==1 )
then
      System.out.println("us2" );
end
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top