[jboss-svn-commits] JBL Code SVN: r26096 - labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Quick_Start.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Apr 17 05:35:59 EDT 2009


Author: laune
Date: 2009-04-17 05:35:59 -0400 (Fri, 17 Apr 2009)
New Revision: 26096

Modified:
   labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Quick_Start/Section-The_Basics.xml
Log:
improvements

Modified: labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Quick_Start/Section-The_Basics.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Quick_Start/Section-The_Basics.xml	2009-04-17 09:35:45 UTC (rev 26095)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Quick_Start/Section-The_Basics.xml	2009-04-17 09:35:59 UTC (rev 26096)
@@ -17,7 +17,7 @@
       beguiling. Have no fear my intrepid adventurer, the complexity is
       layered and you can ease yourself into with simple use cases.</para>
 
-      <para>Stateless session, not utilising inference, forms the simplest of
+      <para>Stateless session, not utilising inference, forms the simplest
       use case. A stateless session can be called like a function passing it
       some data and then receiving some results back. Some common use cases
       for stateless sessions are, but not limited to:</para>
@@ -28,7 +28,7 @@
 
           <itemizedlist>
             <listitem>
-              <para>Is this person legible for a mortgage</para>
+              <para>Is this person eligible for a mortgage?</para>
             </listitem>
           </itemizedlist>
         </listitem>
@@ -38,28 +38,28 @@
 
           <itemizedlist>
             <listitem>
-              <para>Mortgage premium</para>
+              <para>Compute a mortgage premium.</para>
             </listitem>
           </itemizedlist>
         </listitem>
 
         <listitem>
-          <para>Routing/Filtering</para>
+          <para>Routing and Filtering</para>
 
           <itemizedlist>
             <listitem>
-              <para>Filtering incoming messages, such as emails, into
-              folders</para>
+              <para>Filter incoming messages, such as emails, into
+              folders.</para>
             </listitem>
 
             <listitem>
-              <para>Sending incoming message to a destinatino</para>
+              <para>Send incoming messages to a destination.</para>
             </listitem>
           </itemizedlist>
         </listitem>
       </itemizedlist>
 
-      <para>So lets start with a very simple example using a driving license
+      <para>So let's start with a very simple example using a driving license
       application.</para>
 
       <programlisting>public class Applicant {
@@ -70,11 +70,10 @@
 }
 </programlisting>
 
-      <para>Now we have our data model we can write our first rule, we assume
-      the application starts off valid and rules would be used to disqualify
-      the application. As this is a simple validation use case we will add a
-      single rule to disqualify the applicant if they are younger than
-      18.</para>
+      <para>Now that we have our data model we can write our first rule. We
+      assume that the application uses rules to refute invalid applications.
+      As this is a simple validation use case we will add a
+      single rule to disqualify any applicant younger than 18.</para>
 
       <programlisting>package com.company.license
 
@@ -88,17 +87,19 @@
       <para>To make the engine aware of data, so it can be processed against
       the rules, we have to "insert" the data, much like with a database. When
       the Applicant instance is inserted into the engine it is evaluated
-      against the constraints of the rules, in this case just two constraint
-      for one rule. We say two because the type Applicant is the first object
-      type constraint, and the "age &lt; 18" is the second field constraint.
-      An object type constraint plus it's zero or more field constraints is
+      against the constraints of the rules, in this case just two constraints
+      for one rule. We say <emphasis>two</emphasis> because the type Applicant
+      is the first object
+      type constraint, and "age &lt; 18" is the second field constraint.
+      An object type constraint plus its zero or more field constraints is
       referred to as a pattern. When an inserted instance satisfies both the
       object type constraint and all the field constraints, it is said to be
