Проблема написания LHS правил Drools / JBoss, где я сопоставляю один факт, а затем использую этот факт, чтобы определить, существует ли другой факт

StackOverflow https://stackoverflow.com/questions/415907

  •  03-07-2019
  •  | 
  •  

Вопрос

Я использую 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"
Это было полезно?

Решение

да, как вы уже догадались, вам нужно поставить явные " и " внутри "не" шаблон, чтобы объединить их.

Единственный раз, когда вам не нужны " и " находится на верхнем уровне:

например

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) ? Я думаю, что -> должно быть . .

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top