[jboss-svn-commits] JBL Code SVN: r34176 - in labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US: images/Chapter-Examples and 1 other directory.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Jul 26 07:35:42 EDT 2010


Author: ge0ffrey
Date: 2010-07-26 07:35:41 -0400 (Mon, 26 Jul 2010)
New Revision: 34176

Added:
   labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-SudokuExample.xml
   labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/images/Chapter-Examples/SudokuExample/
Removed:
   labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-SodukiExample.xml
   labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/images/Chapter-Examples/SodukiExample/
Modified:
   labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Chapter-Examples.xml
Log:
typo: Soduki must be Sudoku

Modified: labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Chapter-Examples.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Chapter-Examples.xml	2010-07-26 11:30:49 UTC (rev 34175)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Chapter-Examples.xml	2010-07-26 11:35:41 UTC (rev 34176)
@@ -27,7 +27,7 @@
 	<xi:include href="Section-PricingExample.xml" />
 	<xi:include href="Section-PetStoreExample.xml" />
 	<xi:include href="Section-HonestPoliticianExample.xml" />
-	<xi:include href="Section-SodukiExample.xml" />
+	<xi:include href="Section-SudokuExample.xml" />
 	<xi:include href="Section-NumberGuessExample.xml" />
 	<xi:include href="Section-MannersExample.xml" />
 	<xi:include href="Section-ConwaysGameOfLifeExample.xml" />

Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-SodukiExample.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-SodukiExample.xml	2010-07-26 11:30:49 UTC (rev 34175)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-SodukiExample.xml	2010-07-26 11:35:41 UTC (rev 34176)
@@ -1,481 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<section version="5.0"
-         xsi:schemaLocation="http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd"
-         xml:base="../" xmlns="http://docbook.org/ns/docbook" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink"
-         xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:ns="http://docbook.org/ns/docbook">
-    <title>Sudoku Example</title>
-
-    <programlisting><emphasis role="bold">Name:</emphasis> Sudoku
-<emphasis role="bold">Main class:</emphasis> org.drools.examples.sudoku.Main
-<emphasis role="bold">Type:</emphasis> Java application
-<emphasis role="bold">Rules file:</emphasis> sudokuSolver.drl, sudokuValidator.drl
-<emphasis role="bold">Objective:</emphasis> Demonstrates the solving of logic problems, and complex pattern matching.
-</programlisting>
-
-    <para>This example demonstrates how Drools can be used to find a solution
-    in a large potential solution space based on a number of constraints. We
-    use the popular puzzle of Sudoku. This example also shows how Drools can
-    be integrated into a graphical interface and how callbacks can be used to
-    interact with a running Drools rules engine in order to update the
-    graphical interface based on changes in the Working Memory at
-    runtime.</para>
-
-    <section>
-      <title>Sudoku Overview</title>
-
-      <para>Sudoku is a logic-based number placement puzzle. The objective is
-      to fill a 9x9 grid so that each column, each row, and each of the nine
-      3x3 zones contains the digits from 1 to 9, once, and only once.</para>
-
-      <para>The puzzle setter provides a partially completed grid and the
-      puzzle solver's task is to complete the grid with these
-      constraints.</para>
-
-      <para>The general strategy to solve the problem is to ensure that when
-      you insert a new number it should be unique in its particular
-      3x3 zone, row and column.</para>
-
-      <para>See <link xlink:href="http://en.wikipedia.org/wiki/Sudoku">Wikipedia</link>
-      for a more detailed description.</para>
-    </section>
-
-    <section>
-      <title>Running the Example</title>
-
-      <para>Download and install drools-examples as described above and then
-      execute <filename>java org.drools.examples.sudoku.Main</filename>. This
-      example requires Java 5.</para>
-
-      <para>A window will be displayed with a relatively simple partially
-      filled grid. <screenshot>
-          <info>New remote site</info>
-
-          <mediaobject>
-            <imageobject>
-              <imagedata fileref="images/Chapter-Examples/SodukiExample/sudoku1.png" />
-            </imageobject>
-          </mediaobject>
-        </screenshot></para>
-
-      <para>Click on the "Solve" button and the Drools-based engine will fill
-      out the remaining values. The Console window will display detailed
-      information about the rules which are executing to solve the puzzle
-      in a human readable form.</para>
-
-      <para><screen>Rule #3 determined the value at (4,1) could not be 4 as this value already exists in the same column at (8,1)
-Rule #3 determined the value at (5,5) could not be 2 as this value already exists in the same row at (5,6)
-Rule #7 determined (3,5) is 2 as this is the only possible cell in the column that can have this value
-Rule #1 cleared the other PossibleCellValues for (3,5) as a ResolvedCellValue of 2 exists for this cell.
-Rule #1 cleared the other PossibleCellValues for (3,5) as a ResolvedCellValue of 2 exists for this cell.
-... 
-Rule #3 determined the value at (1,1) could not be 1 as this value already  exists in the same zone at (2,1)
-Rule #6 determined (1,7) is 1 as this is the only possible cell in the row that can have this value
-Rule #1 cleared the other PossibleCellValues for (1,7) as a ResolvedCellValue of 1 exists for this cell.
-Rule #6 determined (1,1) is 8 as this is the only possible cell in the row that can have this value</screen></para>
-
-      <para>Once all of the activated rules for the solving logic have
-      executed, the engine executes a second rule base to check that the
-      solution is complete and valid. In this case it is, and the "Solve"
-      button is disabled and displays a text like
-      <code>"Solved (1052ms)"</code>.<screenshot>
-          <info>New remote site</info>
-
-          <mediaobject>
-            <imageobject>
-              <imagedata fileref="images/Chapter-Examples/SodukiExample/sudoku2.png" />
-            </imageobject>
-          </mediaobject>
-        </screenshot></para>
-
-      <para>The example comes with a number of grids which can be loaded and
-      solved. Click on "File", then "Samples" and "Medium" to load a more
-      challenging grid. Note that the solve button is enabled when the new
-      grid is loaded.
-      <screenshot>
-          <info>New remote site</info>
-
-          <mediaobject>
-            <imageobject>
-              <imagedata fileref="images/Chapter-Examples/SodukiExample/sudoku3.png" />
-            </imageobject>
-          </mediaobject>
-        </screenshot></para>
-
-      <para>Click on the "Solve" button again to solve this new grid.
-      <screenshot>
-          <info>New remote site</info>
-
-          <mediaobject>
-            <imageobject>
-              <imagedata fileref="images/Chapter-Examples/SodukiExample/sudoku4.png" />
-            </imageobject>
-          </mediaobject>
-        </screenshot></para>
-
-      <para>Now, let us load a Sudoku grid that is deliberately invalid. Click
-      on "File", "Samples" and "!DELIBERATELY BROKEN!". Note that this grid
-      starts with some issues, for example the value 5 appears twice in the
-      first row.<screenshot>
-          <info>New remote site</info>
-
-          <mediaobject>
-            <imageobject>
-              <imagedata fileref="images/Chapter-Examples/SodukiExample/sudoku5.png" />
-            </imageobject>
-          </mediaobject>
-        </screenshot></para>
-
-      <para>Nevertheless, click on the "Solve" button to apply the solving
-      rules to this invalid grid. Note that the "Solve" button is relabelled
-      to indicate that the resulting solution is invalid. <screenshot>
-          <info>New remote site</info>
-
-          <mediaobject>
-            <imageobject>
-              <imagedata fileref="images/Chapter-Examples/SodukiExample/sudoku6.png" />
-            </imageobject>
-          </mediaobject>
-        </screenshot></para>
-
-      <para>In addition, the validation rule set outputs all of the issues
-      which are discovered to the console. <programlisting>
-There are two cells on the same column with the same value at (6,0) and (4,0)
-There are two cells on the same column with the same value at (4,0) and (6,0)
-There are two cells on the same row with the same value at (2,4) and (2,2)
-There are two cells on the same row with the same value at (2,2) and (2,4)
-There are two cells on the same row with the same value at (6,3) and (6,8)
-There are two cells on the same row with the same value at (6,8) and (6,3)
-There are two cells on the same column with the same value at (7,4) and (0,4)
-There are two cells on the same column with the same value at (0,4) and (7,4)
-There are two cells on the same row with the same value at (0,8) and (0,0)
-There are two cells on the same row with the same value at (0,0) and (0,8)
-There are two cells on the same column with the same value at (1,2) and (3,2)
-There are two cells on the same column with the same value at (3,2) and (1,2)
-There are two cells in the same zone with the same value at (6,3) and (7,3)
-There are two cells in the same zone with the same value at (7,3) and (6,3)
-There are two cells on the same column with the same value at (7,3) and (6,3)
-There are two cells on the same column with the same value at (6,3) and (7,3)</programlisting></para>
-
-      <para>We will look at the solving rule set later in this section, but
-      for the moment we should note that some theoretically solvable solutions
-      can not be solved by the engine as it stands. Click on
-      "File", "Samples" and then "Hard 3" to load a sparsely populated grid.
-      <screenshot>
-          <info>New remote site</info>
-
-          <mediaobject>
-            <imageobject>
-              <imagedata fileref="images/Chapter-Examples/SodukiExample/sudoku7.png" />
-            </imageobject>
-          </mediaobject>
-        </screenshot></para>
-
-      <para>Now click on the "Solve" button and note that the current rules
-      are unable to complete the grid, even though (if you are a Sudoku
-      aficionado) you may be able to see a way forward with the solution.
-      <screenshot>
-          <info>New remote site</info>
-
-          <mediaobject>
-            <imageobject>
-              <imagedata fileref="images/Chapter-Examples/SodukiExample/sudoku8.png" />
-            </imageobject>
-          </mediaobject>
-        </screenshot></para>
-
-      <para>At the present time, the solving functionality has been achieved
-      by the use of ten rules. This rule set could be extended to enable the
-      engine to tackle more complex logic for filling grids such as
-      this.</para>
-    </section>
-
-    <section>
-      <title>Java Source and Rules Overview</title>
-
-      <para>The Java source code can be found in the
-      /src/main/java/org/drools/examples/sudoku directory, with the two DRL
-      files defining the rules located in the
-      /src/main/rules/org/drools/examples/sudoku directory.</para>
-
-      <para>The package <code>org.drools.examples.sudoku.swing</code>
-      contains a set of classes which implement a framework for Sudoku
-      puzzles. Note that this package does not have any dependencies on
-      the Drools libraries. <code>SudokuGridModel</code>
-      defines an interface which can be implemented to store a Sudoku puzzle
-      as a 9x9 grid of <code>Integer</code> values, some of which may be null,
-      indicating that the value for the cell has not yet been resolved.
-      <code>SudokuGridView</code> is
-      a Swing component which can visualize any implementation of
-      <code>SudokuGridModel</code>. <code>SudokuGridEvent</code> and
-      <code>SudokuGridListener</code> are used to
-      communicate state changes between the model and the view: events are
-      fired when a cell's value is resolved or changed. If you are familiar
-      with the model-view-controller patterns in other Swing components such
-      as <code>JTable</code> then this pattern should be familiar.
-      <code>SudokuGridSamples</code> provides a number of partially filled
-      Sudoku puzzles for demonstration purposes.</para>
-
-      <para>Package <code>org.drools.examples.sudoku.rules</code> contains an
-      implementation of <code>SudokuGridModel</code> which is based on Drools.
-      Two Java objects are used, both of which extend
-      <code>AbstractCellValue</code> and represent a value for a specific cell
-      in the grid, including the row and column location of the cell, an index
-      of the 3x3 zone the cell is contained in, and the value of the cell.
-      <code>PossibleCellValue</code> indicates that we do not currently know
-      for sure what the value in a cell is. There can be from 2 to 9 possible
-      cell values for a given cell. <code>ResolvedCellValue</code> indicates 
-      that we have determined what the value
-      for a cell must be. There can only be one resolved cell value for a
-      given cell. <code>DroolsSudokuGridModel</code> implements
-      <code>SudokuGridModel</code> and is responsible for converting an
-      initial two dimensional array of partially specified cells into a set
-      of <code>CellValue</code> Java object, creating a Working Memory
-      based on <filename>solverSudoku.drl</filename> and inserting the
-      <code>CellValue</code> objects into the Working Memory. When the 
-      <code>solve()</code> method is called it calls in turn
-      <code>fireAllRules()</code> on this Working Memory to try to solve
-      the puzzle. <code>DroolsSudokuGridModel</code> attaches a 
-      <code>WorkingMemoryListener</code> to the Working Memory, which
-      allows it to be called back on insert and retract events as the
-      puzzle is solved. When a new <code>ResolvedCellValue</code> is inserted
-      into the Working Memory, this callback allows the implementation to
-      fire a <code>SudokuGridEvent</code> to its
-      <code>SudokuGridListener</code> clientele, which can then update
-      themselves in realtime. Once all the rules fired by the solver Working
-      Memory have executed, <code>DroolsSudokuGridModel</code> runs a
-      second set of rules, based on <filename>validatorSudoku.drl</filename>
-      which works with the same set of Java objects to determine whether the
-      resulting grid is a valid and a full solution.</para>
-
-      <para>The class <code>org.drools.examples.sudoku.Main</code> implements
-      a Java application combining the components desribed.</para>
-
-      <para>The packae <code>org.drools.examples.sudoku</code> contains two
-      DRL files. <filename>solverSudoku.drl</filename> defines the rules
-      which attempt to solve a Sudoku puzzle, and
-      <filename>validator.drl</filename> defines the rules which determin
-      whether the current state of the Working Memory represents a valid
-      solution. Both use <code>PossibleCellValue</code> and
-      <code>ResolvedCellValue</code> objects as their facts and
-      both output information to the Console window as their rules fire. In a
-      real-world situation we would insert logging information and use the
-      <code>WorkingMemoryListener</code> to display this information to a
-      user, rather than use the console in this fashion.</para>
-    </section>
-
-    <section>
-      <title>Sudoku Validator Rules (validatorSudoku.drl)</title>
-
-      <para>We start with the validator rules as this rule set is shorter and
-      simpler than the solver rule set.</para>
-
-      <para>The first rule simply checks that no <code>PossibleCellValue</code>
-      objects remain in the Working Memory. Once the puzzle is solved, only
-      <code>ResolvedCellValue</code> objects should be present, one for
-      each cell.</para>
-
-      <para>The other three rules each match all of the
-      <code>ResolvedCellValue</code> objects and bind them to the
-      variable <code>$resolved1</code>. They then look for
-      <code>ResolvedCellValues</code> that
-      contain the same value and are located, respectively, in the same row,
-      column, or 3x3 zone. If these rules are fired they add a message to a
-      global list of strings describing the reason the solution is invalid.
-      <code>DroolsSudokoGridModel</code> injects this list before it runs
-      the rule set and checks whether it is empty or not after having called
-      <code>fireAllRules()</code>. If it is not empty then it prints all the
-      strings in the list and sets a flag to indicate that the grid is not
-      solved.</para>
-    </section>
-
-    <section>
-      <title>Sudoku Solving Rules (solverSudoku.drl)</title>
-
-      <para>Now let us look at the more complex rule set used to solve Sudoku
-      puzzles.</para>
-
-      <para>Rule #1 is basically a book-keeping rule. Several of the other
-      rules insert <code>ResolvedCellValues</code> into the working memory
-      at specific rows and columns after they have determined that a given
-      cell must have a
-      certain value. At this point, it is important to clear the Working
-      Memory of any inserted <code>PossibleCellValues</code> at the same
-      row and column
-      with invalid values. This rule is therefore given a higher salience than
-      the remaining rules to ensure that as soon as the LHS is true,
-      activations for the rule move to the top of the Agenda and are fired. In
-      turn, this prevents the spurious firing of other rules due to the
-      combination of a <code>ResolvedCellValue</code> and one or more
-      <code>PossibleCellValues</code> being present in the same cell.
-      This rule also calls <code>update()</code> on the
-      <code>ResolvedCellValue</code>, even though its value has not in
-      fact been modified to ensure that Drools fires an event to any
-      <code>WorkingMemoryListeners</code>  attached to the Working Memory
-      so that they can update themselves - in
-      this case so that the GUI can display the new state of the grid.</para>
-
-      <para>Rule #2 identifies cells in the grid which have only one possible
-      value. The first line of the <literal>when</literal> clause matches all of the
-      <code>PossibleCellValue</code> objects in the Working Memory. The
-      second line demonstrates a use of the <literal>not</literal> keyword. This rule
-      will only fire if no other <code>PossibleCellValue</code> objects
-      exist in the Working Memory at the same
-      row and column but with a different value. When the rule fires, the
-      single <code>PossibleCellValue</code> at the row and column is
-      retracted from the Working Memory and is replaced by a new
-      <code>ResolvedCellValue</code> at the same
-      row and column with the same value.</para>
-
-      <para>Rule #3 removes <code>PossibleCellValues</code> with a given
-      value from a row when they have the same value as a
-      <code>ResolvedCellValue</code>. In other words, when a cell is filled
-      with a resolved value, we need to remove the
-      possibility of any other cell on the same row having this value. The
-      first line of the when clause matches all <code>ResolvedCellValue</code>
-      objects in the Working Memory. The second line matches
-      <code>PossibleCellValues</code> which have both the same row and the
-      same value as these <code>ResolvedCellValue</code>
-      objects. If any are found, the rule activates and, when fired retracts
-      the <code>PossibleCellValue</code> which can no longer be a solution
-      for that cell.</para>
-
-      <para>Rules #4 and #5 act in the same way as Rule #3 but check for
-      redundant <code>PossibleCellValues</code> in a given column and a 
-      given zone of the grid as a <code>ResolvedCellValue</code>
-      respectively.</para>
-
-      <para>Rule #6 checks for the scenario where a possible cell value only
-      appears once in a given row. The first line of the LHS matches against
-      all <code>PossibleCellValue</code> facts in the Working Memory, storing
-      the result in a number of local variables. The second line checks that
-      no other <code>PossibleCellValue</code> objects with the same value
-      exist on this row. The third to fifth lines check that there is not
-      a <code>ResolvedCellValue</code> with the same value in the same zone,
-      row or column so that this rule does not fire prematurely.
-      It is interesting to note that we could remove lines 3 to 5 and give
-      rules #3, #4 and #5 a higher salience to make sure they always fire
-      before rules #6,#7 and #8. When the rule fires, we know that
-      <code>$possible</code> must represent the value for the cell;
-      so, as in Rule #2, we retract <code>$possible</code> and replace it
-      with the equivalent, new <code>ResolvedCellValue</code>.</para>
-
-      <para>Rules #7 and #8 act in the same way as Rule #2 but check for
-      single <code>PossibleCellValues</code> in a given column and a given
-      zone of the grid, respectively.</para>
-
-      <para>Rule #9 represents the most complex currently implemented rule.
-      This rule implements the logic that, if we know that a pair of given
-      values can only occur in two cells on a specific row, (for example we
-      have determined the values of 4 and 6 can only appear in the first row
-      in cells [0,3] and [0,5]) and this pair of cells can not hold other 
-      values, then, although we do not know which of the pair contains a 
-      four and which contains a six, we do know that these two values must be
-      in these two cells, and hence we can remove the possibility of them
-      occuring anywhere else in the same row.</para>
-
-<!--  TODO: more detail here and I think the  rule can be cleaned up in
-      the DRL file before fully documenting  it. -->
-
-      <para>Rules #10 and #11 act in the same way as rule #9 but check for the
-      existance of only two possible values in a given column and zone,
-      respectively.</para>
-
-      <para>To solve harder grids, the rule set would need to be extended
-      further with more complex rules that encapsulate more complex
-      reasoning.</para>
-    </section>
-
-    <section>
-      <title>Suggestions for Future Developments</title>
-
-      <para>There are a number of ways in which this example could be
-      developed. The reader is encouraged to consider these as
-      excercises.</para>
-
-      <itemizedlist>
-        <listitem>
-          <para>Agenda groups are a great declarative tool for
-          phased execution. In this example, it is easy to see we have two
-          phases: "resolution" and "validation". Right now, they are executed
-          by creating two separate rule bases, each for one "job".
-          Presumably it would be better to define agenda groups for all the
-          rules, spliting them in "resolution" rules and "validation" rules,
-          all loaded in a single rule base. The engine executes resolution and
-          right after that, executes validation.</para>
-        </listitem>
-
-        <listitem>
-          <para>Auto-focus is a great way of handling exceptions
-          to the regular rules execution. In our case, if we detect an
-          inconsistency, either in the input data or in the resolution rules,
-          why should we spend time continuing the execution if it will be
-          invalid anyway? It is better to simply (and immediately)
-          report the inconsistency as soon as it is found. To do that, since
-          we now have a single rulebase with all rules, we simply need to
-          define the auto-focus attribute for all rules validating puzzle
-          consistency.</para>
-        </listitem>
-
-        <listitem>
-          <para>Logical insert: an inconsistency only exists while wrong data
-          is in the working memory. As so, we could state that the
-          validation rules logically insert inconsistencies and as soon as the
-          offending data is retracted, the inconsistency no longer
-          exists.</para>
-        </listitem>
-
-        <listitem>
-          <para><code>session.iterateObjects()</code>: although a valid
-          use case having a global list to add the found problems, I think
-          it would be more
-          interesting to ask the Stateful Session by the desired list of
-          problems, using <code>session.iterateObjects( new ClassObjectFilter(
-          Inconsistency.class ) ).</code> Having the inconsistency class
-          can also allow us to paint in red the offending cells in the
-          GUI.</para>
-        </listitem>
-
-        <listitem>
-          <para><code>kcontext.getKnowledgeRuntime().halt()</code>: even
-          reporting the error as soon as it is found, we need a way to tell
-          the engine to stop   evaluating rules. We
-          can do that creating a rule that, in the presence of inconsistencies,
-          calls <code>halt()</code> to stop evaluation.</para>
-        </listitem>
-
-        <listitem>
-          <para>Queries: looking at the method
-          <code>getPossibleCellValues(int row, int col)</code> in
-          <code>DroolsSudokuGridModel</code>, we see it iterating over all
-          <code>CellValue</code> objects, looking for the few it wants. That
-          is a great opportunity to demonstrate Drools queries. We just
-          define a query to
-          return the objects we want and iterate over it, cleanly and nicely.
-          Other queries may be defined as needed.</para>
-        </listitem>
-
-        <listitem>
-          <para>Globals as services: the main objective of this change is to
-          attend the next proposed change , but it is nice by its own.
-          In order to teach the use of globals as services, it
-          would be nice to set up a callback, so that each rule that finds the
-          <code>ResolvedCellValue</code> for a given cell can call, to
-          notify and update the corresponding cell in the GUI, providing
-          immediate feedback for
-          the user. Also, the last found cell could have its number painted in
-          a different color to facilitate the identification of the rules'
-          conclusions.</para>
-        </listitem>
-
-        <listitem>
-          <para>Step by step execution: now that we have immediate user
-          feedback, we can make use of the restricted run feature in Drools,
-          i.e., we could add a button in the GUI, that, when activated,
-          causes the execution of a single rule, by calling
-          <code>fireAllRules( 1 )</code>. This way, the user would see,
-          step by step, what the engine is doing.</para>
-        </listitem>
-      </itemizedlist>
-    </section>
-  </section>

Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-SudokuExample.xml (from rev 34175, labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-SodukiExample.xml)
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-SudokuExample.xml	                        (rev 0)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-SudokuExample.xml	2010-07-26 11:35:41 UTC (rev 34176)
@@ -0,0 +1,481 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<section version="5.0"
+         xsi:schemaLocation="http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd"
+         xml:base="../" xmlns="http://docbook.org/ns/docbook" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:ns="http://docbook.org/ns/docbook">
+    <title>Sudoku Example</title>
+
+    <programlisting><emphasis role="bold">Name:</emphasis> Sudoku
+<emphasis role="bold">Main class:</emphasis> org.drools.examples.sudoku.Main
+<emphasis role="bold">Type:</emphasis> Java application
+<emphasis role="bold">Rules file:</emphasis> sudokuSolver.drl, sudokuValidator.drl
+<emphasis role="bold">Objective:</emphasis> Demonstrates the solving of logic problems, and complex pattern matching.
+</programlisting>
+
+    <para>This example demonstrates how Drools can be used to find a solution
+    in a large potential solution space based on a number of constraints. We
+    use the popular puzzle of Sudoku. This example also shows how Drools can
+    be integrated into a graphical interface and how callbacks can be used to
+    interact with a running Drools rules engine in order to update the
+    graphical interface based on changes in the Working Memory at
+    runtime.</para>
+
+    <section>
+      <title>Sudoku Overview</title>
+
+      <para>Sudoku is a logic-based number placement puzzle. The objective is
+      to fill a 9x9 grid so that each column, each row, and each of the nine
+      3x3 zones contains the digits from 1 to 9, once, and only once.</para>
+
+      <para>The puzzle setter provides a partially completed grid and the
+      puzzle solver's task is to complete the grid with these
+      constraints.</para>
+
+      <para>The general strategy to solve the problem is to ensure that when
+      you insert a new number it should be unique in its particular
+      3x3 zone, row and column.</para>
+
+      <para>See <link xlink:href="http://en.wikipedia.org/wiki/Sudoku">Wikipedia</link>
+      for a more detailed description.</para>
+    </section>
+
+    <section>
+      <title>Running the Example</title>
+
+      <para>Download and install drools-examples as described above and then
+      execute <filename>java org.drools.examples.sudoku.Main</filename>. This
+      example requires Java 5.</para>
+
+      <para>A window will be displayed with a relatively simple partially
+      filled grid. <screenshot>
+          <info>New remote site</info>
+
+          <mediaobject>
+            <imageobject>
+              <imagedata fileref="images/Chapter-Examples/SudokuExample/sudoku1.png" />
+            </imageobject>
+          </mediaobject>
+        </screenshot></para>
+
+      <para>Click on the "Solve" button and the Drools-based engine will fill
+      out the remaining values. The Console window will display detailed
+      information about the rules which are executing to solve the puzzle
+      in a human readable form.</para>
+
+      <para><screen>Rule #3 determined the value at (4,1) could not be 4 as this value already exists in the same column at (8,1)
+Rule #3 determined the value at (5,5) could not be 2 as this value already exists in the same row at (5,6)
+Rule #7 determined (3,5) is 2 as this is the only possible cell in the column that can have this value
+Rule #1 cleared the other PossibleCellValues for (3,5) as a ResolvedCellValue of 2 exists for this cell.
+Rule #1 cleared the other PossibleCellValues for (3,5) as a ResolvedCellValue of 2 exists for this cell.
+... 
+Rule #3 determined the value at (1,1) could not be 1 as this value already  exists in the same zone at (2,1)
+Rule #6 determined (1,7) is 1 as this is the only possible cell in the row that can have this value
+Rule #1 cleared the other PossibleCellValues for (1,7) as a ResolvedCellValue of 1 exists for this cell.
+Rule #6 determined (1,1) is 8 as this is the only possible cell in the row that can have this value</screen></para>
+
+      <para>Once all of the activated rules for the solving logic have
+      executed, the engine executes a second rule base to check that the
+      solution is complete and valid. In this case it is, and the "Solve"
+      button is disabled and displays a text like
+      <code>"Solved (1052ms)"</code>.<screenshot>
+          <info>New remote site</info>
+
+          <mediaobject>
+            <imageobject>
+              <imagedata fileref="images/Chapter-Examples/SudokuExample/sudoku2.png" />
+            </imageobject>
+          </mediaobject>
+        </screenshot></para>
+
+      <para>The example comes with a number of grids which can be loaded and
+      solved. Click on "File", then "Samples" and "Medium" to load a more
+      challenging grid. Note that the solve button is enabled when the new
+      grid is loaded.
+      <screenshot>
+          <info>New remote site</info>
+
+          <mediaobject>
+            <imageobject>
+              <imagedata fileref="images/Chapter-Examples/SudokuExample/sudoku3.png" />
+            </imageobject>
+          </mediaobject>
+        </screenshot></para>
+
+      <para>Click on the "Solve" button again to solve this new grid.
+      <screenshot>
+          <info>New remote site</info>
+
+          <mediaobject>
+            <imageobject>
+              <imagedata fileref="images/Chapter-Examples/SudokuExample/sudoku4.png" />
+            </imageobject>
+          </mediaobject>
+        </screenshot></para>
+
+      <para>Now, let us load a Sudoku grid that is deliberately invalid. Click
+      on "File", "Samples" and "!DELIBERATELY BROKEN!". Note that this grid
+      starts with some issues, for example the value 5 appears twice in the
+      first row.<screenshot>
+          <info>New remote site</info>
+
+          <mediaobject>
+            <imageobject>
+              <imagedata fileref="images/Chapter-Examples/SudokuExample/sudoku5.png" />
+            </imageobject>
+          </mediaobject>
+        </screenshot></para>
+
+      <para>Nevertheless, click on the "Solve" button to apply the solving
+      rules to this invalid grid. Note that the "Solve" button is relabelled
+      to indicate that the resulting solution is invalid. <screenshot>
+          <info>New remote site</info>
+
+          <mediaobject>
+            <imageobject>
+              <imagedata fileref="images/Chapter-Examples/SudokuExample/sudoku6.png" />
+            </imageobject>
+          </mediaobject>
+        </screenshot></para>
+
+      <para>In addition, the validation rule set outputs all of the issues
+      which are discovered to the console. <programlisting>
+There are two cells on the same column with the same value at (6,0) and (4,0)
+There are two cells on the same column with the same value at (4,0) and (6,0)
+There are two cells on the same row with the same value at (2,4) and (2,2)
+There are two cells on the same row with the same value at (2,2) and (2,4)
+There are two cells on the same row with the same value at (6,3) and (6,8)
+There are two cells on the same row with the same value at (6,8) and (6,3)
+There are two cells on the same column with the same value at (7,4) and (0,4)
+There are two cells on the same column with the same value at (0,4) and (7,4)
+There are two cells on the same row with the same value at (0,8) and (0,0)
+There are two cells on the same row with the same value at (0,0) and (0,8)
+There are two cells on the same column with the same value at (1,2) and (3,2)
+There are two cells on the same column with the same value at (3,2) and (1,2)
+There are two cells in the same zone with the same value at (6,3) and (7,3)
+There are two cells in the same zone with the same value at (7,3) and (6,3)
+There are two cells on the same column with the same value at (7,3) and (6,3)
+There are two cells on the same column with the same value at (6,3) and (7,3)</programlisting></para>
+
+      <para>We will look at the solving rule set later in this section, but
+      for the moment we should note that some theoretically solvable solutions
+      can not be solved by the engine as it stands. Click on
+      "File", "Samples" and then "Hard 3" to load a sparsely populated grid.
+      <screenshot>
+          <info>New remote site</info>
+
+          <mediaobject>
+            <imageobject>
+              <imagedata fileref="images/Chapter-Examples/SudokuExample/sudoku7.png" />
+            </imageobject>
+          </mediaobject>
+        </screenshot></para>
+
+      <para>Now click on the "Solve" button and note that the current rules
+      are unable to complete the grid, even though (if you are a Sudoku
+      aficionado) you may be able to see a way forward with the solution.
+      <screenshot>
+          <info>New remote site</info>
+
+          <mediaobject>
+            <imageobject>
+              <imagedata fileref="images/Chapter-Examples/SudokuExample/sudoku8.png" />
+            </imageobject>
+          </mediaobject>
+        </screenshot></para>
+
+      <para>At the present time, the solving functionality has been achieved
+      by the use of ten rules. This rule set could be extended to enable the
+      engine to tackle more complex logic for filling grids such as
+      this.</para>
+    </section>
+
+    <section>
+      <title>Java Source and Rules Overview</title>
+
+      <para>The Java source code can be found in the
+      /src/main/java/org/drools/examples/sudoku directory, with the two DRL
+      files defining the rules located in the
+      /src/main/rules/org/drools/examples/sudoku directory.</para>
+
+      <para>The package <code>org.drools.examples.sudoku.swing</code>
+      contains a set of classes which implement a framework for Sudoku
+      puzzles. Note that this package does not have any dependencies on
+      the Drools libraries. <code>SudokuGridModel</code>
+      defines an interface which can be implemented to store a Sudoku puzzle
+      as a 9x9 grid of <code>Integer</code> values, some of which may be null,
+      indicating that the value for the cell has not yet been resolved.
+      <code>SudokuGridView</code> is
+      a Swing component which can visualize any implementation of
+      <code>SudokuGridModel</code>. <code>SudokuGridEvent</code> and
+      <code>SudokuGridListener</code> are used to
+      communicate state changes between the model and the view: events are
+      fired when a cell's value is resolved or changed. If you are familiar
+      with the model-view-controller patterns in other Swing components such
+      as <code>JTable</code> then this pattern should be familiar.
+      <code>SudokuGridSamples</code> provides a number of partially filled
+      Sudoku puzzles for demonstration purposes.</para>
+
+      <para>Package <code>org.drools.examples.sudoku.rules</code> contains an
+      implementation of <code>SudokuGridModel</code> which is based on Drools.
+      Two Java objects are used, both of which extend
+      <code>AbstractCellValue</code> and represent a value for a specific cell
+      in the grid, including the row and column location of the cell, an index
+      of the 3x3 zone the cell is contained in, and the value of the cell.
+      <code>PossibleCellValue</code> indicates that we do not currently know
+      for sure what the value in a cell is. There can be from 2 to 9 possible
+      cell values for a given cell. <code>ResolvedCellValue</code> indicates 
+      that we have determined what the value
+      for a cell must be. There can only be one resolved cell value for a
+      given cell. <code>DroolsSudokuGridModel</code> implements
+      <code>SudokuGridModel</code> and is responsible for converting an
+      initial two dimensional array of partially specified cells into a set
+      of <code>CellValue</code> Java object, creating a Working Memory
+      based on <filename>solverSudoku.drl</filename> and inserting the
+      <code>CellValue</code> objects into the Working Memory. When the 
+      <code>solve()</code> method is called it calls in turn
+      <code>fireAllRules()</code> on this Working Memory to try to solve
+      the puzzle. <code>DroolsSudokuGridModel</code> attaches a 
+      <code>WorkingMemoryListener</code> to the Working Memory, which
+      allows it to be called back on insert and retract events as the
+      puzzle is solved. When a new <code>ResolvedCellValue</code> is inserted
+      into the Working Memory, this callback allows the implementation to
+      fire a <code>SudokuGridEvent</code> to its
+      <code>SudokuGridListener</code> clientele, which can then update
+      themselves in realtime. Once all the rules fired by the solver Working
+      Memory have executed, <code>DroolsSudokuGridModel</code> runs a
+      second set of rules, based on <filename>validatorSudoku.drl</filename>
+      which works with the same set of Java objects to determine whether the
+      resulting grid is a valid and a full solution.</para>
+
+      <para>The class <code>org.drools.examples.sudoku.Main</code> implements
+      a Java application combining the components desribed.</para>
+
+      <para>The packae <code>org.drools.examples.sudoku</code> contains two
+      DRL files. <filename>solverSudoku.drl</filename> defines the rules
+      which attempt to solve a Sudoku puzzle, and
+      <filename>validator.drl</filename> defines the rules which determin
+      whether the current state of the Working Memory represents a valid
+      solution. Both use <code>PossibleCellValue</code> and
+      <code>ResolvedCellValue</code> objects as their facts and
+      both output information to the Console window as their rules fire. In a
+      real-world situation we would insert logging information and use the
+      <code>WorkingMemoryListener</code> to display this information to a
+      user, rather than use the console in this fashion.</para>
+    </section>
+
+    <section>
+      <title>Sudoku Validator Rules (validatorSudoku.drl)</title>
+
+      <para>We start with the validator rules as this rule set is shorter and
+      simpler than the solver rule set.</para>
+
+      <para>The first rule simply checks that no <code>PossibleCellValue</code>
+      objects remain in the Working Memory. Once the puzzle is solved, only
+      <code>ResolvedCellValue</code> objects should be present, one for
+      each cell.</para>
+
+      <para>The other three rules each match all of the
+      <code>ResolvedCellValue</code> objects and bind them to the
+      variable <code>$resolved1</code>. They then look for
+      <code>ResolvedCellValues</code> that
+      contain the same value and are located, respectively, in the same row,
+      column, or 3x3 zone. If these rules are fired they add a message to a
+      global list of strings describing the reason the solution is invalid.
+      <code>DroolsSudokoGridModel</code> injects this list before it runs
+      the rule set and checks whether it is empty or not after having called
+      <code>fireAllRules()</code>. If it is not empty then it prints all the
+      strings in the list and sets a flag to indicate that the grid is not
+      solved.</para>
+    </section>
+
+    <section>
+      <title>Sudoku Solving Rules (solverSudoku.drl)</title>
+
+      <para>Now let us look at the more complex rule set used to solve Sudoku
+      puzzles.</para>
+
+      <para>Rule #1 is basically a book-keeping rule. Several of the other
+      rules insert <code>ResolvedCellValues</code> into the working memory
+      at specific rows and columns after they have determined that a given
+      cell must have a
+      certain value. At this point, it is important to clear the Working
+      Memory of any inserted <code>PossibleCellValues</code> at the same
+      row and column
+      with invalid values. This rule is therefore given a higher salience than
+      the remaining rules to ensure that as soon as the LHS is true,
+      activations for the rule move to the top of the Agenda and are fired. In
+      turn, this prevents the spurious firing of other rules due to the
+      combination of a <code>ResolvedCellValue</code> and one or more
+      <code>PossibleCellValues</code> being present in the same cell.
+      This rule also calls <code>update()</code> on the
+      <code>ResolvedCellValue</code>, even though its value has not in
+      fact been modified to ensure that Drools fires an event to any
+      <code>WorkingMemoryListeners</code>  attached to the Working Memory
+      so that they can update themselves - in
+      this case so that the GUI can display the new state of the grid.</para>
+
+      <para>Rule #2 identifies cells in the grid which have only one possible
+      value. The first line of the <literal>when</literal> clause matches all of the
+      <code>PossibleCellValue</code> objects in the Working Memory. The
+      second line demonstrates a use of the <literal>not</literal> keyword. This rule
+      will only fire if no other <code>PossibleCellValue</code> objects
+      exist in the Working Memory at the same
+      row and column but with a different value. When the rule fires, the
+      single <code>PossibleCellValue</code> at the row and column is
+      retracted from the Working Memory and is replaced by a new
+      <code>ResolvedCellValue</code> at the same
+      row and column with the same value.</para>
+
+      <para>Rule #3 removes <code>PossibleCellValues</code> with a given
+      value from a row when they have the same value as a
+      <code>ResolvedCellValue</code>. In other words, when a cell is filled
+      with a resolved value, we need to remove the
+      possibility of any other cell on the same row having this value. The
+      first line of the when clause matches all <code>ResolvedCellValue</code>
+      objects in the Working Memory. The second line matches
+      <code>PossibleCellValues</code> which have both the same row and the
+      same value as these <code>ResolvedCellValue</code>
+      objects. If any are found, the rule activates and, when fired retracts
+      the <code>PossibleCellValue</code> which can no longer be a solution
+      for that cell.</para>
+
+      <para>Rules #4 and #5 act in the same way as Rule #3 but check for
+      redundant <code>PossibleCellValues</code> in a given column and a 
+      given zone of the grid as a <code>ResolvedCellValue</code>
+      respectively.</para>
+
+      <para>Rule #6 checks for the scenario where a possible cell value only
+      appears once in a given row. The first line of the LHS matches against
+      all <code>PossibleCellValue</code> facts in the Working Memory, storing
+      the result in a number of local variables. The second line checks that
+      no other <code>PossibleCellValue</code> objects with the same value
+      exist on this row. The third to fifth lines check that there is not
+      a <code>ResolvedCellValue</code> with the same value in the same zone,
+      row or column so that this rule does not fire prematurely.
+      It is interesting to note that we could remove lines 3 to 5 and give
+      rules #3, #4 and #5 a higher salience to make sure they always fire
+      before rules #6,#7 and #8. When the rule fires, we know that
+      <code>$possible</code> must represent the value for the cell;
+      so, as in Rule #2, we retract <code>$possible</code> and replace it
+      with the equivalent, new <code>ResolvedCellValue</code>.</para>
+
+      <para>Rules #7 and #8 act in the same way as Rule #2 but check for
+      single <code>PossibleCellValues</code> in a given column and a given
+      zone of the grid, respectively.</para>
+
+      <para>Rule #9 represents the most complex currently implemented rule.
+      This rule implements the logic that, if we know that a pair of given
+      values can only occur in two cells on a specific row, (for example we
+      have determined the values of 4 and 6 can only appear in the first row
+      in cells [0,3] and [0,5]) and this pair of cells can not hold other 
+      values, then, although we do not know which of the pair contains a 
+      four and which contains a six, we do know that these two values must be
+      in these two cells, and hence we can remove the possibility of them
+      occuring anywhere else in the same row.</para>
+
+<!--  TODO: more detail here and I think the  rule can be cleaned up in
+      the DRL file before fully documenting  it. -->
+
+      <para>Rules #10 and #11 act in the same way as rule #9 but check for the
+      existance of only two possible values in a given column and zone,
+      respectively.</para>
+
+      <para>To solve harder grids, the rule set would need to be extended
+      further with more complex rules that encapsulate more complex
+      reasoning.</para>
+    </section>
+
+    <section>
+      <title>Suggestions for Future Developments</title>
+
+      <para>There are a number of ways in which this example could be
+      developed. The reader is encouraged to consider these as
+      excercises.</para>
+
+      <itemizedlist>
+        <listitem>
+          <para>Agenda groups are a great declarative tool for
+          phased execution. In this example, it is easy to see we have two
+          phases: "resolution" and "validation". Right now, they are executed
+          by creating two separate rule bases, each for one "job".
+          Presumably it would be better to define agenda groups for all the
+          rules, spliting them in "resolution" rules and "validation" rules,
+          all loaded in a single rule base. The engine executes resolution and
+          right after that, executes validation.</para>
+        </listitem>
+
+        <listitem>
+          <para>Auto-focus is a great way of handling exceptions
+          to the regular rules execution. In our case, if we detect an
+          inconsistency, either in the input data or in the resolution rules,
+          why should we spend time continuing the execution if it will be
+          invalid anyway? It is better to simply (and immediately)
+          report the inconsistency as soon as it is found. To do that, since
+          we now have a single rulebase with all rules, we simply need to
+          define the auto-focus attribute for all rules validating puzzle
+          consistency.</para>
+        </listitem>
+
+        <listitem>
+          <para>Logical insert: an inconsistency only exists while wrong data
+          is in the working memory. As so, we could state that the
+          validation rules logically insert inconsistencies and as soon as the
+          offending data is retracted, the inconsistency no longer
+          exists.</para>
+        </listitem>
+
+        <listitem>
+          <para><code>session.iterateObjects()</code>: although a valid
+          use case having a global list to add the found problems, I think
+          it would be more
+          interesting to ask the Stateful Session by the desired list of
+          problems, using <code>session.iterateObjects( new ClassObjectFilter(
+          Inconsistency.class ) ).</code> Having the inconsistency class
+          can also allow us to paint in red the offending cells in the
+          GUI.</para>
+        </listitem>
+
+        <listitem>
+          <para><code>kcontext.getKnowledgeRuntime().halt()</code>: even
+          reporting the error as soon as it is found, we need a way to tell
+          the engine to stop   evaluating rules. We
+          can do that creating a rule that, in the presence of inconsistencies,
+          calls <code>halt()</code> to stop evaluation.</para>
+        </listitem>
+
+        <listitem>
+          <para>Queries: looking at the method
+          <code>getPossibleCellValues(int row, int col)</code> in
+          <code>DroolsSudokuGridModel</code>, we see it iterating over all
+          <code>CellValue</code> objects, looking for the few it wants. That
+          is a great opportunity to demonstrate Drools queries. We just
+          define a query to
+          return the objects we want and iterate over it, cleanly and nicely.
+          Other queries may be defined as needed.</para>
+        </listitem>
+
+        <listitem>
+          <para>Globals as services: the main objective of this change is to
+          attend the next proposed change , but it is nice by its own.
+          In order to teach the use of globals as services, it
+          would be nice to set up a callback, so that each rule that finds the
+          <code>ResolvedCellValue</code> for a given cell can call, to
+          notify and update the corresponding cell in the GUI, providing
+          immediate feedback for
+          the user. Also, the last found cell could have its number painted in
+          a different color to facilitate the identification of the rules'
+          conclusions.</para>
+        </listitem>
+
+        <listitem>
+          <para>Step by step execution: now that we have immediate user
+          feedback, we can make use of the restricted run feature in Drools,
+          i.e., we could add a button in the GUI, that, when activated,
+          causes the execution of a single rule, by calling
+          <code>fireAllRules( 1 )</code>. This way, the user would see,
+          step by step, what the engine is doing.</para>
+        </listitem>
+      </itemizedlist>
+    </section>
+  </section>


Property changes on: labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-SudokuExample.xml
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:mime-type
   + text/plain

Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/images/Chapter-Examples/SudokuExample (from rev 34168, labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/images/Chapter-Examples/SodukiExample)



More information about the jboss-svn-commits mailing list