-      matched. The "$a" is a binding and allows the matched object to be
-      referenced in the consquence, so it's properties can be updated, the $
-      is optional, but it helps to differentiate the variables from the
-      fields. This part of the engine is often referred to as pattern matchin,
-      i.e. the matching of patterns against the inserted data.</para>
+      matched. The "$a" is a binding variable which permits us to reference
+      the matched object in the consequence. There its properties can be
+      updated. The dollar character ('$') is optional, but it helps to
+      differentiate variable names from field names. The process of
+      matching patterns against the inserted data is, not surprisingly,
+      often referred to as <emphasis>pattern matching</emphasis>.</para>
 
       <para>Let's assume that the rules are in the same folder as the classes,
       so we can use the classpath resource loader to build our first
@@ -112,9 +113,9 @@
     System.err.println( builder.getErrors().toString() );
 }  </programlisting>
 
-      <para>The above looks on the classpath for the "licenseApplication.drl"
-      file, using the given classes getResource() method. The ResourceType
-      here is DRL, short for "Drools Rule Language". Once the drl has be added
+      <para>The above code snippet looks on the classpath for the "licenseApplication.drl"
+      file, using the method newClasspathResource(). The ResourceType
+      is DRL, short for "Drools Rule Language". Once the DRL file has been added
       we can check the KnowledgeBuilder for any errors. If there are no
       errors, we are now ready to build our session and execute against some
       data:</para>
@@ -126,13 +127,13 @@
 assertFalse( applicant.isValid() );
 </programlisting>
 
-      <para>The above executes the data against the rules, the applicant is
-      under the age of 18, so it marked invalid.</para>
+      <para>The preceding code executes the data against the rules. Since the applicant is
+      under the age of 18, the application is marked as invalid.</para>
 
-      <para>So far we've only used a single instance, but what if want to use
-      more than one? We can also execute against an Iterable, such a a
-      collection. Lets add another class called Application, which has the
-      date of the application and we'll move the boolean valid field to the
+      <para>So far we've only used a single instance, but what if we want to use
+      more than one? We can execute against any object implementing Iterable, such as
+      a collection. Let's add another class called Application, which has the
+      date of the application, and we'll also move the boolean valid field to the
       Application class.</para>
 
       <programlisting>public class Applicant {
@@ -141,14 +142,13 @@
     // getter and setter methods here
 }
 
-
 public class Application {
     private Date dateApplied;
     private boolean valid;
     // getter and setter methods here
 }</programlisting>
 
-      <para>And we can also add another rule, that validates the Application
+      <para>We can also add another rule to validate that the Application
       was made within a period of time.</para>
 
       <programlisting>package com.company.license
@@ -169,9 +169,9 @@
 end
 </programlisting>
 
-      <para>Unfortunately in java an array does not implement h the Iterable
-      interface, so we have to use the JDK converter, asList(...). So code
-      below executes against an Iterable, where each of the collection
+      <para>Unfortunately in Java an array does not implement the Iterable
+      interface, so we have to use the JDK converter asList(...). The code
+      shown below executes against an Iterable, where all collection
       elements are inserted before any matched rules are fired.</para>
 
       <programlisting>StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();
@@ -182,19 +182,18 @@
 assertFalse( application() );
 </programlisting>
 
-      <para>The two execute methods execute(Object object ) and
+      <para>The two execute methods execute(Object object) and
       execute(Iterable objects) are actually convenience methods for the
       interface BatchExecutor's method execute(Command command).</para>
 
-      <para>The CommandFactory is used to return commands, the following is
-      equivalent of execute( Iterable it ):</para>
+      <para>The CommandFactory is used to create commands, so that the following is
+      equivalent to execute( Iterable it ):</para>
 
       <programlisting>ksession.execute( CommandFactory.newInsertIterable( new Object[] { application, applicant } ) );
 </programlisting>
 
