Проблема написания LHS правил Drools / JBoss, где я сопоставляю один факт, а затем использую этот факт, чтобы определить, существует ли другой факт
Я использую Drools (впервые), чтобы выразить некоторые правила, и до сих пор это работало очень хорошо. Однако мне дали новое условие, которое я не могу выразить на языке правил очень четко.
По сути, мне нужно выполнить действие с учетной записью игроков, если у них есть непогашенный остаток на этом счете между определенной суммой, когда они не произвели платеж на прошлой неделе и где они не произвели платеж за последние 4 недели, которые больше или равны недельному вычету. Есть несколько других правил, но я удалил их, чтобы упростить правило для этого вопроса. Это последнее правило, которое вызывает у меня проблемы.
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
Проблема в том, что это просто не работает, я продолжаю получать исключения org.drools.rule.InvalidRulePackage. Я только догадывался о синтаксисе, но не смог найти пример, который бы показал, что я пытаюсь сделать. Это вообще возможно?
Полное оригинальное сообщение об ошибке:
"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'"
После попытки предложения в первом комментарии ошибка:
"[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"
3 ответа
Да, как вы уже догадались, вам нужно поместить явные "и" внутри шаблона "не", чтобы соединить их вместе.
Единственный раз, когда вам не нужно "и" находится на верхнем уровне:
например
when Foo() Bar()
Не требует "и"
но это неявно так же, как
when Foo() and Bar()
Таким образом, ваше решение кажется правильным. Отсутствие верхнего уровня "и", кажется, является условным в большинстве языков правил (возвращаясь к CLIPS!)
После некоторого дополнительного взлома следующее не вызывает никаких ошибок во время выполнения (хотя я не уверен, что это "правильно" пока). Я переписал этот пункт, чтобы сопоставить факты с фактами, использовал инфикс и сгруппировал их.
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)
)
)
)
Спасибо за всю помощь до сих пор.
Как насчет ($deduction->amountInPence * 4)
? Я думаю ->
должен быть .
вместо.