drools how to fire specified group dynamically

366 views Asked by At

i am using drools 7.x.

my logic looks like following:

if(variableA == 1) {

    if(variableA1 == 2) {
        ....
    } else if(variableA1 == 3) {
        ....
    }
}else {

    if(variableB1 == 1) {
        ....
    }else if(variableB1 == 2) {

        if(variableN == 1) {

        }else if(variableN == 2) {

        }
    }
}

by the way, these variables not in the same class, i intend to insert them as fact in drl.

how can i define the rules? or how can i define rules like :

rule 1
    when
    then
end

rule 2
    when
    then
end

rule 1-1
    when
    then
end

rule 1-2
    when
    then
end

rule 2-1
    when
    then
end

rule 2-2
    when
    then
end

wherein, only one of rules will be fired in rule 1 and rule 2, rule 1-1 and rule 1-2 is group1, rule 2-1 and rule 2-2 is group2.

if rule 1 is fired, then only one of rules is fired in group1, there is no need to test group2. While if rule 2 is fired, then only one of rules is fired in group2, there is no need to test group1.

2

There are 2 answers

5
Mike On BEST ANSWER
  • salience for rules priority
  • logical insertions to depend on other rule
  • activation-group for xor logic

rule "1"
  salience 1
  activation-group "group 0"
  when
    $model : Model(a == 1)
  then
    insertLogical(new GroupActivation("group 1", $model));
    System.out.println("rule 1");
end

rule "2"
  salience 1
  activation-group "group 0"
  when
    $model : Model(b == 1)
  then
    insertLogical(new GroupActivation("group 2", $model));
    System.out.println("rule 2");
end

rule "1-1"
  activation-group "group 1"
  when
    GroupActivation(name == "group 1", $model : model)
    Model(this == $model, a1 == 1)
  then
    System.out.println("rule 1-1");
end

rule "1-2"
  activation-group "group 1"
  when
    GroupActivation(name == "group 1", $model : model)
    Model(this == $model, a2 == 1)
  then
    System.out.println("rule 1-2");
end

rule "2-1"
  activation-group "group 2"
  when
    GroupActivation(name == "group 2", $model : model)
    Model(this == $model, b1 == 1)
  then
    System.out.println("rule 2-1");
end

rule "2-2"
  activation-group "group 2"
  when
    GroupActivation(name == "group 2", $model : model)
    Model(this == $model, b2 == 1)
  then
    System.out.println("rule 2-2");
end

Model.java

public class Model {
    
    private int a;
    private int a1;
    private int a2;
    private int b;
    private int b1;
    private int b2;
...

GroupActivation.java

public class GroupActivation {
    
    private String name;
    private Model model;
...
9
Roddy of the Frozen Peas On

I'm going to assume all of these variables exist inside of an class which I'm going to call Inputs. You'd call these rules by passing an instance of Inputs into the rules.

I'm also going to assume that the last 'else if' in your example was a type and you're actually checking that variableN == 2.

rule "A1-2"
when
  Inputs( variableA == 1,
          variableA1 == 2 )
then
  // ...
end

rule "A1-3"
when
  Inputs( variableA == 1,
          variableA1 == 3 )
then
  // ...
end

rule "B1"
when
  Inputs( variableA != 1,
          variableB1 == 1 )
then
  // ...
end

rule "B2-N1"
when
  Inputs( variableA != 1,
          variableB1 == 2,
          variableN == 1 )
then
  // ...
end

rule "B2-N2"
when
  Inputs( variableA != 1,
          variableB1 == 2,
          variableN == 2 )
then
  // ...
end

Rather straight forward. The key is that you need to check that the condition for variableA ==1 is not true for the rules that deal with B. Basically when you're converting an if/elsif/else into rules, you need to negate the conditions from the previous if-clauses on your left-hand-side.

There's no "specified groups" involved. Mostly because there's no explanation about what you mean by these words.

Drools also has inheritance. There's no real reason to use it here, but you could if you wanted to:

rule "A1"
when
  $i: Inputs(variableA == 1)
then // notice empty "then"
end

rule "A1 = 2" extends "A1"
when
  Inputs( variableA1 == 2 ) from $i
then
  //
end