在 lhs 和 rhs 中流口水不同的变量值

如何解决在 lhs 和 rhs 中流口水不同的变量值

我有两个规则

rule "test1"
    when
        $cr: MyContext(flag1 == 1)
    then
        System.out.println("<---- Test1 start ---->");
        $cr.setFlag1(10);
        System.out.println("<---- Test1 end ---->");
    end
rule "test2" salience -1
    when
        $cr: MyContext($flag1: flag1 == 1)
    then
        System.out.println("<---- Test2 start ---->");
        System.out.println($flag1);
        System.out.println("<---- Test2 end ---->");
    end

I rule1,我正在检查变量 MyContext.flag1 是否为 1。既然是这样,我将其更改为 10。 我 rule2,我正在检查变量 MyContext.flag1 是否为 1。 我没想到这条规则会在 flag1 为 10 时执行。

但令人惊讶的是,它执行并打印 flag1 为 10。

它如何在 rule2 的 LHS 中将 flag1 == 1 评估为真,而在 RHS 中将 flag1 打印为 10?

解决方法

最初,Drools 评估必须根据您工作记忆中的事实来触发两个规则。因此,要解雇的规则的议程是(根据您的显着性):

  • 等待触发的规则“test1”......
  • 等待触发的规则“test2”......

你错过的是,如果你不这么说 Drools,议程就不会被修改。 在您的情况下,规则“test1”被触发,然后从议程中删除,议程的新状态是:

  • 等待触发的规则“test2”......

那么接下来会发生什么,规则“test2”被触发,因为你改变了你的事实,drools 打印它的新值,即 10。所以行为是好的。

您需要的是在规则“test1”中修改后调用 update($cr),这意味着:根据我的事实 $cr 使用所有规则更新议程。 结果是 Drools 现在将从其议程中删除规则“test2”。

,

当您触发 drools 规则时,框架会在工作内存中获取您的规则输入并确定哪些规则匹配。然后对这些规则匹配进行排序(按显着性或自然顺序),然​​后按顺序触发。

因此,当您触发规则时,“test1”和“test2”被确定为匹配项。然后 Drools 继续首先触发“test1”,然后是“test2”。

如果你想让 Drools 重新评估规则匹配,你需要“告诉”框架你已经对工作内存进行了更改。为此,您有以下内置方法:

方法 说明
insert 将一个新事实放入工作记忆中。
deleteretract 从工作内存中删除一些信息(对象)。
update 更新/替换工作记忆中的一个事实。
modify 更改工作记忆中事实中的字段。

这些方法还有一些“逻辑”版本,您可以在 Drools documentation 中阅读更多相关信息。

如果您在进行更改时或之后使用这些内置框架方法,您将继续评估初始规则匹配集。这些变化实际上对 drools 来说是不可见的,因为你没有告诉 Drools “嘿,我们已经做出了改变”。每个规则的左侧都根据原始数据集进行了评估;根据匹配顺序对右侧进行评估。

因此,在您的情况下,您想要做的是使用 modify 函数告诉 Drools 您正在对工作记忆中的一条信息进行更改。

rule "test1"
when
  $cr: MyContext(flag1 == 1)
then
  modify( $cr ) {
    setFlag1(10)
  }
end

需要注意的一件事是如何评估规则匹配。当您调用 insert 将新数据放入工作内存时,Drools 将对规则匹配进行部分重新评估。已经匹配并执行过的规则不会再次运行;仅重新评估后续规则以确定它们现在是否匹配。

相反,update 将对所有规则进行全面评估。它的功能等同于停止当前规则执行并使用工作内存中的新数据调用 fireAllRules

如果您的规则具有外部副作用或不是幂等的,则调用 update 可能会产生严重的副作用,因为随着数据的变化,您可能会多次评估规则的 RHS。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?