21.9. Conways of Life example decisions(ruleflow 组和 GUI 集成)
Conwayss Game of Life example 决策集,按照 John Conway 的 advertise cellular automaton,演示如何使用 ruleflow 组来控制规则执行。这个示例还演示了如何将 Red Hat Process Automation Manager 规则与图形用户界面(GUI)集成,在这种情况下,基于 Swing 的实施是生命周期。
以下是生命周期游戏(Conway)示例概述:
-
名称 :
conway
-
主要类别 :
org.drools.examples.conway.ConwayRuleFlowGroupRun
,org.drools.examples.conway.Conway.Conway.ConwayAgendaGroupRun
(insrc/main/java
) -
模块:
droolsjbpm-integration-examples
- 键入: Java 应用程序
-
规则文件 :
org.drools.examples.conway.*.drl
(在src/main/resources
) - 目标 :演示 ruleflow 组和 GUI 集成
生命周期示例的 Conway's Game 与 Red Hat Process Automation Manager 中的大多数其他示例决策集分开,并位于来自红帽客户门户网站的 ~/rhpam-7.13.5-sources/src/droolsjbpm-integration-$VERSION/droolsjbpm-integration-examples
,它包括了来自红帽 客户门户网站的 Red Hat Process Automation Manager 7.13.5 -sources/src/droolsjbpm-integration-examples。
在 Conway 的游戏中,用户通过创建初始配置或具有定义的属性的高级模式来与游戏进行交互,然后观察初始状态的演变方式。游戏旨在展示人们的开发,生成生成。根据所有单元的同步评估,来自前一个结果的生成结果。
以下基本规则管理下一代内容:
- 如果实时单元单元少于两个实时邻居,它会断出一个词子。
- 如果实时单元单元有超过 3 个实时邻居,它将从过度浏览。
- 如果一个死的单元只有 3 个实时邻居,它会进入生命期。
任何不符合这些条件的单元都会被保留为生成下一个。
Conways of Life 示例游戏使用带有 ruleflow-group
属性的 Red Hat Process Automation Manager 规则来定义在游戏中实施的模式。示例还包括一个决策集版本,通过日程安排组实现相同的行为。日程表组使您可以对决策引擎日程表进行分区,以便对规则组提供执行控制。默认情况下,所有规则均位于 MAIN
日程小组。您可以使用 schedule -group
属性来指定该规则的不同日程表组。
此概述不使用日程表组探索 Conway 示例的版本。有关日程表组的更多信息,请参阅 Red Hat Process Automation Manager 示例决策集,其具体处理日程表组。
沟通执行和互动示例
与其他 Red Hat Process Automation Manager 决策示例类似,您可以通过运行 org.drools.examples.conway.ConwayRuleFlowGroupRun
类作为 IDE 中的 Java 应用程序来执行 Conway 规则流示例。
当您执行 Conway 示例时,会出现 Life ways Game of Life
GUI 窗口的 Game。此窗口包含空网格,或"arena",其中将进行模拟。网格最初为空,因为还没有在系统中提供实时单元。
图 21.24. 启动后继续 GUI 示例
从 Pattern 下拉菜单中选择预定义的模式,再单击 Next Generation 以单击每个填充生成。每个单元都可以处于活动状态或死的,其中 live cells 包含一个绿色的 ball。随着人们从初始模式演进,根据游戏的规则,与邻座单元相关的单元格或相对于邻居单元的划分。
图 21.25. 在 Conway 示例中生成演进
邻居不仅包括左、右、顶部和下部的单元格,这些单元格是连接的单位,因此每个单元总数为 8 个邻居。例外是基格(仅有三个邻居),以及这四个边的单元格,分别是五个邻居。
您可以通过单击单元格来手动干预来创建或终止单元。
要从初始模式自动通过 evolution 运行,请单击 Start。
使用 ruleflow 组验证规则示例
ConwayRuleFlowGroupRun
示例中的规则使用 ruleflow 组来控制规则执行。ruleflow group 是 rule flow-group rule
属性关联的一组规则。这些规则只能在激活组时触发。只有当 ruleflow 图的协作达到代表组的节点时,组本身才会变为活跃状态。
Conway 示例对规则使用以下 ruleflow 组:
-
"注册邻居"
-
"评估"
-
"calculate"
-
"重置计算"
-
"birth"
-
"kill"
-
"全部技能"
所有 Cell
对象都插入到 KIE 会话中,ruleflow 组中允许
规则由 ruleflow 进程执行。这一组四个规则可在某些单元及其 northeastern、northern、northwestern 和 western 邻居之间创建邻居关系。"register …"
这种关系是双向的,可以处理其他四个方向。Border 单元不需要任何特殊处理。这些单元不会与邻居单元(没有任何)搭配使用。
通过为所有规则触发了所有激活的时间,所有单元格都与其所有邻居单元相关。
规则 "register …"
rule "register north east" ruleflow-group "register neighbor" when $cell: Cell( $row : row, $col : col ) $northEast : Cell( row == ($row - 1), col == ( $col + 1 ) ) then insert( new Neighbor( $cell, $northEast ) ); insert( new Neighbor( $northEast, $cell ) ); end rule "register north" ruleflow-group "register neighbor" when $cell: Cell( $row : row, $col : col ) $north : Cell( row == ($row - 1), col == $col ) then insert( new Neighbor( $cell, $north ) ); insert( new Neighbor( $north, $cell ) ); end rule "register north west" ruleflow-group "register neighbor" when $cell: Cell( $row : row, $col : col ) $northWest : Cell( row == ($row - 1), col == ( $col - 1 ) ) then insert( new Neighbor( $cell, $northWest ) ); insert( new Neighbor( $northWest, $cell ) ); end rule "register west" ruleflow-group "register neighbor" when $cell: Cell( $row : row, $col : col ) $west : Cell( row == $row, col == ( $col - 1 ) ) then insert( new Neighbor( $cell, $west ) ); insert( new Neighbor( $west, $cell ) ); end
插入所有单元格后,一些 Java 代码会将模式应用到网格,将某些单元设置为 Live
。然后,当用户点击 Start 或 Next Generation 时,该示例执行 Generation
ruleflow。此 ruleflow 管理每个生成周期中的所有单元更改。
图 21.26. 生成规则流
ruleflow 进程进入 "evaluate"
ruleflow 组,以及组中的任何活动规则可以触发。这个组中的规则 "Kill the …"
和 "Give Birth"
将规则规则应用到 birth 或 kill 单元。这个示例使用 phase
属性来根据特定规则组驱动 Cell
对象的原因。通常,该阶段与 ruleflow 进程定义中的 ruleflow 组关联。
请注意,该示例不会更改此时任何 Cell
对象的状态,因为它必须在应用这些更改前完成完整的评估。示例将单元设置为 Phase.KILL
或 Phase.BIRTH
,后者稍后用于控制应用到 Cell
对象的操作。
规则"Kill the …" 和 "Give Birth"
rule "Kill The Lonely" ruleflow-group "evaluate" no-loop when // A live cell has fewer than 2 live neighbors. theCell: Cell( liveNeighbors < 2, cellState == CellState.LIVE, phase == Phase.EVALUATE ) then modify( theCell ){ setPhase( Phase.KILL ); } end rule "Kill The Overcrowded" ruleflow-group "evaluate" no-loop when // A live cell has more than 3 live neighbors. theCell: Cell( liveNeighbors > 3, cellState == CellState.LIVE, phase == Phase.EVALUATE ) then modify( theCell ){ setPhase( Phase.KILL ); } end rule "Give Birth" ruleflow-group "evaluate" no-loop when // A dead cell has 3 live neighbors. theCell: Cell( liveNeighbors == 3, cellState == CellState.DEAD, phase == Phase.EVALUATE ) then modify( theCell ){ theCell.setPhase( Phase.BIRTH ); } end
评估了网格中的所有 Cell
对象后,该示例使用 "reset calculate"
规则清除 "calculate"
ruleflow 组中的任何激活。然后,如果 ruleflow 激活了 ruleflow,示例将启用规则 "kill"
和 "birth"
来触发的规则。这些规则应用状态更改。
规则"重置计算"、"kill"和"birth"
rule "reset calculate" ruleflow-group "reset calculate" when then WorkingMemory wm = drools.getWorkingMemory(); wm.clearRuleFlowGroup( "calculate" ); end rule "kill" ruleflow-group "kill" no-loop when theCell: Cell( phase == Phase.KILL ) then modify( theCell ){ setCellState( CellState.DEAD ), setPhase( Phase.DONE ); } end rule "birth" ruleflow-group "birth" no-loop when theCell: Cell( phase == Phase.BIRTH ) then modify( theCell ){ setCellState( CellState.LIVE ), setPhase( Phase.DONE ); } end
在这个阶段,几个 Cell
对象已被修改,其状态会更改为 LIVE
或 DEAD
。当单元变为 live 或 dead 时,示例使用规则 "Calculate …"
中的邻居关系来迭代所有周围的单元格,从而增加或减少 liveNeighbor
计数。任何改变计数的单元也会设置为
EVALUATE
阶段,以确保它在 ruleflow 过程的评估阶段包含在原因中。
在为所有单元确定和设置实时数后,ruleflow 进程结束。如果用户最初点击 Start,则决策引擎在该处重启规则流。如果用户最初单击 下一步生成,用户可以请求另一个生成。
规则"Calculate …"
rule "Calculate Live" ruleflow-group "calculate" lock-on-active when theCell: Cell( cellState == CellState.LIVE ) Neighbor( cell == theCell, $neighbor : neighbor ) then modify( $neighbor ){ setLiveNeighbors( $neighbor.getLiveNeighbors() + 1 ), setPhase( Phase.EVALUATE ); } end rule "Calculate Dead" ruleflow-group "calculate" lock-on-active when theCell: Cell( cellState == CellState.DEAD ) Neighbor( cell == theCell, $neighbor : neighbor ) then modify( $neighbor ){ setLiveNeighbors( $neighbor.getLiveNeighbors() - 1 ), setPhase( Phase.EVALUATE ); } end