Drools 在I';m匹配一个事实,然后使用该事实确定是否存在另一个事实

Drools 在I';m匹配一个事实,然后使用该事实确定是否存在另一个事实,drools,rule-engine,jboss-rules,Drools,Rule Engine,Jboss Rules,我正在使用Drools(第一次)来表达一些规则,到目前为止,它运行得非常好。然而,我得到了一个新的条件,我不能用规则语言非常清楚地表达 基本上,我需要对玩家账户执行一项操作,如果他们在该账户上有一定金额的未偿余额,在上周他们没有付款,在过去4周他们没有付款,大于或等于每周扣除额。还有一些其他的规则,但为了简化这个问题的规则,我删除了它们。这是给我带来麻烦的最后一条规则 rule "The broken rule" salience 10 no-loop when P

我正在使用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
规则“破规则”
显著性10
无回路
什么时候
播放器($playerNumber:playerNumber)
$a:账户(//余额在5英镑和100英镑之间,无安排
playerNumber==$playerNumber&&
账户余额>=500&&
账户余额输入=一周一次&&
交易代码==“P”//付款
)
)
/*这是下一个被破坏的部分*/
过去4周内未支付(//无付款>(周成本*4)
$Decreation:AccountTransaction(//最近的交易
playerNumber==$playerNumber&&
交易日期>=四周前&&
交易代码==“D”//扣除额
)
存在AccountTransaction(//付款
playerNumber==$playerNumber&&
交易日期>=四周前&&
交易代码==“P”//付款
金额>=($扣减->金额*4)
)
)
然后
//对帐户执行一些操作
结束
问题是它根本不起作用,我一直在抛出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不匹配的令牌:[@2551690:1695='exists',50:3];应为类型RIGHT\u PAREN[54,4]:未知:54:4不匹配的令牌:[@2841840:1852='amountInPence',54:4];应为类型RIGHT\u PAREN[54,22]:未知:54:22意外令牌“$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"
“[50,3]:未知:50:3不匹配的令牌:[@2551690:1695='exists',50:3];应为右对齐类型[54,4]:未知:54:4不匹配的令牌:[@2841840:1852='amountInPence',54:4];应为右对齐类型[54,45]:未知:54:45不匹配的令牌:[@2931881:1881='*',54:45];应为左对齐类型[55,3]:未知:55:3不匹配的令牌:[@2981890:1890=”),,55:3];应键入“THEN”

关于
($DELECTION->amountInPence*4)
?我认为
->
应该是

经过更多的黑客攻击后,以下内容不会导致任何运行时错误(尽管我还不确定它是否“正确”).我重写了这一条款,把两个事实放在一起,用中缀把它们组合起来

  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)
        )
     )
  )

感谢迄今为止的所有帮助。

是的,正如您所猜测的,您需要在“not”模式中添加一个明确的“and”来将它们连接在一起

您唯一不需要“和”的时间是在顶层:

乙二醇

不需要“和”

但这与

when Foo() and Bar()

因此,您的解决方案似乎是正确的。缺少顶级“和”似乎是大多数规则语言的惯例(回到剪辑!)

不幸的是,这不起作用,我将更新问题,并提供更多关于错误消息的详细信息(它们不适合注释)。我认为这是一个已编辑的打字错误-是的,是“->”似乎是错误的。这是一种不再需要的旧语法。您可能不需要“&&”,并且可以将每个字段约束用“,”分隔-只是一个建议接受这个答案,就好像我自己破解了一样-你的答案解释了它为什么有效!谢谢-但你做了艰苦的工作!我只是试图解释它为什么有效。仅供参考,你得到的异常是因为它无法编译(我认为在未来的版本中,您必须检查代码中的错误,不会抛出异常IIRC)
when Foo() and Bar()