[jboss-svn-commits] JBL Code SVN: r26273 - labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Apr 27 05:26:18 EDT 2009
Author: laune
Date: 2009-04-27 05:26:18 -0400 (Mon, 27 Apr 2009)
New Revision: 26273
Modified:
labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-HonestPoliticianExample.xml
labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-NumberGuessExample.xml
labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-SodukiExample.xml
Log:
improvements
Modified: labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-HonestPoliticianExample.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-HonestPoliticianExample.xml 2009-04-27 09:25:51 UTC (rev 26272)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-HonestPoliticianExample.xml 2009-04-27 09:26:18 UTC (rev 26273)
@@ -1,102 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
- <section version="5.0" xmlns="http://docbook.org/ns/docbook"
+<section version="5.0" xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:m="http://www.w3.org/1998/Math/MathML"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://docbook.org/ns/docbook" xml:base="../../">
- <title>Honest Politician Example</title>
+ <title>Honest Politician Example</title>
- <para>The honest politician example demonstrates truth maintenance with logical assertions, the basic premise is that an object can only exist while a statement is true. A rule's consequence can logical insert an object with the insertLogical method, this means the object will only remain in the working memory as long as the rule that logically inserted it remains true, when the rule is no longer true the object is automatically retracted.</para>
+ <programlisting><emphasis role="bold">Name:</emphasis> Honest Politician
+<emphasis role="bold">Main class:</emphasis> org.drools.examples.HonestPoliticianExample
+<emphasis role="bold">Type:</emphasis> Java application
+<emphasis role="bold">Rules file:</emphasis> HonestPoliticianExample.drl
+<emphasis role="bold">Objective:</emphasis> Illustrate the concept of "truth maintenance" based on the logical insertion of facts
+</programlisting>
- <para>In this example there is Politician class with a name and a boolean
- value for honest state, four politicians with honest state set to true are
- inserted.</para>
+ <para>The Honest Politician example demonstrates truth maintenance with
+ logical assertions. The basic premise is that an object can only exist
+ while a statement is true. A rule's consequence can logically insert an
+ object with the <code>insertLogical()</code> method. This means the object
+ will only remain in the Working Memory as long as the rule that logically
+ inserted it remains true. When the rule is no longer true the object is
+ automatically retracted.</para>
- <para><example>
- <title>Politician Class</title>
+ <para>In this example there is the class <code>Politician</code>, with a
+ name and a boolean value for being honest. Four politicians with honest
+ state set to true are inserted.</para>
- <programlisting>public class Politician {
+ <para><example>
+ <title>Class Politician</title>
+
+ <programlisting>public class Politician {
private String name;
private boolean honest;
...
}</programlisting>
</example><example>
- <title>Honest Politician Example Execution</title>
+ <title>Honest Politician: Execution</title>
- <programlisting>Politician blair = new Politician("blair", true);
-Politician bush = new Politician("bush", true);
-Politician chirac = new Politician("chirac", true);
-Politician schroder = new Politician("schroder", true);
-
+ <programlisting>Politician blair = new Politician("blair", true);
+Politician bush = new Politician("bush", true);
+Politician chirac = new Politician("chirac", true);
+Politician schroder = new Politician("schroder", true);
+
ksession.insert( blair );
ksession.insert( bush );
ksession.insert( chirac );
ksession.insert( schroder );
ksession.fireAllRules();</programlisting>
- </example>The console out shows that while there is atleast one honest
- polician democracy lives, however as each politician is in turn corrupted
- by an evil corporation, when all politicians are dishonest democracy is
- dead.<example>
- <title>Honest Politician Example Console Output</title>
+ </example>The Console window output shows that, while there is at
+ least one honest politician, democracy lives. However, as each
+ politician is in turn corrupted by an evil corporation, so that
+ all politicians become dishonest, democracy is dead.<example>
+ <title>Honest Politician: Console Output</title>
- <programlisting>Hurrah!!! Democracy Lives
+ <programlisting>Hurrah!!! Democracy Lives
I'm an evil corporation and I have corrupted schroder
I'm an evil corporation and I have corrupted chirac
I'm an evil corporation and I have corrupted bush
I'm an evil corporation and I have corrupted blair
We are all Doomed!!! Democracy is Dead
</programlisting>
- </example>As soon as there is one more more honest politcians in the
- working memory a new Hope object is logically asserted, this object will
- only exist while there is at least one or more honest politicians, the
- moment all politicians are dishonest then the Hope object will be
- automatically retracted. This rule is given a salience of 10 to make sure
- it fires before any other rules, as at this stage the "Hope is Dead" rule
- is actually true.</para>
+ </example>As soon as there is at least one honest politician in the
+ Working Memory a new <code>Hope</code> object is logically asserted.
+ This object will only exist while there is at least one honest
+ politician. As soon as all politicians are dishonest, the
+ <code>Hope</code> object will be automatically retracted. This rule
+ is given a salience of 10 to ensure that it fires before any other
+ rule, as at this stage the "Hope is Dead" rule is actually true.</para>
<example>
- <title>Honest Politician Example : Rule "We have an honest
- politician"</title>
+ <title>Honest Politician: Rule "We have an honest politician"</title>
- <programlisting>rule "We have an honest Politician"
+ <programlisting>rule "We have an honest Politician"
salience 10
when
exists( Politician( honest == true ) )
then
insertLogical( new Hope() );
end</programlisting>
- </example>
+ </example>
- <para>As soon as a Hope object exists the "Hope Lives" rule matches, and
- fires, it has a salience of 10 so that it takes priority over "Corrupt the
- Honest".</para>
+ <para>As soon as a <code>Hope</code> object exists the "Hope Lives" rule
+ matches and fires. It has a salience of 10 so that it takes priority
+ over "Corrupt the Honest".</para>
- <example>
- <title>Honest Politician Example : Rule "Hope Lives"</title>
+ <example>
+ <title>Honest Politician: Rule "Hope Lives"</title>
- <programlisting>rule "Hope Lives"
+ <programlisting>rule "Hope Lives"
salience 10
- when
- exists( Hope() )
- then
- System.out.println("Hurrah!!! Democracy Lives");
+ when
+ exists( Hope() )
+ then
+ System.out.println("Hurrah!!! Democracy Lives");
end</programlisting>
</example>
- <para>Now that hope exists and we have, at the start, four honest
- politicians we have 4 activations for this rule all in conflict. This rule
- iterates over those rules firing each one in turn, corrupting each
- politician so that they are no longer honest. When all four politicians
- have been corrupted we have no politicians with the property "honest ==
- true" thus the rule "We have an honest Politician" is no longer true and
- the object it logical inserts "new Hope()" is automatically
- retracted.</para>
+ <para>Now that there is hope and we have, at the start, four honest
+ politicians, we have four activations for this rule, all in conflict.
+ They will fire in turn, corrupting each politician so that they are
+ no longer honest. When all four politicians have been corrupted we
+ have no politicians with the property <code>honest == true</code>.
+ Thus, the rule "We have an honest Politician" is no longer true and
+ the object it logical inserted (due to the last execution of
+ <code>new Hope()</code>) is automatically retracted.</para>
<example>
- <title>Honest Politician Example : Rule "Corrupt the Honest"</title>
+ <title>Honest Politician: Rule "Corrupt the Honest"</title>
<programlisting>rule "Corrupt the Honest"
when
@@ -108,12 +120,13 @@
end</programlisting>
</example>
- <para>With Hope being automatically retracted, via the truth maintenance
- system, then Hope no longer exists in the system and this rule will match
- and fire.</para>
+ <para>With the <code>Hope</code> object being automatically retracted,
+ via the truth maintenance system, the conditional element <kw>not</kw>
+ applied to <code>Hope</code> is no longer true so that the following
+ rule will match and fire.</para>
<example>
- <title>Honest Politician Example : Rule "Hope is Dead"</title>
+ <title>Honest Politician: Rule "Hope is Dead"</title>
<programlisting>rule "Hope is Dead"
when
@@ -123,7 +136,7 @@
end</programlisting>
</example>
- <para>lets take a look the audit trail for this application:</para>
+ <para>Let's take a look at the Audit trail for this application:</para>
<figure>
<title>Honest Politician Example Audit View</title>
@@ -136,23 +149,25 @@
</mediaobject>
</figure>
- <para>The moment we insert the first politician we have two activations,
- the "We have an honest Politician" is activated only once for the first
- inserted politician because it uses an existential 'exists' conditional
- element which only matches. the rule "Hope is Dead" is also activated at
- this stage, because as of yet we have not inserted the Hope object. "We
- have an honest Politician" fires first, as it has a higher salience over
- "Hope is Dead" which inserts the Hope object, that action is highlighted
- green above. The insertion of the Hope object activates "Hope Lives" and
- de-activates "Hope is Dead", it also actives "Corrupt the Honest" for each
- inserted honested politician. "Rule Hope Lives" executes printing
- "Hurrah!!! Democracy Lives". Then for each politician the rule "Corrupt
- the Honest" fires printing "I'm an evil corporation and I have corrupted
- X", where X is the name of the politician, and modifies the politicians
- honest value to false. When the last honest polician is corrupted Hope is
- automatically retracted, by the truth maintenance system, as shown by the
- blue highlighted area. The green highlighted area shows the origin of the
- currently selected blue highlighted area. Once Hope is retracted "Hope is
+ <para>The moment we insert the first politician we have two activations.
+ The rule "We have an honest Politician" is activated only once for the first
+ inserted politician because it uses an <kw>exists</kw> conditional
+ element, which matches once for any number. The rule "Hope is Dead" is
+ also activated at this stage, because we have not yet inserted the
+ <code>Hope</code> object. Rule "We have an honest Politician" fires first,
+ as it has a higher salience than "Hope is Dead", which inserts the
+ <code>Hope</code> object. (That action is highlighted green.) The
+ insertion of the <code>Hope</code> object activates "Hope Lives" and
+ de-activates "Hope is Dead"; it also activates "Corrupt the Honest"
+ for each inserted honested politician. Rule "Hope Lives" executes,
+ printing "Hurrah!!! Democracy Lives". Then, for each politician, rule
+ "Corrupt the Honest" fires, printing "I'm an evil corporation and I
+ have corrupted X", where X is the name of the politician, and modifies
+ the politician's honest value to false. When the last honest politician
+ is corrupted, <code>Hope</code> is automatically retracted, by the truth
+ maintenance system, as shown by the blue highlighted area. The green
+ highlighted area shows the origin of the currently selected blue
+ highlighted area. Once the <code>Hope</code> fact is retracted, "Hope is
dead" activates and fires printing "We are all Doomed!!! Democracy is
Dead".</para>
Modified: labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-NumberGuessExample.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-NumberGuessExample.xml 2009-04-27 09:25:51 UTC (rev 26272)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-NumberGuessExample.xml 2009-04-27 09:26:18 UTC (rev 26273)
@@ -1,387 +1,382 @@
-<?xml version="1.0" encoding="UTF-8"?>
- <section version="5.0" xmlns="http://docbook.org/ns/docbook"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:xi="http://www.w3.org/2001/XInclude"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns:m="http://www.w3.org/1998/Math/MathML"
- xmlns:html="http://www.w3.org/1999/xhtml"
- xmlns:db="http://docbook.org/ns/docbook" xml:base="../../">
- <title>Number Guess</title>
-
- <programlisting><emphasis role="bold">Name:</emphasis> Number Guess
-<emphasis role="bold">Main class:</emphasis> org.drools.examples.NumberGuessExample
-<emphasis role="bold">Type:</emphasis> java application
-<emphasis role="bold">Rules file:</emphasis> NumberGuess.drl
-<emphasis role="bold">Objective:</emphasis> Demonstrate use of Rule Flow to organise Rules
-</programlisting>
-
- <para>The "Number Guess" example shows the use of RuleFlow, a way of
- controlling the order in which rules are fired. It uses widely
- understood workflow diagrams to make clear the order that groups of
- rules will be executed.</para>
-
- <example>
- <title>Creating the Number Guess RuleBase - extract 1 from
- NumberGuessExample.java main() method</title>
-
+<?xml version="1.0" encoding="UTF-8"?>
+<section version="5.0" xmlns="http://docbook.org/ns/docbook"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xi="http://www.w3.org/2001/XInclude"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:m="http://www.w3.org/1998/Math/MathML"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ xmlns:db="http://docbook.org/ns/docbook" xml:base="../../">
+ <title>Number Guess</title>
+
+ <programlisting><emphasis role="bold">Name:</emphasis> Number Guess
+<emphasis role="bold">Main class:</emphasis> org.drools.examples.NumberGuessExample
+<emphasis role="bold">Type:</emphasis> Java application
+<emphasis role="bold">Rules file:</emphasis> NumberGuess.drl
+<emphasis role="bold">Objective:</emphasis> Demonstrate use of Rule Flow to organise Rules
+</programlisting>
+
+ <para>The "Number Guess" example shows the use of Rule Flow, a way of
+ controlling the order in which rules are fired. It uses widely
+ understood workflow diagrams for defining the order in which groups
+ of rules will be executed.</para>
+
+ <example>
+ <title>Creating the Number Guess RuleBase: NumberGuessExample.main() - part 1</title>
+
<programlisting>final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
- kbuilder.add( ResourceFactory.newClassPathResource( "NumberGuess.drl",
- ShoppingExample.class ),
- ResourceType.DRL );
- kbuilder.add( ResourceFactory.newClassPathResource( "NumberGuess.rf",
- ShoppingExample.class ),
- ResourceType.DRF );
+kbuilder.add( ResourceFactory.newClassPathResource( "NumberGuess.drl",
+ ShoppingExample.class ),
+ ResourceType.DRL );
+kbuilder.add( ResourceFactory.newClassPathResource( "NumberGuess.rf",
+ ShoppingExample.class ),
+ ResourceType.DRF );
- final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
- kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
-
-</programlisting>
- </example>
-
- <para>The creation of the package, and the loading of the rules (using
- the add() method ) is the same as the previous examples.
- There is a additional line to add the RuleFlow (NumberGuess.rf) as you
- have the option of specifying different ruleflows for the same KnowledgeBase.
- Otherwise the KnowledgeBase is created in the same manner as before.</para>
-
- <example>
- <title>Starting the RuleFlow - extract 2 from NumberGuessExample.java
- main() method</title>
-
- <programlisting>final StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
+final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );</programlisting>
+ </example>
- KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "log/numberguess");
+ <para>The creation of the package and the loading of the rules (using
+ the <code>add()</code> method) is the same as the previous examples.
+ There is an additional line to add the Rule Flow
+ (<filename>NumberGuess.rf</filename>), which provides the option of
+ specifying different rule flows for the same Knowledge Base.
+ Otherwise, the Knowledge Base is created in the same manner as before.</para>
- ksession.insert( new GameRules( 100,
- 5 ) );
- ksession.insert( new RandomNumber() );
- ksession.insert( new Game() );
+ <example>
+ <title>Starting the RuleFlow: NumberGuessExample.main() - part 2</title>
- ksession.startProcess( "Number Guess" );
- ksession.fireAllRules();
+ <programlisting>final StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
- logger.close();
+KnowledgeRuntimeLogger logger =
+ KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "log/numberguess");
- ksession.dispose();
-
-</programlisting>
- </example>
-
- <para>Once we have a KnowledgeBase we can use it to obtain a stateful
- session. Into our session we insert our facts (standard Java Objects).
- For simplicity in this sample, these classes are all contained within
- our NumberGuessExample.java file. The GameRules class provides the
- maximum range and the number of guesses allowed. The RandomNumber class
- automatically generates a number between 0 and 100 and makes it
- available to our rules after insertion (via the getValue() method). The
- Game class keeps track of the guesses we have made before, and the
- number of guesses we have made.</para>
-
- <para>Note that before we call the standard fireAllRules() method, we
- also start the process that we loaded earlier (via the startProcess()
- method). We explain where to obtain the parameter we pass ("Number
- Guess" - the id of the ruleflow) when we talk about the RuleFlow file
- and the graphical RuleFlow editor below.</para>
-
- <para>Before we finish we our Java code , we note that In 'real life' we
- would examine the final state of the objects (e.g. how many guesses it
- took, so that we could add it to a high score table). For this example
- we are content to ensure the working memory session is cleared by
- calling the dispose() method.</para>
-
- <figure>
- <title>RuleFlow for the NumberGuess Example</title>
-
- <mediaobject>
- <imageobject>
- <imagedata width="100%"
- fileref="images/Chapter-Examples/NumberGuessExample/numberguess-ruleflow.png" />
- </imageobject>
- </mediaobject>
- </figure>
-
- <para>If you open the NumberGuess.rf file open in the Drools IDE (and
- have the JBoss Rules extensions installed correctly in Eclipse) you
- should see the above diagram, similar to a standard flowchart. Its icons
- are similar (but not exactly the same) as the JBoss jBPM workflow
- product. Should you wish to edit the diagram, a menu of available
- components should be available to the left of the diagram in the IDE,
- which is call the pallete. This diagram is saved in a (almost human)
- readable xml format, using xstream.</para>
-
- <para>If it is not already open, ensure the properties view is visible
- in the IDE. It can opened by selecting Window -> Show View ->
- Other and then select the Properties view. If you do this <emphasis
- role="bold">before</emphasis> you select any item on the RuleFlow (or
- click on blank space in the RuleFlow) you should be presented with the
- following set of properties.</para>
-
- <figure>
- <title>Properties for the Number Guess RuleFlow</title>
-
- <mediaobject>
- <imageobject>
- <imagedata width="100%"
- fileref="images/Chapter-Examples/NumberGuessExample/numberguess-ruleflow-properties.png" />
- </imageobject>
- </mediaobject>
- </figure>
-
- <para>Keep an eye on the properties view as we progress through the
- example RuleFlow as it gives valuable information. In this case it
- provides us with the ID of the RuleFlow process that we used in our
- earlier code example when we called session.startprocess().</para>
-
- <para>To give an overview of each of the node types (boxes) in the
- NumberGuess RuleFlow.</para>
-
- <para>
- <itemizedlist>
- <listitem>
- <para>The Start and End nodes (green arrow and red box) are where
- the RuleFlow starts and ends.</para>
- </listitem>
-
- <listitem>
- <para>RuleFlowGroup (simple yellow box). These map to the
- RuleFlowGroups in our rules (DRL) file that we will look at later.
- For example when the flow reaches the 'Too High' RuleFlowGroup,
- only those rules marked with an attribute of <emphasis
- role="bold">ruleflow-group "Too High" </emphasis> can potentially
- fire.</para>
- </listitem>
-
- <listitem>
- <para>Action Nodes (yellow box with cog like icon). These can
- perform standard Java method calls. Most action nodes in this
- example call System.out.println to give an indication to the user
- of what is going on.</para>
- </listitem>
-
- <listitem>
- <para>Split and Join Nodes (Blue Ovals) such as "Guess Correct"
- and "More Guesses Join" where the flow of control can split
- (according to various conditions) and / or rejoin.</para>
- </listitem>
-
- <listitem>
- <para>Arrows that indicate the flow between the various
- nodes.</para>
- </listitem>
- </itemizedlist>
- </para>
-
- <para>These various nodes work together with the Rules to make the
- Number Guess game work. For example, the "Guess" RuleFlowGroup allows
- only the rule "Get user Guess" to fire (details below) as only that Rule
- has a matching attribute of <emphasis role="bold">ruleflow-group
- "Guess"</emphasis></para>
-
- <example>
- <title>A Rule that will fire only a specific point in the RuleFlow -
- extract from NumberGuess.drl</title>
-
- <programlisting>rule "Get user Guess"
- ruleflow-group "Guess"
- no-loop
- when
- $r : RandomNumber()
- rules : GameRules( allowed : allowedGuesses )
- game : Game( guessCount < allowed )
- not ( Guess() )
- then
- System.out.println( "You have " + ( rules.allowedGuesses - game.guessCount )
- + " out of " + rules.allowedGuesses + " guesses left.\nPlease enter your guess
- from 0 to " + rules.maxRange );
- br = new BufferedReader( new InputStreamReader( System.in ) );
- modify ( game ) { guessCount = game.guessCount + 1 }
- i = br.readLine();
- insert( new Guess( i ) );
-end</programlisting>
- </example>
-
- <para>The rest of this rule is fairly standard : The <emphasis
- role="bold">LHS (when)</emphasis> section of the rule states that it
- will be activated for each <emphasis>RandomNumber</emphasis> object
- inserted into the working memory where <emphasis>guessCount</emphasis>
- is less than the <emphasis>allowedGuesses</emphasis> ( read from the
- GameRules Class) and where the user has not guessed the correct
- number.</para>
-
- <para>The <emphasis role="bold">RHS (consequence, then)</emphasis>
- prints a message to the user, then awaits user input from
- <emphasis>System.in. </emphasis> After getting this input (as System.in
- blocks until the <return> key is pressed) it updates/modifes the
- guess count, the actual guess and makes both available in the working
- memory.</para>
-
- <para>The rest of the Rules file is fairly standard ; the package
- declares the dialect is set to MVEL, various Java classes are imported.
- In total, there are five rules in this file:</para>
-
- <orderedlist>
- <listitem>
- <para>Get User Guess, the Rule we examined above.</para>
- </listitem>
-
- <listitem>
- <para>A Rule to record the highest guess.</para>
- </listitem>
-
- <listitem>
- <para>A Rule to record the lowest guess.</para>
- </listitem>
-
- <listitem>
- <para>A Rule to inspect the guess and retract it from memory if
- incorrect.</para>
- </listitem>
-
- <listitem>
- <para>A Rule that notifies the user that all guesses have been
- used up.</para>
- </listitem>
- </orderedlist>
-
- <para>One point of integration between the standard Rules and
- the RuleFlow is via the 'ruleflow-group' attribute on the rules (as
- dicussed above). A <emphasis role="bold">second point of integration
- between the Rules File (drl) and the Rules Flow .rf files </emphasis>is
- that the Split Nodes (the blue ovals) can use values in working memory
- (as updated by the Rules) to decide which flow of action to take. To see
- how this works click on the "Guess Correct Node" ; then within the
- properties view, open the constraints editor (the button at the right
- that appears once you click on the 'Constraints' property line). You
- should see something similar to the Diagram below.</para>
-
- <figure>
- <title>Edit Constraints for the GuessCorrect Node</title>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="images/Chapter-Examples/NumberGuessExample/numberguess-editconstraints.png" />
- </imageobject>
- </mediaobject>
- </figure>
-
- <para>Click on 'Edit' beside 'To node Too High' and you see a dialog
- like the one below. The values in the 'Textual Editor' follow the
- standard Rule Format (LHS) and can refer to objects in working memory.
- The consequence (RHS) is that the flow of control follows this node
- (i.e. To node Too high') if the LHS expression evaluates to true.</para>
-
- <figure>
- <title>Constraints Editor for the GuessCorrect Node / value too
- high</title>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="images/Chapter-Examples/NumberGuessExample/numberguess-constraint-toohigh.png" />
- </imageobject>
- </mediaobject>
- </figure>
-
- <para>Since the NumberGuess.java example contains a main() method, it
- can be run as a standard Java application (either from the command line
- or via the IDE). A typical game might result in the interaction below
- (the numbers in bold are typed in by the user).</para>
-
- <example>
- <title>Example Console output where the Number Guess Example beat the
- human!</title>
-
- <programlisting>You have 5 out of 5 guesses left.
-Please enter your guess from 0 to 100
-<emphasis role="bold">50</emphasis>
-Your guess was too high
-You have 4 out of 5 guesses left.
-Please enter your guess from 0 to 100
-<emphasis role="bold">25</emphasis>
-Your guess was too low
-You have 3 out of 5 guesses left.
-Please enter your guess from 0 to 100
-<emphasis role="bold">37</emphasis>
-Your guess was too low
-You have 2 out of 5 guesses left.
-Please enter your guess from 0 to 100
-<emphasis role="bold">44</emphasis>
-Your guess was too low
-You have 1 out of 5 guesses left.
-Please enter your guess from 0 to 100
-<emphasis role="bold">47</emphasis>
-Your guess was too low
-You have no more guesses
-The correct guess was 48
-
-</programlisting>
- </example>
-
- <para>A summary of what is happening in this sample is:</para>
-
-
- <orderedlist>
- <listitem>
- <para>Main() method of NumberGuessExample.java loads RuleBase,
- gets a StatefulSession and inserts Game, GameRules and
- RandomNumber (containing the target number) objects into it. This
- method sets the process flow we are going to use, and fires all
- rules. Control passes to the RuleFlow.</para>
- </listitem>
-
- <listitem>
- <para>The NumberGuess.rf RuleFlow begins at the Start node.</para>
- </listitem>
-
- <listitem>
- <para>Control passes (via the "more guesses" join node) to the
- Guess Node..</para>
- </listitem>
-
- <listitem>
- <para>At the Guess node, the appropriate RuleFlowGroup ("Get user
- Guess") is enabled. In this case the Rule "Guess" (in the
- NumberGuess.drl file) is triggered. This rule displays a message
- to the user, takes the response, and puts it into memory. Flow
- passes to the next Rule Flow Node.</para>
- </listitem>
-
- <listitem>
- <para>At the next node , "Guess Correct", constraints inspect the
- current session and decide which path we take next.</para>
-
- <para>If the guess in step 4 was too high / too low flow procees
- along a path which has (i) An action node with normal Java code
- prints a too high / too low statement and (ii) a RuleFlowGroup
- causes a highest guess / lowest guess Rule to be triggered in the
- Rules file. Flow passes from these nodes to step 6.</para>
-
- <para>If the guess in step 4 just right we proceed along the path
- towards the end of the Rule Flow. Before we get there, an action
- node with normal Java code prints a statement "you guessed
- correctly". There is a join node here (just before the Rule Flow
- End) so that our no-more-guesses path (step 7) can also terminate
- the RuleFlow.</para>
- </listitem>
-
- <listitem>
- <para>Control passes as per the RuleFlow via a join node, a guess
- incorrect RuleFlowGroup (triggers a rule to retract a guess from
- working memory) onto the "more guesses" decision node.</para>
- </listitem>
-
- <listitem>
- <para>The "more guesses" decision node (right hand side of
- ruleflow) uses constraints (again looking at values that the Rules
- have put into the working memory) to decide if we have more
- guesses and if so, goto step 3. If not we proceed to the end of
- the workflow, via a RuleFlowGroup that triggers a rule stating
- "you have no more guesses".</para>
- </listitem>
-
- <listitem>
- <para>The Loop 3-7 continues until the number is guessed
- correctly, or we run out of guesses.</para>
- </listitem>
- </orderedlist>
-
+ksession.insert( new GameRules( 100, 5 ) );
+ksession.insert( new RandomNumber() );
+ksession.insert( new Game() );
+
+ksession.startProcess( "Number Guess" );
+ksession.fireAllRules();
+
+logger.close();
+
+ksession.dispose();</programlisting>
+ </example>
+
+ <para>Once we have a Knowledge Base, we can use it to obtain a Stateful
+ Session. Into our session we insert our facts, i.e., standard Java objects.
+ (For simplicity, in this sample, these classes are all contained within
+ our <filename>NumberGuessExample.java</filename> file. Class
+ <code>GameRules</code> provides the maximum range and the number of guesses
+ allowed. Class <code>RandomNumber</code> automatically generates a number
+ between 0 and 100 and makes it available to our rules, by insertion via
+ the <code>getValue()</code> method. Class <code>Game</code> keeps track
+ of the guesses we have made before, and their number.</para>
+
+ <para>Note that before we call the standard <code>fireAllRules()</code>
+ method, we also start the process that we loaded earlier, via the
+ <code>startProcess()</code> method. We'll learn where to obtain the
+ parameter we pass ("Number Guess", i.e., the identifier of the rule flow)
+ when we talk about the rule flow file and the graphical Rule Flow Editor
+ below.</para>
+
+ <para>Before we finish the discussion of our Java code, we note that in
+ some real life application we would examine the final state of the objects.
+ (Here, we could retrieve the number of guesses, to add it to a high score
+ table.) For this example we are content to ensure that the Working Memory
+ session is cleared by calling the <code>dispose()</code> method.</para>
+
+ <figure>
+ <title>RuleFlow for the NumberGuess Example</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata width="100%"
+ fileref="images/Chapter-Examples/NumberGuessExample/numberguess-ruleflow.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>If you open the <filename>NumberGuess.rf</filename> file in the
+ Drools IDE (provided you have the JBoss Rules extensions installed
+ correctly in Eclipse) you should see the above diagram, similar to a
+ standard flowchart. Its icons are similar (but not exactly the same)
+ as in the JBoss jBPM workflow product. Should you wish to edit the
+ diagram, a menu of available components should be available to the
+ left of the diagram in the IDE, which is called the
+ <emphasis>palette</emphasis>. This diagram is saved in XML, an
+ (almost) human readable format, using XStream.</para>
+
+ <para>If it is not already open, ensure that the Properties View is
+ visible in the IDE. It can be opened by clicking "Window", then
+ "Show View" and "Other", where you can select the "Properties" view.
+ If you do this <emphasis>before</emphasis> you select any item on
+ the rule flow (or click on the blank space in the rule flow) you
+ should be presented with the following set of properties.</para>
+
+ <figure>
+ <title>Properties for the Number Guess Rule Flow</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata width="100%"
+ fileref="images/Chapter-Examples/NumberGuessExample/numberguess-ruleflow-properties.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Keep an eye on the Properties View as we progress through the
+ example's rule flow, as it gives valuable information. In this case, it
+ provides us with the identification of the Rule Flow Process that
+ we used in our earlier code snippet, when we called
+ <code>session.startProcess()</code>.</para>
+
+ <para>In the Number Guess rule flow, we encounter several node
+ types, sometimes identified by an icon.</para>
+
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>The Start node (white arrow in a green circle) and the End
+ node (red box) mark beginning and end of the rule flow.</para>
+ </listitem>
+
+ <listitem>
+ <para>A Rule Flow Group box (yellow, without an icon) represents
+ a Rule Flow Groups defined in our rules (DRL) file that we will
+ look at later. For example, when the flow reaches the Rule Flow Group
+ "Too High", only those rules marked with an attribute of
+ <kw>ruleflow-group</kw> <code>"Too High"</code> can potentially fire.</para>
+ </listitem>
+
+ <listitem>
+ <para>Action nodes (yellow, cog-shaped icon) perform standard Java
+ method calls. Most action nodes in this example call
+ <code>System.out.println()</code>, indicating the program's progress
+ to the user.</para>
+ </listitem>
+
+ <listitem>
+ <para>Split and Join Nodes (blue ovals, no icon) such as "Guess Correct?"
+ and "More guesses Join" mark places where the flow of control can
+ split, according to various conditions, and rejoin, respectively</para>
+ </listitem>
+
+ <listitem>
+ <para>Arrows indicate the flow between the various nodes.</para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>The various nodes in combination with the rules make the
+ Number Guess game work. For example, the "Guess" Rule Flow Group
+ allows only the rule "Get user Guess" to fire, because only that rule
+ has a matching attribute of <kw>ruleflow-group</kw> <code>"Guess"</code>.</para>
+
+ <example>
+ <title>A Rule firing only at a specific point in the Rule Flow:
+ NumberGuess.drl</title>
+
+ <programlisting>rule "Get user Guess"
+ ruleflow-group "Guess"
+ no-loop
+ when
+ $r : RandomNumber()
+ rules : GameRules( allowed : allowedGuesses )
+ game : Game( guessCount < allowed )
+ not ( Guess() )
+ then
+ System.out.println( "You have " + ( rules.allowedGuesses - game.guessCount )
+ + " out of " + rules.allowedGuesses
+ + " guesses left.\nPlease enter your guess from 0 to "
+ + rules.maxRange );
+ br = new BufferedReader( new InputStreamReader( System.in ) );
+ i = br.readLine();
+ modify ( game ) { guessCount = game.guessCount + 1 }
+ insert( new Guess( i ) );
+end</programlisting>
+ </example>
+
+ <para>The rest of this rule is fairly standard. The LHS section
+ (after <kw>when</kw>) of the rule states that it will be activated
+ for each <code>RandomNumber</code> object inserted into the Working
+ Memory where <code>guessCount</code> is less than
+ <code>allowedGuesses</code> from the <code>GameRules</code> object
+ and where the user has not guessed the correct number.</para>
+
+ <para>The RHS section (or consequence, after <kw>then</kw>) prints a
+ message to the user and then awaits user input from
+ <code>System.in</code>. After obtaining this input (the
+ <code>readLine()</code> method call blocks until the return key is
+ pressed) it calls modifies the guess count and inserts the new
+ guess, making both available to the Working Memory.</para>
+
+ <para>The rest of the rules file is fairly standard; the package
+ declares the dialect as MVEL, and various Java classes are imported.
+ In total, there are five rules in this file:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Get User Guess, the Rule we examined above.</para>
+ </listitem>
+
+ <listitem>
+ <para>A Rule to record the highest guess.</para>
+ </listitem>
+
+ <listitem>
+ <para>A Rule to record the lowest guess.</para>
+ </listitem>
+
+ <listitem>
+ <para>A Rule to inspect the guess and retract it from memory if
+ incorrect.</para>
+ </listitem>
+
+ <listitem>
+ <para>A Rule that notifies the user that all guesses have been
+ used up.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>One point of integration between the standard Rules and
+ the RuleFlow is via the 'ruleflow-group' attribute on the rules (as
+ dicussed above). A <emphasis role="bold">second point of integration
+ between the Rules File (drl) and the Rules Flow .rf files </emphasis>is
+ that the Split Nodes (the blue ovals) can use values in working memory
+ (as updated by the Rules) to decide which flow of action to take. To see
+ how this works click on the "Guess Correct Node" ; then within the
+ properties view, open the constraints editor (the button at the right
+ that appears once you click on the 'Constraints' property line). You
+ should see something similar to the Diagram below.</para>
+
+ <figure>
+ <title>Edit Constraints for the GuessCorrect Node</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/Chapter-Examples/NumberGuessExample/numberguess-editconstraints.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Click on 'Edit' beside 'To node Too High' and you see a dialog
+ like the one below. The values in the 'Textual Editor' follow the
+ standard Rule Format (LHS) and can refer to objects in working memory.
+ The consequence (RHS) is that the flow of control follows this node
+ (i.e. To node Too high') if the LHS expression evaluates to true.</para>
+
+ <figure>
+ <title>Constraints Editor for the GuessCorrect Node / value too
+ high</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/Chapter-Examples/NumberGuessExample/numberguess-constraint-toohigh.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Since the NumberGuess.java example contains a main() method, it
+ can be run as a standard Java application (either from the command line
+ or via the IDE). A typical game might result in the interaction below
+ (the numbers in bold are typed in by the user).</para>
+
+ <example>
+ <title>Example Console output where the Number Guess Example beat the
+ human!</title>
+
+ <programlisting>You have 5 out of 5 guesses left.
+Please enter your guess from 0 to 100
+<emphasis role="bold">50</emphasis>
+Your guess was too high
+You have 4 out of 5 guesses left.
+Please enter your guess from 0 to 100
+<emphasis role="bold">25</emphasis>
+Your guess was too low
+You have 3 out of 5 guesses left.
+Please enter your guess from 0 to 100
+<emphasis role="bold">37</emphasis>
+Your guess was too low
+You have 2 out of 5 guesses left.
+Please enter your guess from 0 to 100
+<emphasis role="bold">44</emphasis>
+Your guess was too low
+You have 1 out of 5 guesses left.
+Please enter your guess from 0 to 100
+<emphasis role="bold">47</emphasis>
+Your guess was too low
+You have no more guesses
+The correct guess was 48
+
+</programlisting>
+ </example>
+
+ <para>A summary of what is happening in this sample is:</para>
+
+
+ <orderedlist>
+ <listitem>
+ <para>Main() method of NumberGuessExample.java loads RuleBase,
+ gets a StatefulSession and inserts Game, GameRules and
+ RandomNumber (containing the target number) objects into it. This
+ method sets the process flow we are going to use, and fires all
+ rules. Control passes to the RuleFlow.</para>
+ </listitem>
+
+ <listitem>
+ <para>The NumberGuess.rf RuleFlow begins at the Start node.</para>
+ </listitem>
+
+ <listitem>
+ <para>Control passes (via the "more guesses" join node) to the
+ Guess Node..</para>
+ </listitem>
+
+ <listitem>
+ <para>At the Guess node, the appropriate RuleFlowGroup ("Get user
+ Guess") is enabled. In this case the Rule "Guess" (in the
+ NumberGuess.drl file) is triggered. This rule displays a message
+ to the user, takes the response, and puts it into memory. Flow
+ passes to the next Rule Flow Node.</para>
+ </listitem>
+
+ <listitem>
+ <para>At the next node , "Guess Correct", constraints inspect the
+ current session and decide which path we take next.</para>
+
+ <para>If the guess in step 4 was too high / too low flow procees
+ along a path which has (i) An action node with normal Java code
+ prints a too high / too low statement and (ii) a RuleFlowGroup
+ causes a highest guess / lowest guess Rule to be triggered in the
+ Rules file. Flow passes from these nodes to step 6.</para>
+
+ <para>If the guess in step 4 just right we proceed along the path
+ towards the end of the Rule Flow. Before we get there, an action
+ node with normal Java code prints a statement "you guessed
+ correctly". There is a join node here (just before the Rule Flow
+ End) so that our no-more-guesses path (step 7) can also terminate
+ the RuleFlow.</para>
+ </listitem>
+
+ <listitem>
+ <para>Control passes as per the RuleFlow via a join node, a guess
+ incorrect RuleFlowGroup (triggers a rule to retract a guess from
+ working memory) onto the "more guesses" decision node.</para>
+ </listitem>
+
+ <listitem>
+ <para>The "more guesses" decision node (right hand side of
+ ruleflow) uses constraints (again looking at values that the Rules
+ have put into the working memory) to decide if we have more
+ guesses and if so, goto step 3. If not we proceed to the end of
+ the workflow, via a RuleFlowGroup that triggers a rule stating
+ "you have no more guesses".</para>
+ </listitem>
+
+ <listitem>
+ <para>The Loop 3-7 continues until the number is guessed
+ correctly, or we run out of guesses.</para>
+ </listitem>
+ </orderedlist>
+
</section>
Modified: 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 2009-04-27 09:25:51 UTC (rev 26272)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Examples/Section-SodukiExample.xml 2009-04-27 09:26:18 UTC (rev 26273)
@@ -10,7 +10,7 @@
<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">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>
More information about the jboss-svn-commits
mailing list