专家/规则引擎以原子方式更新事实?

时间:2013-12-06 21:53:18

标签: drools rule-engine expert-system

原子上可能不是正确的词。在对细胞自动机或神经网络进行建模时,通常会有两个系统状态副本。一个是当前状态,一个是您正在更新的下一步的状态。这确保了在运行所有规则以确定下一步骤时系统整体状态保持不变的一致性。例如,如果您运行一个单元格/神经元的规则以确定下一步的状态,则运行下一个单元格的规则,它的邻居,您要将这些规则的输入用作当前状态相邻单元格,而不是其更新状态。

由于每个步骤都要求您在更新它们之前将所有当前步骤状态复制到下一步状态这一事实,这似乎效率低下,但重要的是要这样做以准确模拟系统,就像所有细胞/神经元一样实际上是同时处理的,因此规则/触发功能的所有输入都是当前状态。

在为专家系统设计规则时困扰我的是一个规则如何运行,更新一些应该触发其他规则运行的事实,并且您可能有100个排队等待运行的规则作为响应,但是使用了突出性作为一种脆弱的方式来确保真正重要的运行首先。随着这些规则的运行,系统会发生更多变化。事实的状态一直在变化,因此当您处理第100条规则时,系统的状态自从它真正响应第一个事实更改时添加到队列的时间以来发生了显着变化。它可能已经发生了巨大的变化,以至于规则没有机会对系统的原始状态作出反应。通常作为一种解决方法,你仔细调整它的显着性,然后将其他规则移到列表中,你会遇到鸡或蛋的问题。其他解决方法涉及添加“处理标志”事实,这些事实充当锁定机制以抑制某些规则,直到其他规则处理。这些都感觉像黑客,并导致规则包括超出核心域模型的标准。

如果您构建了一个真正复杂的系统来准确地建模问题,那么您真的希望将事实的更改转移到单独的“更新”队列,该队列在规则队列为空之前不会影响当前事实。因此,假设您做了一个事实更改,填充规则队列以运行100个规则。所有这些规则都会运行,但它们都不会更新当前事实列表中的事实,它们所做的任何更改都会排队到更改列表,并确保在当前批处理时不会激活其他规则。处理完所有规则后,事实更改将立即应用于当前事实列表,然后触发更多要激活的规则。冲洗重复。因此它变得非常像神经网络或细胞自动机的处理方式。 针对不变的当前状态运行所有规则,队列更改,在运行所有规则后将更改应用于当前状态。

这种操作模式是否存在于专家系统学术界?我想知道是否有一个术语。

Drools是否能够以允许所有规则运行而不影响当前事实的方式运行,并且在所有规则运行之前单独更改事实?如果是这样,怎么做?我不希望你为我编写代码,只是在API中调用它的一些关键字或关键字,这是帮助我搜索的一些起点。

是否有其他专家/规则引擎具备此功能?

请注意,在这种情况下,订单规则不再重要,因为排队等待运行的所有规则都将只看到当前状态。因此,当运行和清除规则队列时,没有规则看到其他规则正在进行的任何更改,因为它们都是针对当前事实集运行的。 因此,顺序变得无关紧要,并且管理规则执行顺序的复杂性消失。所有事实更改都处于暂挂状态,并且在从队列中清除所有规则之前不会应用于当前状态。然后立即应用所有这些更改,从而导致相关规则再次排队。因此,我的目标不是更多地控制规则的运行顺序,而是通过使用模拟同时执行规则的引擎完全避免规则执行顺序的问题。

2 个答案:

答案 0 :(得分:2)

如果我理解你的描述:

  • 您有一个由许多规则管理的事实
  • 每条规则都应适用于您事实的初始值,无权修改事实值(不修改其他规则的执行)
  • 然后批量处理规则所做的所有更新
  • 其他规则以类似的方式“同时”适用于此新事实值

在我看来,它就像一个工作单元设计模式,就像Hibernate实现它一样(事实上还有许多ORM):http://www.codeproject.com/Articles/581487/Unit-of-Work-Design-Pattern

基本上你在内存中存储所有的更改(例如在'技术'事实中),然后在基于初始值的所有规则被触发以更新事实值时执行'事务',依此类推。 Hibernate通过其会话执行此操作(您修改附加对象,然后在需要时它在数据库上执行更新查询,而不是对java对象的所有修改都会在您的数据库上生成查询)。

如果更新发生冲突(相同的事实字段值已修改,选择哪个值?与源版本控制冲突相同),您仍然会遇到麻烦,您必须定义一种确定主义方式来订购更新,但它只会被定义一旦可用于所有规则和其他更改,它将无缝地工作。

答案 1 :(得分:1)

根据您的相当含糊的描述,此工作可能会/可能不会起作用。如果您真的担心触发进一步激活的规则,为什么不自己排队中间状态。一旦当前评估完成,将这些新事实插入工作记忆中。

在插入每个事实之后你必须调用fireAllRules(),这可能非常昂贵。然后在规则中,而不是直接插入事实,将这些推入队列。一旦上述调用返回,请执行相同的队列(或完全插入原始事实后...)

我认为这将会非常缓慢,加速,您可以使用相同的规则拥有多个并行的工作记忆,并将多个事实评估为多个队列等等。但是事情变得非常毛茸茸......

无论如何,这个想法对于评论来说太长了......