POJO Object Models for Blocks World Example

return this.name; } public void setNameString name { this.name = name; } public String getOnTopOf { return this.onTopOf; } public void setOnTopOfString onTopOf { this.onTopOf = onTopOf; } public String getSupporting { return this.supporting; } public void setSupportingString supporting { this.supporting = supporting; } } The next POJO class OldBlockState is used to represent previous states of blocks as they are being moved as the rules in this example “fire.” We will later see rules that will not put a block into a state that it previously existed in: public static class OldBlockState extends Block { public OldBlockStateString name, String onTopOf, String supporting { supername, onTopOf, supporting; } public String toString { return [OldBlockState_ + this.hashCode + + name + on top of: + onTopOf + supporting: + supporting+]; } } The next POJO class Goal is used to represent a goal state for the blocks that we are trying to reach: public static class Goal { 83 A B C Figure 5.4: Block B has been removed from block A and placed on the table. private String supportingBlock; private String supportedBlock; public GoalString supporting, String supported { this.supportingBlock = supporting; this.supportedBlock = supported; } public String toString { return [Goal_ + this.hashCode + Goal: supporting block: + supportingBlock + and supported block: + supportedBlock +]; } public void setSupportingBlock String supportingBlock { this.supportingBlock = supportingBlock; } public String getSupportingBlock { return supportingBlock; } public void setSupportedBlock String supportedBlock { this.supportedBlock = supportedBlock; } public String getSupportedBlock { return supportedBlock; } } Each block object has three string attributes: a name, the name of the block that this block is on top of, and the block that this block supports is under. We will also define a block instance with the name “table.” We need the POJO class OldBlockState that is a subclass of Block to avoid cycles in the reasoning process. 84 A B C Figure 5.5: The goal is solved by placing block C on top of block A.

5.4.2 Drools Rules for Blocks World Example

We need four rules for this example and they are listed below with comments as appropriate: package com.markwatson.examples.drool import com.markwatson.examples.drool.DroolsBlockWorld .Goal; import com.markwatson.examples.drool.DroolsBlockWorld .Block; import com.markwatson.examples.drool.DroolsBlockWorld .OldBlockState; We place the rules in the same Java package as the Java support code seen in the next section and the POJO model classes that we saw in the last section. The first rule has no preconditions so it can always fire. We use the special rule condition “no-loop true” to let the Drools system know that we only want this rule to fire one time. This rule inserts facts into working memory for the simple problem seen in Figures 5.2 through 5.5: rule Startup Rule no-loop true when then insertnew GoalC, B; test 1 insertnew GoalC, A; test 2 BlockString name, String onTopOf, String supporting insertnew BlockA, table, B; insertnew BlockB, A, C; insertnew BlockC, B, ; insertnew BlockD, , ; 85 insertnew Blocktable, , A; end The following rule looks for situations where it is possible to move a block with a few conditions: • Find a block block 1 that is on top of another block and is not itself supporting any other blocks • Find a second block block 2 that is not block 1 and is not itself supporting any other blocks • Find the block on top of 1 that is under block 2 and supporting block 1 • Make sure that no previous block with the name in the variable block 2 has already been on top of block on top of 2 and supporting block 1 If these conditions are met, we can remove the three matching facts and create facts for the new block positions and a new OldBlockState fact in working memory. Note that the fourth LHS matching pattern is prefixed with “not” so this matches if there are no objects in working memory that match this pattern: rule Set Block On: move block_1 to block_2 when fact1 : Blockblock_1 : name, on_top_of_1 : onTopOf = , supporting == fact2 : Blockblock_2 : name = block_1, on_top_of_2 : onTopOf = , supporting == fact3 : Blockname == on_top_of_1, on_top_of_3 : onTopOf, supporting == block_1 not OldBlockStatename == block_2, onTopOf == on_top_of_2, supporting == block_1 then System.out.println fact1 ; System.out.println fact2 ; System.out.println fact3 ; retractfact1; retractfact2; retractfact3; insertnew Blockblock_1, block_2, ; insertnew Blockblock_2, on_top_of_2, 86