Drools / JBoss LHS rule writing problem where I match one fact and then using that fact to determine if another fact exists

I am using Drools (for the first time) to express some rules and it has been working very well so far. However, I have been given a new condition, which I cannot express in the language of rules very clearly.

Basically, I need to take an action on the players account if they have an outstanding account balance between a certain amount, where they didn't make a payment last week, and where they didn't make a payment in the last 4 weeks, which is greater than or equal to a weekly deduction. There are a few more rules, but I've removed them to simplify the rule for this question. This is the last rule that is causing me the problem.

rule "The broken rule"
   salience 10
   no-loop
   when
      Player( $playerNumber : playerNumber )
      $a : Account( // balance between £5 and £100 and no arrangement
       playerNumber == $playerNumber &&
         accountBalanceInPence >= 500 &&
         accountBalanceInPence <= 10000
      )
      not ( // no payment in last week
         exists AccountTransaction(
            playerNumber == $playerNumber &&
            transactionDate >= oneWeekAgo &&
            transactionCode == "P" // payment
         )
      )
      /* It this next bit that is broken */
      not ( // no payment > (weekly cost * 4) paid within last 4 weeks
         $deduction : AccountTransaction( // a recent transaction
            playerNumber == $playerNumber &&
            transactionDate >= fourWeeksAgo &&
            transactionCode == "D" // deduction
         )
         exists AccountTransaction( // the payment
            playerNumber == $playerNumber &&
            transactionDate >= fourWeeksAgo &&
            transactionCode == "P" // payment
            amountInPence >= ($deduction->amountInPence * 4)
         )
   )
   then
      // do some action to the account
end

      

The problem is, it just doesn't work, I keep getting org.drools.rule.InvalidRulePackage exceptions. I was just guessing about the syntax, but couldn't find an example that showed what I am trying to do. Is it possible?


Complete original error message:

"unknown:50:3 mismatched token: [@255,1690:1695='exists',<39>,50:3]; expecting type RIGHT_PAREN[54,4]: unknown:54:4 mismatched token: [@284,1840:1852='amountInPence',<7>,54:4]; expecting type RIGHT_PAREN[54,22]: unknown:54:22 Unexpected token '$payment'"

      

After trying the suggestion in the first comment, the error is:

"[50,3]: unknown:50:3 mismatched token: [@255,1690:1695='exists',<39>,50:3]; expecting type RIGHT_PAREN[54,4]: unknown:54:4 mismatched token: [@284,1840:1852='amountInPence',<7>,54:4]; expecting type RIGHT_PAREN[54,45]: unknown:54:45 mismatched token: [@293,1881:1881='*',<71>,54:45]; expecting type LEFT_PAREN[55,3]: unknown:55:3 mismatched token: [@298,1890:1890=')',<12>,55:3]; expecting type THEN"

      

+1


source to share


3 answers


yes, you guessed it, you need to add an explicit "and" inside the template "not" to combine them.

The only time you don't need "and" is at the top level:

eg

when Foo() Bar()

      



Not required "and"

but this is implicitly the same as

when Foo() and Bar()

      

So your solution seems to be correct. The lack of a top-level "and" seems to be a convention in most rule languages ​​(fallback to CLIPS!)

+1


source


After some hacks around the following, it doesn't throw runtime errors (although I'm not sure if it's "fixed" yet). I rewrote the proposal to put a creature around both facts and use infix and group them.

  not ( // no payment > (weekly cost * 4) paid within last 4 weeks
     exists (
        AccountTransaction( // a recent transaction
           playerNumber == $playerNumber &&
           transactionDate >= fourWeeksAgo &&
           transactionCode == "D" // deduction
           $recentDeducation : amountInPence
        ) and
        AccountTransaction( // the payment
           playerNumber == $playerNumber &&
           transactionDate >= fourWeeksAgo &&
           transactionCode == "P" // payment
           amountInPence >= ($recentDeducation * 4)
        )
     )
  )

      



Thanks for all the help so far.

+1


source


How about ($deduction->amountInPence * 4)

? I think there ->

should be .

instead.

0


source







All Articles