Drools 布尔值比较

Drools boolean comparison

为什么 false == (cancelationCode == 'C') 行为不同
来自 (cancelationCode == 'C') == false?

它是 drools 6.5.0 中的错误还是我遗漏了什么?


完整故事如下:

我正在使用 Drools DSL,我必须实施规则:

rule "my business rule"
    dialect "mvel"
    when
        There is a trade that
        - Supervised Trade
        ...
    then
        ...
end

我有这些 DSL 定义:

[when] Supervised Trade = 
    Customer Trade 
    AND NOT Canceled 

[when] Customer Trade = (recordTypeCode is equal to '910')
[when] Canceled = (cancellationCode is equal to 'C')

[when] is equal to = ==

[when] {var1}?(?<![\w'])\s*AND\s*(?![\w']){var2}? = {var1} && {var2}
[when] {var1}?(?<![\w'])\s*OR\s*(?![\w']){var2}? = {var1} || {var2}
[when] {var1}?(?<![\w'])\s*NOT\s*(?![\w']){var2}? = {var1} false == {var2}

要求是以积极的方式编写可重用的 DSL 语句,并有能力否定它们。

最初 NOT 是作为 ! 实现的,它适用于当前场景。但它不适用于像 buySellTypeCode in ('B', 'S') 这样的情况,尽管它与 false == statement 一起工作。

当 DSL 被评估为

时,不会为输入对象触发规则
$trade: Trade((recordTypeCode == '910') && false == (cancellationCode == 'C'))    

并且当 DSL 被评估为

时,为同一输入对象触发
$trade: Trade((recordTypeCode == '910') && (cancellationCode == 'C') == false)

它的行为确实不同,因为它使用 DRL6 词法分析器进行了不同的解析。
org.drools.compiler.compiler.DrlExprParser.parse 按原样使用这些文本片段,但是
BaseDescr expr = parser.conditionalOrExpression(); 表明 ANTLR 解析器以不同的方式处理这些。

当我将 false == (cancelationCode == 'C') 更改为 true ^ (cancelationCode == 'C') 时,出现错误:"Predicate 'true ^ cancellationCode == 'C'' must be a Boolean expression"。这揭示了问题的根本原因——ANTLR 解析器去掉了单个语句周围的大括号,这就是为什么

false == cancelationCode == 'C' -> doesn't work as expected    
cancelationCode == 'C' == false -> works as expected

有趣的是,复杂语句周围的大括号并没有被剥离,因此两者都按预期工作:

false == (true && cancelationCode == 'C')
(true && cancelationCode == 'C') == false

我会说这 'optimization' 是一个错误。