I'm using Drools (for the first time) to express some rules and it has been working really well so far. However I've been given a new condition that I'm not able to express in the rules language very clearly.
Essentially I need to perform an action on the players account if they have an outstanding balance on there account between a certain amount, where they haven't made a payment in the last week and where they haven't made a payment in the last 4 weeks that is greater than or equal to a weekly deduction. There are a few other rules but I've removed them in an effort to simplify the rule for this question. It's the last rule that is causing me a 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's 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 that it just doesn't work, I keep getting org.drools.rule.InvalidRulePackage exceptions thrown. I was just guessing on the syntax but couldn't seem to find an example that showed what I'm trying to do. Is it even possible?
The full original error message is:
"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"
yes as you guessed, you need to put an explicit "and" inside the "not" pattern to join them together.
The only time you don't need the "and" is at the top level:
eg
when Foo() Bar()
Doesn't require a an "and"
but this is implicitly the same as
when Foo() and Bar()
So your solution seems correct. The lack of a top level "and" seems to be convention in most rule languages (going back to CLIPS !)