jagapathi
jagapathi

Reputation: 1645

If condition in THEN clause drools

I tried researching a lot online but unable to find the exact reason for my error

Here is my problem

I am trying to write an if-else condition in RHS (THEN) but my drools show the following error

[An error occurred when attempting to build drools rule set. Error: Unable to Analyse Expression if (

I know this clearly says that I can't write if inside THEN (RHS), but I was able to do it in drools version 6.5.0-FINAL

is it something that got introduced in the 6.5.0 version? please guide me in the right direction for this investigation

I cant create two rules for this I need an if-else condition inside THEN

my drools version is 5.5.0

rule "TEST"
when
     $aa : Age()
then
     if(//something)
     {
        //something
     }
     else
     {
     }
end

Upvotes: 3

Views: 11374

Answers (1)

Roddy of the Frozen Peas
Roddy of the Frozen Peas

Reputation: 15179

This is perfectly valid going back to Drools 5.0 (can't speak to earlier, that's the earliest I ever used.) It is bad rule design -- whatever is restricting you to not adding a second rule is simply incorrect -- but you can have an if/else on the right hand side.

The reason it is bad rule design is that conditions should go on the conditional clause (left hand side, 'when') and the right hand side (then) should have the consequences. Drools optimizes the checking of conditions on the LHS, but executes the consequences on the RHS as-is. So by moving conditions to the RHS, you are causing your rules to be less performant because you're bypassing the optimization Drools provides.

The correct way would be -- as you probably figured out -- to have two rules like follows. (Since I don't know your particular use problem I'm going to make up something -- a difference in consequence depending on if the age is greater than or less than 18.)

rule "TEST - Under 18"
when
  Age( value < 18 )
then
  System.out.println("User is underage.");
end

rule "TEST - Adult"
when
  Age( value >= 18 )
then
  Sytem.out.println("User is an adult.");
end

As mentioned, you still can use an if-else if you must, but it is bad rule design and if I were doing your code review I'd send it back for revision. :)

rule "TEST WITH BAD PRACTICES"
when
  Age( $age: value )
then
  if ($age < 18) {
    System.out.println("User is underage.");
  } else  {
    System.out.println("User is an adult.");
  }
end

This rule is perfectly valid and it works. If it doesn't work for you, the problem is not with the rule, it's with something else in how you're loading or firing your rules that you have not shared. Maybe it's your dialect. Maybe it's how you're loading them. Maybe you have a typo in your 'if' like a missing quotation mark or hyphen, which you haven't shown us because you've not provided your actual rule.

That's something you'll have to investigate in your own environment (I suggest breakpoints and a debug session in your IDE.)


For completeness' sake, Drools 7 introduced the concept of conditional and named consequences. While many I know prefer the simplicity and streamlined-ness of the best practice of having multiple rules, this is an alternative way to provide conditional processing in a single rule.

Basically the idea is that if you have two extremely similar conditions, such that one builds off the other, you can use a syntax that is very similar to "goto" to trigger permutations of the right hand side. Here is how you might go about doing it for your situation:

rule "TEST with named consequences"
when
  Age( $age: value )
  if ( $age  < 18 ) break[underage]
then
  System.out.println("User is an adult.");
then[underage]
  System.out.println("User is underage.");
end

Upvotes: 7

Related Questions