口水累积正在更新一个不相关的事实

标签 drools

在 Drools 中使用累积时,会针对未更新的事实评估并触发规则。

规则如下:

rule "WidgetsPerUser"
    when
        $user : User()
        accumulate(
            Widget ( checkIsUser($user) ); 
            $widgetCount : sum(1)
        )
    then
        System.out.println($user + " has " +  $widgetCount + " widgets");
end

这个想法很简单:计算每个用户Widget对象的数量。 checkIsUser() 是一个简单的相等性检查,但表示无法使用索引的检查。

以下是 Drools 7.0.0.Final 的示例输出:

-- Calling fire all rules --
User5 has 10 widgets
User4 has 10 widgets
User3 has 10 widgets
User2 has 10 widgets
User1 has 10 widgets

Widget moved from User3 to User1

-- Calling fire all rules --
User5 has 10 widgets
User3 has 9 widgets
User1 has 11 widgets

这里我们有 5 个 User 事实插入到内存中,并且所有 Widget 的起始计数都是 10。对 fireAllRules 的第一次调用显示正确的打印,因为所有用户事实都被插入到内存中。接下来是更新,其中 Widget 从 User3 移至 User1。存在预期的输出,但是 User5 没有理由显示为正在更新。

直观地突出问题:

User5 has 10 widgets    (User5 should NOT be triggered!)

                        (User4 is correctly ignored)

User3 has 9 widgets     (User3 is correctly triggered)

                        (User2 is correctly ignored)

User1 has 11 widgets    (User1 is correctly triggered)

User5 与 User2 或 User4 的唯一不同之处在于它是最后添加的用户事实,那么为什么它的行为不同呢?

这是预期的额外评估吗?它有什么目的?

请注意,问题不在于如何避免或解决额外的触发因素。

最佳答案

我自己挖掘了流口水核心以获得一些答案。我发现了以下内容(在版本 7.0.0 和 7.39.0 中):

在计算累积节点 PhreakAccumulateNode.doRightUpdates 更新的方法中,就在方法 doRightUpdatesProcessChildren 之前(用于左右元组之间的匹配),存在以下代码:

// if LeftTupleMemory is empty, there are no matches to modify
if ( leftTuple != null ) {
   if ( leftTuple.getStagedType() == LeftTuple.NONE ) {
         trgLeftTuples.addUpdate( leftTuple ); //<----
   }
   doRightUpdatesProcessChildren( ARGS );
}

基于此,无论内存中的元组是否存在匹配,如果作为累加一部分的事实有更新,则第一个左元组(在本例中为 User5)将始终被视为正在匹配。

我查看了另一个测试节点JoinNode。该节点的代码类似于 AccumulateNode ,但是它缺少第一个左元组的附加更新,使我相信它是意外添加的,并且没有理由存在。

我的说法正确吗?

关于口水累积正在更新一个不相关的事实,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62705527/

相关文章:

java - Drools - 从具有不同事实的多个 DRL 文件中触发多个规则

java - 决策树和规则引擎 (Drools)

java - 流口水最好成绩为空

java - Drools 中的 `Unable to find class` 错误

tomcat - 我在使用 Drools 和 Tomcat 6 重新部署应用程序时遇到问题

java - 在 Drools 中检查 map 中的特定元素

java - 比较 JBoss Drools 中同一类的对象

java - Drools 返回规则列表

java - 当具有包含无限循环的函数(监视器)时如何在 Drools 中触发规则?

java - Drools 日志记录低于配置级别