[jboss-svn-commits] JBL Code SVN: r15356 - labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Tue Sep 25 05:31:12 EDT 2007
Author: michael.neale at jboss.com
Date: 2007-09-25 05:31:12 -0400 (Tue, 25 Sep 2007)
New Revision: 15356
Modified:
labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/Section-Examples.xml
Log:
added example doco for golfer
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-25 08:01:23 UTC (rev 15355)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/Section-Examples.xml 2007-09-25 09:31:12 UTC (rev 15356)
@@ -900,11 +900,209 @@
<programlisting><emphasis role="bold">Name:</emphasis> Golfing
<emphasis role="bold">Main class:</emphasis> org.drools.examples.GolfingExample
<emphasis role="bold">Type:</emphasis> java application
-<emphasis role="bold">Rules file:</emphasis> golfing.drl
+<emphasis role="bold">Rules file:</emphasis> golf.drl
<emphasis role="bold">Objective:</emphasis> Configuration example that finds the solution from a large number of available cross products
</programlisting>
- <para></para>
+ <para>The golf example solves a "riddle" style problem that is simple
+ enough to state in sentences, but for which a conventional algorithmic
+ solition is not obvious. It does this by searching for a suitable
+ combination from a "space" of possible solutions.</para>
+
+ <section>
+ <title>The riddle</title>
+
+ <para>The problem is written as a riddle:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>A foursome of golfers is standing at a tee, in a line from
+ left to right.</para>
+ </listitem>
+
+ <listitem>
+ <para>Each golfer wears different colored pants; one is wearing red
+ pants.</para>
+ </listitem>
+
+ <listitem>
+ <para>The golfer to Fred’s immediate right is wearing blue
+ pants.</para>
+ </listitem>
+
+ <listitem>
+ <para>Joe is second in line.</para>
+ </listitem>
+
+ <listitem>
+ <para>Bob is wearing plaid pants.</para>
+ </listitem>
+
+ <listitem>
+ <para>Tom isn’t in position one or four, and he isn’t wearing the
+ hideous orange pants.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>The immediate thing about this riddle, is that a solution is not
+ obvious (of course ! it wouldn't be a riddle otherwise !). It also isn't
+ obvious how to write an algorithm to solve it (if it is for you - then
+ you can take a break now, go have a coffee or someting to reward your
+ uber intellect).</para>
+
+ <para>Instead of thinking about how to solve it, we can be lazy and use
+ rules instead. So we don't attempt to solve it, we just state the
+ problem in rules, and let the engine derive the solution.</para>
+ </section>
+
+ <section>
+ <title>Launching the example</title>
+
+ <para>The supporting code is in the GolfingExample.java class. There is
+ an inner class "Golfer" which represents a golf player, it has their
+ name, position (1 to 4 meaning left to right), and their pants color, as
+ simple properties.</para>
+
+ <programlisting>
+ String[] names = new String[] { "Fred", "Joe", "Bob", "Tom" };
+ String[] colors = new String[] { "red", "blue", "plaid", "orange" };
+ int[] positions = new int[] { 1, 2, 3, 4 };
+
+ for ( int n = 0; n < names.length; n++ ) {
+ for ( int c = 0; c < colors.length; c++ ) {
+ for ( int p = 0; p < positions.length; p++ ) {
+ session.insert( new Golfer( names[n], colors[c], positions[p]) );
+ }
+ }
+ }
+ </programlisting>
+
+ <para>The above listing shows the interesting part of the supporting
+ code. Note that we have arrays representing each name, color, and
+ position. We then go through a nested loop inserting instances of Golfer
+ - so in the working memory we will have all combinations of name, color
+ and position. It is then the job of the rules to find the appropriate
+ one.</para>
+
+ <para>Launching the code as a java application should yield the
+ following output:</para>
+
+ <programlisting>
+Fred 1 orange
+Joe 2 blue
+Bob 4 plaid
+Tom 3 red
+ </programlisting>
+
+ <para>This shows that the rule(s) have found a suitable solution.</para>
+ </section>
+
+ <section>
+ <title>The matching rule</title>
+
+ <para>The solution in rules is quite simple, it is a single rule which
+ expresses the constraints as stated in the riddle. Effectively, we can
+ interpret the riddle as a series of constraints on our object model.
+ Given that we have enough "combinations" in the working memory, all we
+ have to do is express the constraints in a rule and the engine will
+ match it with a solution (we don't really care how it does it, as long
+ as it works !).</para>
+
+ <para>There is one rule in the solution, in golf.drl, called "find
+ solution". The rule is made up of 5 patterns, with constraints that map
+ to items in the riddle.</para>
+
+ <programlisting>
+ $fred : Golfer( name == "Fred" )
+ </programlisting>
+
+ <para>In the above pattern, we are simply matching a Golfer who is
+ called fred, and binding it to a variable called $fred. All that we know
+ is that there is a golfer called fred.</para>
+
+ <programlisting>
+ $joe : Golfer( name == "Joe",
+ position == 2,
+ position != $fred.position,
+ color != $fred.color )
+ </programlisting>
+
+ <para>The next pattern says that we have a golfer named Joe, in position
+ 2 ("second in line"). Now, we also know that he must NOT be in the same
+ position as fred (of course !) and have different color pants. So far,
+ nothing that amazing.</para>
+
+ <programlisting>
+ $bob : Golfer( name == "Bob",
+ position != $fred.position,
+ position != $joe.position,
+ color == "plaid",
+ color != $fred.color,
+ color != $joe.color )
+ </programlisting>
+
+ <para>Refering to the above, we also know there is a golfer called Bob,
+ who wears plaid pants - once again that all we know about him. but of
+ course, we add in the constraints that he must be in a different
+ position to fred, joe, and also have different colored pants.</para>
+
+ <programlisting>
+ $tom : Golfer( name == "Tom",
+ position != 1,
+ position != 4,
+ position != $fred.position,
+ position != $joe.position,
+ position != $bob.position,
+ color != "orange,
+ color != $fred.color,
+ color != $joe.color,
+ color != $bob.color )
+ </programlisting>
+
+ <para>(referring to the above) We also know that there is a guy called
+ Tom, who doesn't wear the Orange pants, AND he is not in position 1, or
+ 4. Of course we also add in the other constraints (he must be in a
+ different position to the others so far, and have a different
+ color).</para>
+
+ <programlisting>
+ Golfer( position == ( $fred.position + 1 ),
+ color == "blue",
+ this in ( $joe, $bob, $tom ) )
+ </programlisting>
+
+ <para>Finally, we know that the golfer on the right of Fred (position +
+ 1), is in blue pants. We also add in the constraint that he must be
+ either Joe, Bob or Tom (as Fred can't be beside himself, well he can I
+ guess, but not in the sense we mean here !) - note the use of "this" to
+ refer to the current pattern, we don't really care who "this" is, just
+ who they are not. Maybe if Fred was really really happy they this
+ wouldn't work, but lets assume otherwise for now.</para>
+
+ <para>Thats it ! We have expressed the rule as constraints that map to
+ the ones expressed in the riddle, yet we haven't had to solve the
+ riddle, the engine does that for us.</para>
+ </section>
+
+ <section>
+ <title>Conclustion</title>
+
+ <para>This simple example shows how you can express a problem
+ declaratively, and let the engine solve the problem for you, by making
+ use of combinations. This is an often useful technique, as it allows you
+ to express rules as a statement of the problem you are trying to solve.
+ </para>
+
+ <para>Of course, care must be taken. Using combinatorics like this can
+ cause performance problems when there are large numbers of facts (eg in
+ this case, if there were a larger number of golfers, or colors/positions
+ etc - possibilities). When the fact count grows, the combinations the
+ engine has to deal with can explode exponentially, making this not very
+ efficient. However, in cases where the rules are perhaps complex, the
+ problem is hard, but the fact numbers are relatively low, this approach
+ can be very very useful and help you solve problems that would otherwise
+ be very hard.</para>
+ </section>
</section>
<section>
More information about the jboss-svn-commits
mailing list