Drools 布尔比较

Posted

技术标签:

【中文标题】Drools 布尔比较【英文标题】:Drools boolean comparison 【发布时间】:2019-05-28 02:35:29 【问题描述】:

为什么false == (cancelationCode == 'C') bahave 不同 来自(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语句并具有否定它们的能力。

最初不是作为! 实现的,它适用于当前场景。但它不适用于buySellTypeCode in ('B', 'S') 之类的情况,但它适用于false == statement

当 DSL 被评估为输入对象时,规则不会被触发

$trade: Trade((recordTypeCode == '910') && false == (cancellationCode == 'C'))    

当 DSL 被评估为相同的输入对象时触发

$trade: Trade((recordTypeCode == '910') && (cancellationCode == 'C') == false)

【问题讨论】:

可能是因为第一个 cancelationCode 有一个 L,而第二个有两个? 不,只是我的错字,我在这里放了简化的表达方式来展开讨论) 您必须展示一个完整的示例 (minimal reproducible example) 来演示该问题,并解释“bahaves different”的含义。 cancelationCode 的值是多少?这些比较的结果是什么?问题很可能出在代码的其他地方。 抱歉,我在想它的 ='C'。 'behaves different' 意味着对于同一个输入对象,一个语句触发规则,而另一个语句不触发 【参考方案1】:

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

当我将false == (cancelationCode == 'C') 更改为true ^ (cancelationCode == 'C') 时出现错误:“谓词'true ^ cancelCode =='C'' 必须是布尔表达式”。这揭示了问题的根本原因 - ANTLR 解析器在单个语句周围去掉大括号,这就是为什么

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

有趣的是,复杂的语句并没有去掉大括号,所以两者都按预期工作:

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

我会说这种“优化”是一个错误。

【讨论】:

以上是关于Drools 布尔比较的主要内容,如果未能解决你的问题,请参考以下文章

Drools 规则引擎一文读懂

Drools实战系列之eclipse创建工程

规则引擎调研(drools和qlexpress)

将类对象传递给 Drools 规则 (drt) 文件

使用Drools来实现规则引擎

Drools规则引擎-如果判断某个对象中的集合是否包含指定的值