-      <para>Where the the BatchExecutor and CommandFactory becomes useful is
-      while working with multiple Commands and out identifiers for
-      results.</para>
+      <para>BatchExecutor and CommandFactory are particularly useful when working
+      with multiple Commands and output identifiers for results.</para>
 
       <programlisting>List&lt;Command&gt; cmds = new ArrayList&lt;Command&gt;();
 cmds.add( CommandFactory.newInsert( new Person( "Mr John Smith" ), "mrSmith" );
@@ -204,7 +203,7 @@
 </programlisting>
 
       <para>CommandFactory supports many other Commands that can be used in
-      the BatchExecutor like StartProcess, Query, SetGlobal.</para>
+      the BatchExecutor like StartProcess, Query, and SetGlobal.</para>
     </section>
 
     <section>
@@ -220,7 +219,7 @@
 
           <itemizedlist>
             <listitem>
-              <para>Stock market monitorig and analysis for semi-automatic
+              <para>Stock market monitoring and analysis for semi-automatic
               buying.</para>
             </listitem>
           </itemizedlist>
@@ -231,7 +230,7 @@
 
           <itemizedlist>
             <listitem>
-              <para>fault finding, medical diagnostics</para>
+              <para>Fault finding, medical diagnostics</para>
             </listitem>
           </itemizedlist>
         </listitem>
@@ -241,7 +240,7 @@
 
           <itemizedlist>
             <listitem>
-              <para>parcel tracking and delivery provisioning</para>
+              <para>Parcel tracking and delivery provisioning</para>
             </listitem>
           </itemizedlist>
         </listitem>
@@ -260,14 +259,14 @@
       <para>Unlike a stateless session the dispose() method must be called
       afterwards to ensure there are no memory leaks, as the KnowledgeBase
       contains references to StatefulKnowledgeSessions when they are created.
-      StatefulKnowledgeSession also supports the BatchExecutor interface like
-      StatelessKnowledgeSession, the only difference is that when used with
-      stateful the FireAllRules command is not automatically called at the
-      end.</para>
+      StatefulKnowledgeSession also supports the BatchExecutor interface, like
+      StatelessKnowledgeSession, the only difference being that 
+      the FireAllRules command is not automatically called at the
+      end for a stateful session.</para>
 
-      <para>We can use a fire alarm example to explore the monitoring use
-      case. The simple example has just 4 classes. We are monitoring the rooms
-      in a house, each room has one sprinkler. If a fire starts in a room, we
+      <para>We illustrate the monitoring use case with an example for raising a
+      fire alarm. Using just 4 classes, we represent rooms in a house, each of which
+      has one sprinkler. If a fire starts in a room, we
       represent that with a single Fire instance.</para>
 
       <programlisting>public class Room {
@@ -289,18 +288,18 @@
 
       <para>In the previous section on stateless sessions the concepts of
       inserting and matching against data was introduced. That example assumed
-      only a single instance of each object type was ever inserted and thus
-      only used literal constraints. However a house has many rooms, so rules
-      have the need to express joins that constraint to the desired objects,
-      this can be done using a binding as a variable constraint in a pattern.
-      This join process results in what is called cross products, which are
+      that only a single instance of each object type was ever inserted and thus
+      only used literal constraints. However, a house has many rooms, so rules
+      must express relationships between objects, such as a sprinkler being in
+      a certain room. This is best done by using a binding variable as a constraint
+      in a pattern. This "join" process results in what is called cross products, which are
       covered in the next section.</para>
 
       <para>When a fire occurs an instance of the Fire class is created, for
-      that room, and insert it. The rule uses a binding on the room field of
-      the Fire to constrain to the Sprinkler for that room, which is currently
-      off. When this rule fires and the consequence is executed the sprinkler
-      is turned on</para>
+      that room, and inserted into the session. The rule uses a binding on the "room"
+      field of the Fire object to constrain matching to the Sprinkler for that room,
+      which is currently  off. When this rule fires and the consequence is executed
+      the sprinkler is turned on</para>
 
       <programlisting>rule "When there is a fire turn on the sprinkler"
 when
@@ -311,24 +310,26 @@
     System.out.println( "Turn on the sprinkler for room " + $room.getName() );
 end</programlisting>
 
-      <para>Where as the stateless session used standard java syntax to modify
-      a field, in the above rule we use the modify keyword, which acts as a
-      sort of with statement, that contains a series of comma separated java
-      expressions. Stateless sessions typically do not use inference, which
-      can be explicitly turned off by using the "sequential mode", so the
-      engine does not need to be aware of changes to data, however a stateful
-      session does. The modify keyword allows the setters to modify the data,
-      while make the engine aware of those changes so it can reason over them,
-      this process is called inference.</para>
+      <para>Whereas the stateless session used standard Java syntax to modify
+      a field, in the above rule we use the "modify" statement, which acts as a
+      sort of "with" statement. It may contain a series of comma separated Java
+      expressions, calls to setters of the object selected by the "modify" control
+      expression. This modifies the data, and makes the engine aware of those changes
+      so it can reason over them once more. This process is called inference, and
+      it's essential for the working of a stateful session. Stateless sessions 
+      typically do not use inference, so the engine does not need to be aware of 
+      changes to data. Inference can also be turned off explicitly by using the
+      "sequential mode".</para>
 
       <para>So far we have rules that tell us when matching data exists, but
-      what about when it doesn't exist? What about when there stops being a
-      Fire? Previously the constraints have been propositional logic where the
-      engine is constraining against individual intances, Drools also has
-      support for first order logic that allows you to look at sets of data.
-      The 'not' keyword matches when something does not exist. So for a Room
-      with a Sprinkler that is on when the Fire for that room stops existing
-      we can turn off the sprinkler.</para>
+      what about when it does <emphasis>not</emphasis> exist? How do we determine
+      that a Fire has been extinguished, i.e., there isn't a Fire object any more.
+      Previously the constraints have been sentences according to Propositional Logic,
+      where the engine is constraining against individual intances. Drools also has
+      support for First Order Logic that allows you to look at sets of data.
+      The 'not' keyword matches when something does not exist. The rule given
+      below turns the Sprinkler off as soon as the Fire in that room has
+      disappeared.</para>
 
       <programlisting>rule "When the fire is gone turn off the sprinkler"
 when
@@ -341,10 +342,11 @@
 end</programlisting>
 
       <para>While there is a Sprinkler per room, there is just a single Alarm
-      for the building. An Alarm is created when a Fire is occurs, but only
+      for the building. An Alarm is created when a Fire occurs, but only
       one Alarm is needed for the entire building, no matter how many Fires
-      occur. Previously 'not' was introduced, the compliment to ths is
-      'exists' which matches for one or more of something.</para>
+      occur. Previously 'not' was introduced to match the absence of a fact;
+      now we use its complement 'exists' which matches for one or more of
+      something.</para>
 
       <programlisting>rule "Raise the alarm when we have one or more fires"
 when
@@ -354,16 +356,16 @@
     System.out.println( "Raise the alarm" );
 end</programlisting>
 
-      <para>Likewise when there are no Fires we want to remove the alarm, so
+      <para>Likewise, when there are no Fires we want to remove the alarm, so
       the 'not' keyword can be used again.</para>
 
-      <programlisting>rule "Lower the alarm when all the fires have gone"
+      <programlisting>rule "Cancel the alarm when all the fires have gone"
 when
     not Fire()
     $alarm : Alarm()
 then
     retract( $alarm );
-    System.out.println( "Lower the alarm" );
+    System.out.println( "Cancel the alarm" );
 end
 
 </programlisting>
@@ -381,10 +383,10 @@
 end</programlisting>
 
       <para>The above rules should be placed in a single drl file and saved to
-      the classpath using the file name "fireAlarm.drl", as per the stateless
-      session example. We can then build a KnowledgeBase as before, just using
-      the new name "fireAlarm.drl". The difference is this time we create a
-      stateful session from the kbase, where as before we created a stateless
+      the classpath using the file name "fireAlarm.drl", as in the stateless
+      session example. We can then build a KnowledgeBase, as before, just using
+      the new name "fireAlarm.drl". The difference is that this time we create a
+      stateful session from the kbase, whereas before we created a stateless
       session.</para>
 
       <programlisting>KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
@@ -397,46 +399,35 @@
 
       <para>With the session created it is now possible to iteratvely work
       with it over time. Four Rooms are created and inserted, a Sprinkler for
-      each room is also inserted. At this point the engine has done all it's
-      matching, but no rules have fired. calling "fireAllRules" on the
-      ksession allows the matched rules to fire, currently that is just the
-      health message.</para>
+      each room is also inserted. At this point the engine has done all of its
+      matching, but no rules have fired yet. Calling "fireAllRules" on the
+      ksession allows the matched rules to fire, but without a fire that will
+      just produce the health message.</para>
 
-      <programlisting>Room kitchen = new Room( "kitchen" );
-Room bedroom = new Room( "bedroom" );
-Room office = new Room( "office" );
-Room livingRoom = new Room( "livingroom" );
+      <programlisting>String[] names = new String[]{"kitchen", "bedroom", "office", "livingroom"};
+Map&lt;String,Room&gt; name2room = new HashMap&lt;String,Room&gt;();
+for( String name: names ){
+    Room room = new Room( name );
+    name2room.put( name, room );
+    ksession.insert( room );
+    Sprinkler sprinkler = new Sprinkler( room );
+    ksession.insert( sprinkler );
+}
 
-ksession.insert( kitchen );
-ksession.insert( bedroom );
-ksession.insert( office );
-ksession.insert( livingRoom );
-
-Sprinkler kitchenSprinkler = new Sprinkler( kitchen );
-Sprinkler bedroomSprinkler = new Sprinkler( bedroom );
-Sprinkler officeSprinkler = new Sprinkler( office );
-Sprinkler livingRoomSprinkler = new Sprinkler( livingRoom );
-
-
-ksession.insert( kitchenSprinkler );
-ksession.insert( bedroomSprinkler );
-ksession.insert( officeSprinkler );
-ksession.insert( livingRoomSprinkler );
-
 ksession.fireAllRules()
 </programlisting>
 
       <programlisting>&gt; Everything is ok</programlisting>
 
-      <para>We now create two fires and insert them, this time a referenced is
+      <para>We now create two fires and insert them, this time a reference is
       kept for the returned FactHandle. The FactHandle is an internal engine
-      reference to the inserted instance and allows that instance to be
+      reference to the inserted instance and allows instances to be
       retracted or modified at a later point in time. With the Fires now in
       the engine, once "fireAllRules" is called, the Alarm is raised and the
-      respectively Sprinklers are turned on.</para>
+      respective Sprinklers are turned on.</para>
 
-      <programlisting>Fire kitchenFire = new Fire( kitchen );
-Fire officeFire = new Fire( office );
+      <programlisting>Fire kitchenFire = new Fire( name2room.get( "kitchen" ) );
+Fire officeFire = new Fire( name2room.get( "office" ) );
 
 FactHandle kitchenFireHandle = ksession.insert( kitchenFire );
 FactHandle officeFireHandle = ksession.insert( officeFire );
@@ -449,7 +440,7 @@
 
       <para>After a while the fires will be put out and the Fire intances are
       retracted. This results in the Sprinklers being turned off, the Alarm
-      being lowered and eventually the health message is printed again.</para>
+      being cancelled, and eventually the health message is printed again.</para>
 
       <programlisting>ksession.retract( kitchenFireHandle );
 ksession.retract( officeFireHandle );
@@ -458,10 +449,10 @@
 
       <programlisting>&gt; Turn on the sprinkler for room office
 &gt; Turn on the sprinkler for room kitchen
-&gt; Lower the alarm
+&gt; Cancel the alarm
 &gt; Everything is ok</programlisting>
 
-      <para>Every one still with me? That wasn't so hard and already I'm
+      <para>Everyone still with me? That wasn't so hard and already I'm
       hoping you can start to see the value and power of a declarative rule
       system.</para>
     </section>




More information about the jboss-svn-commits mailing list