流口水的法则在不应该维持状态和解雇规则的情况下

如何解决流口水的法则在不应该维持状态和解雇规则的情况下

我遇到了一个问题,即规则不更新状态并在不应该触发时触发,我只希望规则在两个开关都打开时才触发。

For example:

In the following order I

open switcha
close switcha
open switchb 

在不应该关闭switcha时触发规则。尽快出现 Switch(name ==“ switcha”,status ==“ Open)变为true,即使再次关闭开关也保持此状态。

rule "Electrical Circuit Status"
  when
    Switch( name == "switcha",status == "Open" )
and
    Switch( name == "switchb",status == "Open" )

  then   // Raise Alert

 ** Didn't write this code out as it works fine

end

感谢您的帮助。

解决方法

您可能会误解工作记忆状态。但是,由于您的问题对细节的要求极低,因此我将在解释中做出几个假设,这些假设将在下面列出。

假设我们有两个处于以下状态的开关:

  • Switch( name == "switcha",status == "Closed")
  • Switch( name == "switchb",status == "Closed")

我们将这些开关原样传递到我们的规则中。

当我们在云模式下运行时,规则是在时间的瞬间而不是在一段时间内执行的(这将是流模式)。云模式是默认模式,也是大多数应用程序利用的模式。由于您没有提及事件流,因此我将假设您正在此模式下运行。 (如果您不知道我在说什么,那么您也可能会在Cloud模式下运行; Stream模式是一个相对较新的功能。)我还将承担一个有状态的会话。

当我们调用fireAllRules时,Drools将查看规则输入并找出哪些规则具有与这些条件匹配的条件。将使用该规则的子集,根据显着性和自然顺序找出它们的顺序,然后执行它们。

在执行这些规则时,您可以通过多种方式修改规则输入。

  • 致电insert。这将新事实添加到工作记忆中。
  • 致电modify。这将更改现有的事实数据。
  • 致电update。这也会更改现有的事实数据。
  • 直接更改对象上的数据,例如通过getter或setter。

取决于更改数据的方式,这可能会或可能不会更改规则的评估方式。

如果您直接更改数据(例如,通过getter或setter更改),则不会对规则进行任何重新评估。任何更改在功能上对于Drools引擎都是“不可见的”。即使条件不再成立,仍会触发最初被识别为匹配的规则,因为您更新数据的方式不会导致Drools重新评估这些条件。

如果您致电update ,Drools将重新评估整个规则范围。这在功能上等同于更改数据,然后从顶部再次重新定义规则。 Drools将使用工作内存中的新数据查看所有规则,并重做收集匹配,排序和触发它们的过程。使用update调用很容易进入“循环”状态。

如果您调用insert ,则是将新的数据添加到工作存储器中。 Drools将对规则进行部分重新评估,以确定是否有符合条件的新规则可以触发,或者以前的匹配项现在是否无效。它不会重新触发以前匹配并被触发的任何规则。同样,如果您调用modify ,则会以某种方式更改现有规则输入对象的属性,因此Drools将根据更改的条件部分重新评估。

(这已简化。您可以通过阅读源代码或文档来了解有关细微差别的更多信息。)

由于您只显示了一条局部规则,并且只说即使在“再次关闭开关时”也会触发,尽管没有说明关闭开关的方式,所以我可以提出几种可能的方法根据前面关于如何在有(或没有)重新评估规则条件的情况下更改数据的解释触发此条件。

例如,如果通过调用setStatus("Closed")方法而不是通过使用modify来更改开关状态,则规则将不知道新状态。

rule "change switch state invisibly"
when
  // some conditions
  $b: Switch( name == "switchb",status == "Open" )
then
  $b.setStatus("Closed"); 
end

rule "Electrical Circuit Status"
  Switch( name == "switcha",status == "Open" ) // let's assume this is true
  Switch( name == "switchb",status == "Open" ) // Also still true!
then
  // show alert
end

由于您使用setStatus而不是modify来更改状态,因此Drools不会重新评估后续的规则匹配,而是保留先前的匹配。因此条件仍然成立。

要解决此问题,在更改后,您应该使用modify或(建议不要使用)update的工作记忆(但要理解,将重新评估所有 规则) )

modify ($b) {
  setStatus("Closed")
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 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元字符(。)和普通点?