Drools:基于PHREAK堆栈的评估和向后链接

前一段时间,我写了一篇有关我们新算法的博客: http : //blog.athico.com/2013/11/rip-rete-time-to-get-phreaky.html

有人问我有关新的基于堆栈的系统以及向后链接如何工作的信息。 我在电子邮件中回复了他们,但我认为其他人可能会发现它很有用,因此请将其粘贴在下面。 它是从我的大脑直接写到页面上的,因此在某些地方有点粗糙。 但我希望有人觉得它有用,无论如何。

-

评估规则时,它将从根到尖端进行评估。

对于每个节点,它评估所有可能的联接并生成一个元组集。 然后,该子元组集将传递到子节点。 传入的元组集称为srcTupleSet(用于变量名),然后将所有子级放入trgTupleSet中。 trgTupleSet传递到子节点,在此它成为srcTupleSet。

第245行显示了此循环: https : //github.com/droolsjbpm/drools/blob/master/drools-core/src/main/java/org/drools/core/phreak/RuleNetworkEvaluator.java#L245

srcTuples = trgTuples; // previous target, is now the source

输入节点后,它具有许多评估该节点所需的变量。 节点ID,节点内存,段内存,srcTupleSet,trgTupleSet。 通过创建引用这些值的StackEntry,可以暂停和恢复任何节点(在稍后的时间进行评估)。 StackEntry放置在堆栈上。 这是StackEntry类: https : //github.com/droolsjbpm/drools/blob/master/drools-core/src/main/java/org/drools/core/phreak/StackEntry.java

出于两个原因需要这样做,即反向链接和子网。 向后链接是通过查询节点完成的。

当传播到达查询节点时,它需要暂停对当前规则的评估-因此它创建了StackEntry并将其放置在堆栈中。

第459行: https : //github.com/droolsjbpm/drools/blob/master/drools-core/src/main/java/org/drools/core/phreak/RuleNetworkEvaluator.java#L459

查询只是没有RHS的规则,没有后果。 它收集到达终端节点的所有结果,并将其返回给调用方。 查询节点允许规则通过传入参数来调用查询。 通过插入DroolsQuery对象来完成查询,该对象与根模式匹配并触发传播:

参见第67行: https : //github.com/droolsjbpm/drools/blob/master/drools-core/src/main/java/org/drools/core/phreak/PhreakQueryNode.java

LeftInputAdapterNode.doInsertObject(handle, pCtx, lian, wm, lm, false, dquery.isOpen());

像序言一样,参数可以绑定或不绑定。 绑定参数是一个固定变量,而未绑定参数是一个固定变量。 在实现方面,我们不对未绑定的参数施加约束。 这允许经典的序言“传递闭包”类型查询。 虽然规则可以调用查询,但是查询也可以调用查询(我们没有制表法来检测无限循环)。

query isContainedIn( String x, String y )
  Location( x, y; )
  or
  ( Location( z, y; ) and isContainedIn( x, z; ) )
end

注意drools支持模式中的位置参数和空位参数。 这是通过将所有位置映射到插槽来完成的。

可在此处找到有关反应式和非反应式传递闭包的上述查询的逐步操作指南, 网址为https : //www.youtube.com/watch?v=fCjIRVSRFvA

对于评估查询,当trgTulupleSet到达终端节点时,它将迭代并将每个元组添加到“收集器”。

参见第65行: https : //github.com/droolsjbpm/drools/blob/master/drools-core/src/main/java/org/drools/core/phreak/PhreakQueryTerminalNode.java#L65

收集器创建一个特殊的子元组,可以将其添加到调用父级。

参见第343行: https : //github.com/droolsjbpm/drools/blob/master/drools-core/src/main/java/org/drools/core/reteoo/QueryElementNode.java#L343

查询完成评估后,将返回。 然后,重新调整过程允许执行程序访问堆栈,并在其中弹出StackEntry并恢复评估-但现在查询结果可用。

参见第166和173行: https : //github.com/droolsjbpm/drools/blob/master/drools-core/src/main/java/org/drools/core/phreak/RuleNetworkEvaluator.java

可以反应性和非反应性地调用查询。 非反应式意味着没有剩余内存,查询也没有打开。 反应性地意味着有剩余的内存,查询保持打开状态。 反应式查询是完全增量式的,并且支持更新和删除:

参见143和169行: https : //github.com/droolsjbpm/drools/blob/master/drools-core/src/main/java/org/drools/core/phreak/PhreakQueryNode.java#L143

我们用于元组和“嵌套”(查询结果)元组的数据结构高效且“无复制”和“无搜索” –都是双链表。 这对于使增量查询有效很有必要。

子网使用类似的技术。 在到达子网的点上,外部规则被挂起(放在堆栈上),并创建内部网络评估。

参见第593和604行: https : //github.com/droolsjbpm/drools/blob/master/drools-core/src/main/java/org/drools/core/phreak/RuleNetworkEvaluator.java

子网完成后,外部规则将恢复并将结果放入外部子节点的正确输入中:

第662行: https : //github.com/droolsjbpm/drools/blob/master/drools-core/src/main/java/org/drools/core/phreak/RuleNetworkEvaluator.java#L662

如前所述,当前我们提供惰性规则评估,但不提供增量规则评估。 一旦开始规则评估,就会生成所有元组。 但是,由于堆栈条目可以在任何节点中暂停和恢复,因此它也可以用于提供增量规则评估-尽管我们现在不这样做。 实际上,您在正确的输入上“获取”了X个对象-可以是1或5或25或100。该数量使您可以调整延迟与吞吐量。 如果仍然有未评估的正确输入,请创建一个StackEntry,以在当前传播完成后强制对该节点进行重新评估。


翻译自: https://www.javacodegeeks.com/2014/01/drools-phreak-stack-based-evaluations-and-backward-chaining.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值