[jboss-svn-commits] JBL Code SVN: r15179 - labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Sep 17 18:38:19 EDT 2007
Author: mark.proctor at jboss.com
Date: 2007-09-17 18:38:18 -0400 (Mon, 17 Sep 2007)
New Revision: 15179
Added:
labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/numberguess-constraint-toohigh.png
labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/numberguess-editconstraints.png
labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/numberguess-ruleflow-properties.png
labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/numberguess-ruleflow.png
Modified:
labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/Section-Examples.xml
Log:
JBRULES-1200 Documentation for Number Guess Example
-added number guess example, curtesy of Paul Browne
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/Section-Examples.xml
===================================================================
--- labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/Section-Examples.xml 2007-09-17 17:44:00 UTC (rev 15178)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/Section-Examples.xml 2007-09-17 22:38:18 UTC (rev 15179)
@@ -1414,6 +1414,380 @@
</section>
<section>
+ <section>
+ <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 a 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>
+
+ <programlisting>final PackageBuilder builder = new PackageBuilder();
+
+builder.addPackageFromDrl( new InputStreamReader(
+ ShoppingExample.class.getResourceAsStream( "NumberGuess.drl" ) ) );
+builder.addRuleFlow( new InputStreamReader(
+ ShoppingExample.class.getResourceAsStream( "NumberGuess.rfm" ) ) );
+
+final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+ruleBase.addPackage( builder.getPackage() );
+
+</programlisting>
+ </example>
+
+ <para>The creation of the package, and the loading of the rules (using
+ the addPackageFromDrl() method ) is the same as the previous examples.
+ There is a additional line to add the RuleFlow (NumberGuess.rfm) as you
+ have the option of specifying different ruleflows for the same RuleBase.
+ Otherwise the RuleBase is created in the same manner as before .</para>
+
+ <example>
+ <title>Starting the RuleFlow - extract 2 from NumberGuessExample.java
+ main() method</title>
+
+ <programlisting>final StatefulSession session = ruleBase.newStatefulSession();
+
+session.insert( new GameRules( 100, 5 ) );
+session.insert( new RandomNumber() );
+session.insert( new Game() );
+
+session.startProcess( "Number Guess" );
+session.fireAllRules();
+
+session.dispose();
+
+</programlisting>
+ </example>
+
+ <para>Once we have a RuleBase 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 example 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 fileref="numberguess-ruleflow.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>If you open the NumberGuess.rf file open in the Drools IDE (or
+ have the JBoss Rules extensions installed correctly in Eclipse) you
+ should see the above digaram, similar to a standard flowchart. It's
+ 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.
+ This diagram is saved in a (almost human) readable xml format.</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 fileref="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 is
+ stated the dialect is set to MVEL, various Java classes are imported. In
+ total, there are five rules in this file:</para>
+
+ <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>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="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="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>
+
+ <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>
+ </para>
+ </section>
+ </section>
+
+ <section>
<title>Miss Manners and Benchmarking</title>
<programlisting><emphasis role="bold">Name:</emphasis> Miss Manners
Added: labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/numberguess-constraint-toohigh.png
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/numberguess-constraint-toohigh.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/numberguess-editconstraints.png
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/numberguess-editconstraints.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/numberguess-ruleflow-properties.png
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/numberguess-ruleflow-properties.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/numberguess-ruleflow.png
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/numberguess-ruleflow.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
More information about the jboss-svn-commits
mailing list