[jboss-svn-commits] JBL Code SVN: r26092 - 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:16:20 EDT 2009
Author: laune
Date: 2009-04-17 05:16:20 -0400 (Fri, 17 Apr 2009)
New Revision: 26092
Modified:
labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Quick_Start/Section-A_Little_More_Theory.xml
Log:
improvements
Modified: labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Quick_Start/Section-A_Little_More_Theory.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Quick_Start/Section-A_Little_More_Theory.xml 2009-04-17 09:14:26 UTC (rev 26091)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Quick_Start/Section-A_Little_More_Theory.xml 2009-04-17 09:16:20 UTC (rev 26092)
@@ -14,9 +14,9 @@
<title>Methods versus Rules</title>
<para>People often confuse methods and rules, and new rule users regular
- ask, "how do I call a rule?". After the last section, you are now
- feeling like a rule expert and the answer to that is obvsious, but just
- to summarise.</para>
+ ask, "How do I call a rule?" After the last section, you are now
+ feeling like a rule expert and the answer to that is obvious, but let's
+ summarize the differences nonetheless.</para>
<programlisting>public void helloWorld(Person person) {
if ( person.getName().equals( "Chuck" ) ) {
@@ -32,6 +32,10 @@
<listitem>
<para>Specific instances are passed.</para>
</listitem>
+
+ <listitem>
+ <para>One call results in a single execution.</para>
+ </listitem>
</itemizedlist>
<programlisting>rule "Hello World"
@@ -43,8 +47,8 @@
<itemizedlist>
<listitem>
- <para>Rules execute by matching against data inserted into the
- engine.</para>
+ <para>Rules execute by matching against any data as long it is
+ inserted into the engine.</para>
</listitem>
<listitem>
@@ -54,6 +58,11 @@
<listitem>
<para>Specific instances cannot be passed to a rule.</para>
</listitem>
+
+ <listitem>
+ <para>Depending on the matches, a rule may fire once or several
+ times, or not at all.</para>
+ </listitem>
</itemizedlist>
</section>
@@ -61,15 +70,17 @@
<title>Cross Products</title>
<para>Earlier the term "cross product" was mentioned, which is the
- result of a join. Imagine for a moment when using the previous data the
- following rules where used, with no field constraints:</para>
+ result of a join. Imagine for a moment that the data from the
+ fire alarm example were used in combination with the following
+ rule where there ar no field constraints:</para>
<programlisting>rule
when
$room : Room()
$sprinkler : Sprinkler()
then
- System.out.println( "room:" + $room.getName() + " sprinkler:" + $sprinkler.getRoom().getName() );
+ System.out.println( "room:" + $room.getName() +
+ " sprinkler:" + $sprinkler.getRoom().getName() );
end</programlisting>
<para>In SQL terms this would be like doing "select * from Room,
@@ -77,53 +88,54 @@
row in the Sprinkler table resulting in the following output:</para>
<programlisting>room:office sprinker:office
-room:office sprinker:kitchen
-room:office sprinker:livingroom
-room:office sprinker:bedroom
-room:kitchen sprinker:office
-room:kitchen sprinker:kitchen
-room:kitchen sprinker:livingroom
-room:kitchen sprinker:bedroom
-room:livingroom sprinker:office
-room:livingroom sprinker:kitchen
-room:livingroom sprinker:livingroom
-room:livingroom sprinker:bedroom
-room:bedroom sprinker:office
-room:bedroom sprinker:kitchen
-room:bedroom sprinker:livingroom
-room:bedroom sprinker:bedroom</programlisting>
+room:office sprinkler:kitchen
+room:office sprinkler:livingroom
+room:office sprinkler:bedroom
+room:kitchen sprinkler:office
+room:kitchen sprinkler:kitchen
+room:kitchen sprinkler:livingroom
+room:kitchen sprinkler:bedroom
+room:livingroom sprinkler:office
+room:livingroom sprinkler:kitchen
+room:livingroom sprinkler:livingroom
+room:livingroom sprinkler:bedroom
+room:bedroom sprinkler:office
+room:bedroom sprinkler:kitchen
+room:bedroom sprinkler:livingroom
+room:bedroom sprinkler:bedroom</programlisting>
- <para>These cross products can obviously become huge as well as
- returning potentially incorrect data. The size of cross products is
- often source of performance problems for new rule authors. From this it
- can be seen that it's always desirable to constrain the cross products,
- which is done with the variable constriant.</para>
+ <para>These cross products can obviously become huge, and they may
+ very well contain spurious data. The size of cross products is
+ often the source of performance problems for new rule authors.
+ From this it can be seen that it's always desirable to constrain
+ the cross products, which is done with the variable constraint.</para>
<programlisting>rule
when
$room : Room()
$sprinkler : Sprinkler( room == $room )
then
- System.out.println( "room:" + $room.getName() + " sprinkler:" + $sprinkler.getRoom().getName() );
+ System.out.println( "room:" + $room.getName() +
+ " sprinkler:" + $sprinkler.getRoom().getName() );
end</programlisting>
- <para>Resulting in just for rows of data, with the correct Sprinkler for
- the Room. In SQL (actually HQL) terms that is like "select * from Room,
- Sprinkler where Room == Sprinkler.room"</para>
+ <para>This results in just four rows of data, with the correct Sprinkler
+ for each Room. In SQL (actually HQL) the corresponding query would be
+ "select * from Room, Sprinkler where Room == Sprinkler.room"</para>
- <programlisting>room:office sprinker:office
-room:kitchen sprinker:kitchen
-room:livingroom sprinker:livingroom
-room:bedroom sprinker:bedroom</programlisting>
+ <programlisting>room:office sprinkler:office
+room:kitchen sprinkler:kitchen
+room:livingroom sprinkler:livingroom
+room:bedroom sprinkler:bedroom</programlisting>
</section>
<section>
<title>Activations, Agenda and Conflict Sets.</title>
- <para>So far the data and matching process has been simple and small. To
+ <para>So far the data and the matching process has been simple and small. To
mix things up a bit a new example will be explored that handles cashflow
- calculations over date periods and the state of the engine will be
- illustrateively shown at key stages to help get a better understanding
+ calculations over date periods. The state of the engine will be
+ illustratively shown at key stages to help get a better understanding
of what is actually going on under the hood. Three classes will be used,
as shown below.</para>
@@ -143,16 +155,16 @@
public AccountPeriod {
private Date start;
- private Dte end
+ private Date end;
// getter and setter methods here
}</programlisting>
<para>By now you already know how to create KnowledgeBases and how to
instantiate facts to populate the StatefulKnowledgeSession, so tables
will be used to show the state of the inserted data, as it makes things
- clearer for illustration purposes. The tables below show a single fact
- was inserted for the Account and a series of debit's and credit's as
- Cashflows over two quarters for that Account were inserted.</para>
+ clearer for illustration purposes. The tables below show that a single fact
+ was inserted for the Account. Also inserted are a series of debits and credits
+ as Cashflows for that Account, extending over two quarters.</para>
<figure>
<title>CashFlows and Account</title>
@@ -165,7 +177,7 @@
</figure>
<para>Two rules can be used to determine the debit and credit for that
- quarter and update the Account balance. The two rules below constraint
+ quarter and update the Account balance. The two rules below constrain
the Cashflows for an Account for a given time period. Notice the
"&&" which use short cut syntax to avoid repeating the field
name twice.</para>
@@ -174,39 +186,39 @@
<tbody>
<tr>
<td align="left" valign="top">
- <programlisting>rule "increase balance for AccountPeriod Credits"
+ <programlisting>rule "increase balance for credits"
when
- ap : AccountPeriod()
- acc : Account( $accountNo : accountNo )
- CashFlow( type == CREDIT,
- accountNo == $accountNo,
- date >= ap.start && <= ap.end,
- $ammount : ammount )
+ ap : AccountPeriod()
+ acc : Account( $accountNo : accountNo )
+ CashFlow( type == CREDIT,
+ accountNo == $accountNo,
+ date >= ap.start && <= ap.end,
+ $amount : amount )
then
- acc.balance += $amount;
+ acc.balance += $amount;
end</programlisting>
</td>
<td align="left" valign="top">
- <programlisting>rule "decrease balance for AccountPeriod Debits"
+ <programlisting>rule "decrease balance for debits"
when
- ap : AccountPeriod()
- acc : Account( $accountNo : accountNo )
- CashFlow( type == DEBIT,
- accountNo == $accountNo,
- date >= ap.start && <= ap.end,
- $ammount : ammount )
+ ap : AccountPeriod()
+ acc : Account( $accountNo : accountNo )
+ CashFlow( type == DEBIT,
+ accountNo == $accountNo,
+ date >= ap.start && <= ap.end,
+ $amount : amount )
then
- acc.balance -= $amount;
+ acc.balance -= $amount;
end</programlisting>
</td>
</tr>
</tbody>
</informaltable>
- <para>If the AccountPeriod is set to the first quarter we constraint the
- "increase balance for AccountPeriod Credits" to two rows of data and
- "decrease balance for AccountPeriod Debits" to one row of data.</para>
+ <para>If the AccountPeriod is set to the first quarter we constrain the
+ "increase balance for credits" to fire on two rows of data and
+ "decrease balance for debits" to act on one row of data.</para>
<figure>
<title>CashFlows and Account</title>
@@ -219,14 +231,14 @@
</figure>
<para>The two Cashflow tables above represent the matched data for the
- two rules, the data is matched during the insertion stage and as you
- found in the previous chapter does not fire straight away, until
- fireAllRules() is called. Intstead the rule plus it's matched data is
+ two rules. The data is matched during the insertion stage and, as you
+ discovered in the previous chapter, does not fire straight away, but only
+ after fireAllRules() is called. Meanwhile, rule plus its matched data is
placed on the Agenda and referred to as an Activation. The Agenda is a
table of Activations that are able to fire and have their consequences
- executed, when fireAllRules() is called. Each of the Activations on the
- Agneda are executed in turn. Notice that the order of execution so far
- is considered arbitrary.</para>
+ executed, as soon as fireAllRules() is called. Activations on the
+ Agenda are executed in turn. Notice that the order of execution
+ so far is considered arbitrary.</para>
<figure>
<title>CashFlows and Account</title>
@@ -238,7 +250,7 @@
</mediaobject>
</figure>
- <para>After each of the above activations are fired, the Account has a
+ <para>After all of the above activations are fired, the Account has a
balance of -25.</para>
<figure>
@@ -251,8 +263,8 @@
</mediaobject>
</figure>
- <para>If the AccountPeriod is updated to Q2, we have just a single
- matched row of data, and thus just a single Activation on the
+ <para>If the AccountPeriod is updated to the second quarter, we have just
+ a single matched row of data, and thus just a single Activation on the
Agenda.</para>
<figure>
@@ -277,37 +289,38 @@
</mediaobject>
</figure>
- <para>So what happens if you don't want the order of Activation
+ <para>What if you don't want the order of Activation
execution to be arbitrary? When there is one or more Activations on the
Agenda they are said to be in conflict, and a conflict resolver strategy
is used to determine the order of execution. At the simplest level the
default strategy uses salience to determine rule priority. Each rule has
a default value of 0, the higher the value the higher the priority. To
- illustrate this a rule to print the Account balance can be added, we
- want this rule to be executed after all the debit's and credit's have
- been applied for this rule, by setting the rule to have a salience of
- below 0 we ensure it fires afterwards.</para>
+ illustrate this we add a rule to print the Account balance, where we
+ want this rule to be executed after all the debits and credits have
+ been applied for all accounts. We achieve this by assigning a negative
+ salience to this rule so that it fires after all rules with the default
+ salience 0.</para>
<table border="0">
<tbody>
<tr>
<td>
- <programlisting>rule "Print blance for AccountPeriod"
+ <programlisting>rule "Print balance for AccountPeriod"
salience -50
when
ap : AccountPeriod()
- acc : Account( )
+ acc : Account()
then
- System.out.println( acc.accountNo + " : " acc.balance );
+ System.out.println( acc.accountNo + " : " + acc.balance );
end</programlisting>
</td>
</tr>
</tbody>
</table>
- <para>The table below shows the resulting Agenda, the 3 debit and credit
- rules are shown to be arbitrary order, while the print rule is shown to
- execute aftwards.</para>
+ <para>The table below depicts the resulting Agenda. The 3 debit and credit
+ rules are shown to be in arbitrary order, while the print rule is ranked
+ last, to execute afterwards.</para>
<figure>
<title>CashFlows and Account</title>
@@ -320,24 +333,30 @@
</figure>
<para>Earlier we showed how rules would equate to SQL, which can often
- be helpful for people with an SQL background when understanding rules.
- The two ruels above can be represented with two views and a trigger for
+ help people with an SQL background to understand rules.
+ The two rules above can be represented with two views and a trigger for
each view, as below:</para>
<table border="0">
<tbody>
<tr>
<td align="left" valign="top">
- <programlisting>select * from Account acc, Cashflow cf, AccountPeriod ap
+ <programlisting>select * from Account acc,
+ Cashflow cf,
+ AccountPeriod ap
where acc.accountNo == cf.accountNo and
- cf.type == CREDIT cf.date >= ap.start and
+ cf.type == CREDIT and
+ cf.date >= ap.start and
cf.date <= ap.end</programlisting>
</td>
<td align="left" valign="top">
- <programlisting>select * from Account acc, Cashflow cf, AccountPeriod ap
+ <programlisting>select * from Account acc,
+ Cashflow cf,
+ AccountPeriod ap
where acc.accountNo == cf.accountNo and
- cf.type == DEBIT cf.date >= ap.start and
+ cf.type == DEBIT and
+ cf.date >= ap.start and
cf.date <= ap.end</programlisting>
</td>
</tr>
@@ -357,7 +376,7 @@
<para>Drools also features ruleflow-group attributes which allows
workflow diagrams to declaratively specify when rules are allowed to
fire. The screenshot below is taken from Eclipse using the Drools
- plugin. It has two ruleflow-group nodes that ensures the calculation
+ plugin. It has two ruleflow-group nodes which ensures that the calculation
rules are executed before the reporting rules.</para>
<mediaobject>
@@ -373,28 +392,29 @@
<tbody>
<tr>
<td align="left" valign="top">
- <programlisting>rule "increase balance for AccountPeriod Credits"
- ruleflow-group "calculation"
+ <programlisting>rule "increase balance for credits"
+ ruleflow-group "calculation"
when
- ap : AccountPeriod()
- acc : Account( $accountNo : accountNo )
- CashFlow( type == CREDIT,
- accountNo == $accountNo,
- date >= ap.start && <= ap.end,
- $ammount : ammount )
+ ap : AccountPeriod()
+ acc : Account( $accountNo : accountNo )
+ CashFlow( type == CREDIT,
+ accountNo == $accountNo,
+ date >= ap.start && <= ap.end,
+ $amount : amount )
then
- acc.balance += $amount;
+ acc.balance += $amount;
end</programlisting>
</td>
<td align="left" valign="top">
- <programlisting>rule "Print blance for AccountPeriod"
- ruleflow-group "report"
- when
- ap : AccountPeriod()
- acc : Account( )
- then
- System.out.println( acc.accountNo + " : " acc.balance );
+ <programlisting>rule "Print balance for AccountPeriod"
+ ruleflow-group "report"
+when
+ ap : AccountPeriod()
+ acc : Account()
+then
+ System.out.println( acc.accountNo +
+ " : " + acc.balance );
end</programlisting>
</td>
</tr>
More information about the jboss-svn-commits
mailing list