[jboss-svn-commits] JBL Code SVN: r20479 - in labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples: BankingExample and 8 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Sat Jun 14 09:00:10 EDT 2008
Author: mark.proctor at jboss.com
Date: 2008-06-14 09:00:09 -0400 (Sat, 14 Jun 2008)
New Revision: 20479
Added:
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/FibonacciExample/fibonacci_agenda1.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/FibonacciExample/fibonacci_agenda2.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/HonestPolitician/
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/HonestPolitician/honest_politician_audit.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Manners/
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Manners/guests_at_table.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Manners/guests_at_table.vsd
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Manners/make_path.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Manners/make_path.vsd
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Manners/manners_activity_diagram.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Manners/manners_activity_diagram.svg
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Manners/manners_activity_diagram.vsd
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/NumberGuess/
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/NumberGuess/numberguess-constraint-toohigh.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/NumberGuess/numberguess-editconstraints.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/NumberGuess/numberguess-ruleflow-properties.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/NumberGuess/numberguess-ruleflow.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-BankingExample.xml
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample.xml
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-GolfingExample.xml
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HelloWorldExample.xml
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HonestPolitician.xml
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-StateExample.xml
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-TroubleTicketExample.xml
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Soduki/
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Soduki/sudoku1.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Soduki/sudoku2.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Soduki/sudoku3.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Soduki/sudoku4.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Soduki/sudoku5.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Soduki/sudoku6.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Soduki/sudoku7.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Soduki/sudoku8.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/TroubleTicket/
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/TroubleTicket/tt_audit_firing.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/TroubleTicket/tt_audit_view.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/TroubleTicket/tt_initial.png
Removed:
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/BankingExample/Section-BankingExample.xml
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/FibonacciExample/Section-FibonacciExample.xml
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/HelloWorldExample/Section-HelloWorldExample.xml
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/guests_at_table.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/guests_at_table.vsd
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/honest_politician_audit.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/make_path.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/make_path.vsd
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/manners_activity_diagram.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/manners_activity_diagram.svg
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/manners_activity_diagram.vsd
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/numberguess-constraint-toohigh.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/numberguess-editconstraints.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/numberguess-ruleflow-properties.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/numberguess-ruleflow.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku1.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku2.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku3.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku4.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku5.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku6.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku7.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku8.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/tt_audit_firing.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/tt_audit_view.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/tt_initial.png
Modified:
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/FibonacciExample/
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/HelloWorldExample/
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-Examples.xml
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/StateExample/
Log:
JBRULES-1643
-trying to move example images to section folders for better grouping
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/BankingExample/Section-BankingExample.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/BankingExample/Section-BankingExample.xml 2008-06-14 01:58:02 UTC (rev 20478)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/BankingExample/Section-BankingExample.xml 2008-06-14 13:00:09 UTC (rev 20479)
@@ -1,592 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
- <section xml:base="../">
- <title>Banking Tutorial</title>
-
- <screen><emphasis role="bold">Name:</emphasis> BankingTutorial
-<emphasis role="bold">Main class:</emphasis> org.drools.tutorials.banking.*
-<emphasis role="bold">Type:</emphasis> java application
-<emphasis role="bold">Rules file:</emphasis> org.drools.tutorials.banking.*
-<emphasis role="bold">Objective:</emphasis> tutorial that builds up knowledge of pattern matching, basic sorting and calculation rules.</screen>
-
- <para>This tutorial will demonstrate the process of developing a complete personal banking application that will handle credits, debits, currencies and that will use a set of design patterns that have been created for the process. In order to make the examples documented here clear and modular, I will try and steer away from re-visiting existing code to add new functionality, and will instead extend and inject where appropriate.</para>
-
- <para>The RuleRunner class is a simple harness to execute one or more drls against a set of data. It compiles the Packages and creates the RuleBase for each execution, this allows us to easy execute each scenario and see the outputs. In reality this is not a good solution for a production system where the RuleBase should be built just once and cached, but for the purposes of this tutorial it shall suffice.</para>
-
- <example>
- <title>Banking Tutorial : RuleRunner</title>
-
- <programlisting>public class RuleRunner {
-
- public RuleRunner() {
- }
-
- public void runRules(String[] rules,
- Object[] facts) throws Exception {
-
- RuleBase ruleBase = RuleBaseFactory.newRuleBase();
- PackageBuilder builder = new PackageBuilder();
-
- for ( int i = 0; i < rules.length; i++ ) {
- String ruleFile = rules[i];
- System.out.println( "Loading file: " + ruleFile );
- builder.addPackageFromDrl(new InputStreamReader( RuleRunner.class.getResourceAsStream( ruleFile ) ) );
- }
-
- Package pkg = builder.getPackage();
- ruleBase.addPackage( pkg );
- WorkingMemory workingMemory = ruleBase.newStatefulSession();
-
- for ( int i = 0; i < facts.length; i++ ) {
- Object fact = facts[i];
- System.out.println( "Inserting fact: " + fact );
- workingMemory.insert( fact );
- }
-
- workingMemory.fireAllRules();
- }
-}</programlisting>
- </example>
-
- <para>This is our first Example1.java class it loads and executes a single drl file "Example.drl" but inserts no data.</para>
-
- <example>
- <title>Banking Tutorial : Java Example1</title>
-
- <programlisting>public class Example1 {
- public static void main(String[] args) throws Exception {
- new RuleRunner().runRules( new String[] { "Example1.drl" },
- new Object[0] );
- }
-}</programlisting>
- </example>
-
- <para>And this is the first simple rule to execute. It has a single "eval" condition that will alway be true, thus this rul will always match and fire.</para>
-
- <example>
- <title>Banking Tutorial : Rule Example1</title>
-
- <programlisting>rule "Rule 01"
- when
- eval (1==1)
- then
- System.out.println("Rule 01 Works");
-endh</programlisting>
- </example>
-
- <para>The output for the rule is below, the rule matches and executes the single print statement.</para>
-
- <example>
- <title>Banking Tutorial : Output Example1</title>
-
- <programlisting>Loading file: Example1.drl
-Rule 01 Works</programlisting>
- </example>
-
- <para>The next step is to assert some simple facts and print them out. </para>
-
- <example>
- <title>Banking Tutorial : Java Example2</title>
-
- <programlisting>public class Example2 {
- public static void main(String[] args) throws Exception {
- Number[] numbers = new Number[] {wrap(3), wrap(1), wrap(4), wrap(1), wrap(5)};
- new RuleRunner().runRules( new String[] { "Example2.drl" },
- numbers );
- }
-
- private static Integer wrap(int i) {
- return new Integer(i);
- }
-}</programlisting>
- </example>
-
- <para>This doesnât use any specific facts but instead asserts a set of java.lang.Integerâs. This is not considered "best practice" as a number of a collection is not a fact, it is not a thing. A Bank acount has a number, its balance, thus the Account is the fact; but to get started asserting Integers shall suffice for demonstration purposes as the complexity is built up.</para>
-
- <para>Now we will create a simple rule to print out these numbers.</para>
-
- <example>
- <title>Banking Tutorial : Rule Example2</title>
-
- <programlisting>rule "Rule 02"
- when
- Number( $intValue : intValue )
- then
- System.out.println("Number found with value: " + $intValue);
-end</programlisting>
- </example>
-
- <para>Once again, this rule does nothing special. It identifies any facts that are Numbers and prints out the values. Notice the user of interfaces here, we inserted Integers but the pattern matching engine is able to match the interfaces and super classes of the asserted objects.</para>
-
- <para>The output shows the drl being loaded, the facts inserted and then the matched and fired rules. We can see that each inserted number is matched and fired and thus printed.</para>
-
- <example>
- <title>Banking Tutorial : Output Example2</title>
-
- <programlisting>Loading file: Example2.drl
-Inserting fact: 3
-Inserting fact: 1
-Inserting fact: 4
-Inserting fact: 1
-Inserting fact: 5
-Number found with value: 5
-Number found with value: 1
-Number found with value: 4
-Number found with value: 1
-Number found with value: 3
-</programlisting>
- </example>
-
- <para>here are probably a hundred and one better ways to sort numbers; but we will need to apply some cashflows in date order when we start looking at banking rules so letâs look at a simple rule based example.</para>
-
- <example>
- <title>Banking Tutorial : Java Example3</title>
-
- <programlisting>public class Example3 {
- public static void main(String[] args) throws Exception {
- Number[] numbers = new Number[] {wrap(3), wrap(1), wrap(4), wrap(1), wrap(5)};
- new RuleRunner().runRules( new String[] { "Example3.drl" },
- numbers );
- }
-
- private static Integer wrap(int i) {
- return new Integer(i);
- }
-}</programlisting>
- </example>
-
- <para>Again we insert our Integers as before, this time the rule is slightly different:</para>
-
- <example>
- <title>Banking Tutorial : Rule Example3</title>
-
- <programlisting>rule "Rule 03"
- when
- $number : Number( )
- not Number( intValue < $number.intValue )
- then
- System.out.println("Number found with value: " + $number.intValue() );
- retract( $number );
-end</programlisting>
- </example>
-
- <para>The first line of the rules identifies a Number and extracts the value. The second line ensures that there does not exist a smaller number than the one found. By executing this rule, we might expect to find only one number - the smallest in the set. However, the retraction of the number after it has been printed, means that the smallest number has been removed, revealing the next smallest number, and so on. </para>
-
- <para>So, the output we generate is, notice the numbers are now sorted numerically.</para>
-
- <example>
- <title>Banking Tutorial : Output Example3</title>
-
- <programlisting>Loading file: Example3.drl
-Inserting fact: 3
-Inserting fact: 1
-Inserting fact: 4
-Inserting fact: 1
-Inserting fact: 5
-Number found with value: 1
-Number found with value: 1
-Number found with value: 3
-Number found with value: 4
-Number found with value: 5
-</programlisting>
- </example>
-
- <para>Now we want to start moving towards our personal accounting rules. The first step is to create a Cashflow POJO.</para>
-
- <example>
- <title>Banking Tutoria : Class Cashflow</title>
-
- <programlisting>public class Cashflow {
- private Date date;
- private double amount;
-
- public Cashflow() {
- }
-
- public Cashflow(Date date,
- double amount) {
- this.date = date;
- this.amount = amount;
- }
-
- public Date getDate() {
- return date;
- }
-
- public void setDate(Date date) {
- this.date = date;
- }
-
- public double getAmount() {
- return amount;
- }
-
- public void setAmount(double amount) {
- this.amount = amount;
- }
-
- public String toString() {
- return "Cashflow[date=" + date + ",amount=" + amount + "]";
- }
-}</programlisting>
- </example>
-
- <para>The Cashflow has two simple attributes, a date and an amount. I have added a toString method to print it and overloaded the constructor to set the values. The Example4 java code inserts 5 Cashflow objecst with varying dates and amounts.</para>
-
- <example>
- <title>Banking Tutorial : Java Example4</title>
-
- <programlisting>public class Example4 {
- public static void main(String[] args) throws Exception {
- Object[] cashflows = {
- new Cashflow(new SimpleDate("01/01/2007"), 300.00),
- new Cashflow(new SimpleDate("05/01/2007"), 100.00),
- new Cashflow(new SimpleDate("11/01/2007"), 500.00),
- new Cashflow(new SimpleDate("07/01/2007"), 800.00),
- new Cashflow(new SimpleDate("02/01/2007"), 400.00),
- };
-
- new RuleRunner().runRules( new String[] { "Example4.drl" },
- cashflows );
- }
-}</programlisting>
- </example>
-
- <para>SimpleDate is a simple class that extends Date and takes a String as input. It allows for pre-formatted Data classes, for convienience. The code is listed below</para>
-
- <example>
- <title>Banking Tutorial : Java SimpleDate</title>
-
- <programlisting>public class SimpleDate extends Date {
- private static final SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
-
- public SimpleDate(String datestr) throws Exception {
- setTime(format.parse(datestr).getTime());
- }
-}</programlisting>
- </example>
-
- <para>Now, letâs look at rule04.drl to see how we print the sorted Cashflows:</para>
-
- <example>
- <title>Banking Tutorial : Rule Example4</title>
-
- <programlisting>rule "Rule 04"
- when
- $cashflow : Cashflow( $date : date, $amount : amount )
- not Cashflow( date < $date)
- then
- System.out.println("Cashflow: "+$date+" :: "+$amount);
- retract($cashflow);
-end</programlisting>
- </example>
-
- <para>Here, we identify a Cashflow and extract the date and the amount. In the second line of the rules we ensure that there is not a Cashflow with an earlier date than the one found. In the consequences, we print the Cashflow that satisfies the rules and then retract it, making way for the next earliest Cashflow. So, the output we generate is:</para>
-
- <example>
- <title>Banking Tutorial : Output Example4</title>
-
- <programlisting>Loading file: Example4.drl
-Inserting fact: Cashflow[date=Mon Jan 01 00:00:00 GMT 2007,amount=300.0]
-Inserting fact: Cashflow[date=Fri Jan 05 00:00:00 GMT 2007,amount=100.0]
-Inserting fact: Cashflow[date=Thu Jan 11 00:00:00 GMT 2007,amount=500.0]
-Inserting fact: Cashflow[date=Sun Jan 07 00:00:00 GMT 2007,amount=800.0]
-Inserting fact: Cashflow[date=Tue Jan 02 00:00:00 GMT 2007,amount=400.0]
-Cashflow: Mon Jan 01 00:00:00 GMT 2007 :: 300.0
-Cashflow: Tue Jan 02 00:00:00 GMT 2007 :: 400.0
-Cashflow: Fri Jan 05 00:00:00 GMT 2007 :: 100.0
-Cashflow: Sun Jan 07 00:00:00 GMT 2007 :: 800.0
-Cashflow: Thu Jan 11 00:00:00 GMT 2007 :: 500.0
-</programlisting>
- </example>
-
- <para>Here we extend our Cashflow to give a TypedCashflow which can be CREDIT or DEBIT. Ideally, we would just add this to the Cashflow type, but so that we can keep all the examples simple, we will go with the extensions.</para>
-
- <example>
- <title>Banking Tutoria : Class TypedCashflow</title>
-
- <programlisting>public class TypedCashflow extends Cashflow {
- public static final int CREDIT = 0;
- public static final int DEBIT = 1;
-
- private int type;
-
- public TypedCashflow() {
- }
-
- public TypedCashflow(Date date,
- int type,
- double amount) {
- super( date,
- amount );
- this.type = type;
- }
-
- public int getType() {
- return type;
- }
-
- public void setType(int type) {
- this.type = type;
- }
-
- public String toString() {
- return "TypedCashflow[date=" + getDate() + ",type=" + (type == CREDIT ? "Credit" : "Debit") + ",amount=" + getAmount() + "]";
- }
-}</programlisting>
- </example>
-
- <para>There are lots of ways to improve this code, but for the sake of the example this will do.</para>
-
- <para>Nows lets create the Example5 runner.</para>
-
- <example>
- <title>Banking Tutorial : Java Example5</title>
-
- <programlisting>public class Example5 {
- public static void main(String[] args) throws Exception {
- Object[] cashflows = {
- new TypedCashflow(new SimpleDate("01/01/2007"),
- TypedCashflow.CREDIT, 300.00),
- new TypedCashflow(new SimpleDate("05/01/2007"),
- TypedCashflow.CREDIT, 100.00),
- new TypedCashflow(new SimpleDate("11/01/2007"),
- TypedCashflow.CREDIT, 500.00),
- new TypedCashflow(new SimpleDate("07/01/2007"),
- TypedCashflow.DEBIT, 800.00),
- new TypedCashflow(new SimpleDate("02/01/2007"),
- TypedCashflow.DEBIT, 400.00),
- };
-
- new RuleRunner().runRules( new String[] { "Example5.drl" },
- cashflows );
- }
-}</programlisting>
- </example>
-
- <para>Here, we simply create a set of Cashflows which are either CREDIT or DEBIT Cashflows and supply them and rule05.drl to the RuleEngine. </para>
-
- <para>Now, letâs look at rule0 Example5.drl to see how we print the sorted Cashflows:</para>
-
- <example>
- <title>Banking Tutorial : Rule Example5</title>
-
- <programlisting>rule "Rule 05"
- when
- $cashflow : TypedCashflow( $date : date,
- $amount : amount,
- type == TypedCashflow.CREDIT )
- not TypedCashflow( date < $date,
- type == TypedCashflow.CREDIT )
- then
- System.out.println("Credit: "+$date+" :: "+$amount);
- retract($cashflow);
-end</programlisting>
- </example>
-
- <para>Here, we identify a Cashflow with a type of CREDIT and extract the date and the amount. In the second line of the rules we ensure that there is not a Cashflow of type CREDIT with an earlier date than the one found. In the consequences, we print the Cashflow that satisfies the rules and then retract it, making way for the next earliest Cashflow of type CREDIT.</para>
-
- <para>So, the output we generate is</para>
-
- <example>
- <title>Banking Tutorial : Output Example5</title>
-
- <screen>Loading file: Example5.drl
-Inserting fact: TypedCashflow[date=Mon Jan 01 00:00:00 GMT 2007,type=Credit,amount=300.0]
-Inserting fact: TypedCashflow[date=Fri Jan 05 00:00:00 GMT 2007,type=Credit,amount=100.0]
-Inserting fact: TypedCashflow[date=Thu Jan 11 00:00:00 GMT 2007,type=Credit,amount=500.0]
-Inserting fact: TypedCashflow[date=Sun Jan 07 00:00:00 GMT 2007,type=Debit,amount=800.0]
-Inserting fact: TypedCashflow[date=Tue Jan 02 00:00:00 GMT 2007,type=Debit,amount=400.0]
-Credit: Mon Jan 01 00:00:00 GMT 2007 :: 300.0
-Credit: Fri Jan 05 00:00:00 GMT 2007 :: 100.0
-Credit: Thu Jan 11 00:00:00 GMT 2007 :: 500.0
-</screen>
- </example>
-
- <para>Here we are going to process both CREDITs and DEBITs on 2 bank accounts to calculate the account balance. In order to do this, I am going to create two separate Account Objects and inject them into the Cashflows before passing them to the Rule Engine. The reason for this is to provide easy access to the correct Bank Accounts without having to resort to Helper classes. Letâs take a look at the Account class first. This is a simple POJO with an account number and balance:</para>
-
- <example>
- <title>Banking Tutoria : Class Account</title>
-
- <programlisting>public class Account {
- private long accountNo;
- private double balance = 0;
-
- public Account() {
- }
-
- public Account(long accountNo) {
- this.accountNo = accountNo;
- }
-
- public long getAccountNo() {
- return accountNo;
- }
-
- public void setAccountNo(long accountNo) {
- this.accountNo = accountNo;
- }
-
- public double getBalance() {
- return balance;
- }
-
- public void setBalance(double balance) {
- this.balance = balance;
- }
-
- public String toString() {
- return "Account[" + "accountNo=" + accountNo + ",balance=" + balance + "]";
- }
-}</programlisting>
- </example>
-
- <para>Now letâs extend our TypedCashflow to give AllocatedCashflow (allocated to an account).</para>
-
- <example>
- <title>Banking Tutoria : Class AllocatedCashflow</title>
-
- <programlisting>public class AllocatedCashflow extends TypedCashflow {
- private Account account;
-
- public AllocatedCashflow() {
- }
-
- public AllocatedCashflow(Account account,
- Date date,
- int type,
- double amount) {
- super( date,
- type,
- amount );
- this.account = account;
- }
-
- public Account getAccount() {
- return account;
- }
-
- public void setAccount(Account account) {
- this.account = account;
- }
-
- public String toString() {
- return "AllocatedCashflow[" + "account=" + account + ",date=" + getDate() +
- ",type=" + (getType() == CREDIT ? "Credit" : "Debit") +
- ",amount=" + getAmount() + "]";
- }
-}</programlisting>
- </example>
-
- <para>Now, letâs java code for Example5 execution. Here we create two Account objects and inject one into each cashflow as appropriate. For simplicity I have simply included them in the constructor.</para>
-
- <example>
- <title>Banking Tutorial : Java Example5</title>
-
- <programlisting>public class Example6 {
- public static void main(String[] args) throws Exception {
- Account acc1 = new Account(1);
- Account acc2 = new Account(2);
-
- Object[] cashflows = {
- new AllocatedCashflow(acc1,new SimpleDate("01/01/2007"),
- TypedCashflow.CREDIT, 300.00),
- new AllocatedCashflow(acc1,new SimpleDate("05/02/2007"),
- TypedCashflow.CREDIT, 100.00),
- new AllocatedCashflow(acc2,new SimpleDate("11/03/2007"),
- TypedCashflow.CREDIT, 500.00),
- new AllocatedCashflow(acc1,new SimpleDate("07/02/2007"),
- TypedCashflow.DEBIT, 800.00),
- new AllocatedCashflow(acc2,new SimpleDate("02/03/2007"),
- TypedCashflow.DEBIT, 400.00),
- new AllocatedCashflow(acc1,new SimpleDate("01/04/2007"),
- TypedCashflow.CREDIT, 200.00),
- new AllocatedCashflow(acc1,new SimpleDate("05/04/2007"),
- TypedCashflow.CREDIT, 300.00),
- new AllocatedCashflow(acc2,new SimpleDate("11/05/2007"),
- TypedCashflow.CREDIT, 700.00),
- new AllocatedCashflow(acc1,new SimpleDate("07/05/2007"),
- TypedCashflow.DEBIT, 900.00),
- new AllocatedCashflow(acc2,new SimpleDate("02/05/2007"),
- TypedCashflow.DEBIT, 100.00)
- };
-
- new RuleRunner().runRules( new String[] { "Example6.drl" },
- cashflows );
- }
-}</programlisting>
- </example>
-
- <para>Now, letâs look at rule Example06.drl to see how we apply each cashflow in date order and calculate and print the balance. </para>
-
- <example>
- <title>Banking Tutorial : Rule Example6</title>
-
- <programlisting>rule "Rule 06 - Credit"
- when
- $cashflow : AllocatedCashflow( $account : account,
- $date : date, $amount : amount,
- type==TypedCashflow.CREDIT )
- not AllocatedCashflow( account == $account, date < $date)
- then
- System.out.println("Credit: " + $date + " :: " + $amount);
- $account.setBalance($account.getBalance()+$amount);
- System.out.println("Account: " + $account.getAccountNo() +
- " - new balance: " + $account.getBalance());
- retract($cashflow);
-end
-
-rule "Rule 06 - Debit"
- when
- $cashflow : AllocatedCashflow( $account : account,
- $date : date, $amount : amount,
- type==TypedCashflow.DEBIT )
- not AllocatedCashflow( account == $account, date < $date)
- then
- System.out.println("Debit: " + $date + " :: " + $amount);
- $account.setBalance($account.getBalance() - $amount);
- System.out.println("Account: " + $account.getAccountNo() +
- " - new balance: " + $account.getBalance());
- retract($cashflow);
-end</programlisting>
- </example>
-
- <para>Here, we have separate rules for CREDITs and DEBITs, however we do not specify a type when checking for earlier cashflows. This is so that all cashflows are applied in date order regardless of which type of cashflow type they are. In the rule section we identify the correct account to work with and in the consequences we update it with the cashflow amount.</para>
-
- <example>
- <title>Banking Tutorial : Output Example6</title>
-
- <programlisting>Loading file: Example6.drl
-Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Mon Jan 01 00:00:00 GMT 2007,type=Credit,amount=300.0]
-Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Mon Feb 05 00:00:00 GMT 2007,type=Credit,amount=100.0]
-Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Sun Mar 11 00:00:00 GMT 2007,type=Credit,amount=500.0]
-Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Wed Feb 07 00:00:00 GMT 2007,type=Debit,amount=800.0]
-Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Fri Mar 02 00:00:00 GMT 2007,type=Debit,amount=400.0]
-Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Sun Apr 01 00:00:00 BST 2007,type=Credit,amount=200.0]
-Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Thu Apr 05 00:00:00 BST 2007,type=Credit,amount=300.0]
-Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Fri May 11 00:00:00 BST 2007,type=Credit,amount=700.0]
-Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Mon May 07 00:00:00 BST 2007,type=Debit,amount=900.0]
-Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Wed May 02 00:00:00 BST 2007,type=Debit,amount=100.0]
-Debit: Fri Mar 02 00:00:00 GMT 2007 :: 400.0
-Account: 2 - new balance: -400.0
-Credit: Sun Mar 11 00:00:00 GMT 2007 :: 500.0
-Account: 2 - new balance: 100.0
-Debit: Wed May 02 00:00:00 BST 2007 :: 100.0
-Account: 2 - new balance: 0.0
-Credit: Fri May 11 00:00:00 BST 2007 :: 700.0
-Account: 2 - new balance: 700.0
-Credit: Mon Jan 01 00:00:00 GMT 2007 :: 300.0
-Account: 1 - new balance: 300.0
-Credit: Mon Feb 05 00:00:00 GMT 2007 :: 100.0
-Account: 1 - new balance: 400.0
-Debit: Wed Feb 07 00:00:00 GMT 2007 :: 800.0
-Account: 1 - new balance: -400.0
-Credit: Sun Apr 01 00:00:00 BST 2007 :: 200.0
-Account: 1 - new balance: -200.0
-Credit: Thu Apr 05 00:00:00 BST 2007 :: 300.0
-Account: 1 - new balance: 100.0
-Debit: Mon May 07 00:00:00 BST 2007 :: 900.0
-Account: 1 - new balance: -800.0
-</programlisting>
- </example>
-
- </section>
\ No newline at end of file
Property changes on: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/FibonacciExample
___________________________________________________________________
Name: svn:ignore
+ *.db
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/FibonacciExample/Section-FibonacciExample.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/FibonacciExample/Section-FibonacciExample.xml 2008-06-14 01:58:02 UTC (rev 20478)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/FibonacciExample/Section-FibonacciExample.xml 2008-06-14 13:00:09 UTC (rev 20479)
@@ -1,169 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
- <section xml:base="../">
- <title>Fibonacci Example</title>
-
- <screen><emphasis role="bold">Name:</emphasis> Fibonacci
-<emphasis role="bold">Main class:</emphasis> org.drools.examples.FibonacciExample
-<emphasis role="bold">Type:</emphasis> java application
-<emphasis role="bold">Rules file:</emphasis> Fibonacci.drl
-<emphasis role="bold">Objective:</emphasis> Demonsrates Recursion, 'not' CEs and Cross Product Matching</screen>
-
- <para>The Fibonacci Numbers, <ulink url="http://en.wikipedia.org/wiki/Fibonacci_number">http://en.wikipedia.org/wiki/Fibonacci_number</ulink>, invented by Leonardo of Pisa, <ulink url="http://en.wikipedia.org/wiki/Fibonacci">http://en.wikipedia.org/wiki/Fibonacci</ulink>, are obtained by starting with 0 and 1, and then produce the next Fibonacci number by adding the two previous Fibonacci numbers. The first Fibonacci numbers for n = 0, 1,... are: * 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946... The Fibonacci Example demonstrates recursion and conflict resolution with Salience values.</para>
-
- <para>A single fact Class is used in this example, Fibonacci. It has two fields, sequence and value. The sequence field is used to indicate the position of the object in the Fibonacci number sequence and the value field shows the value of that Fibonacci object for that sequence position.</para>
-
- <example>
- <title>Fibonacci Class</title>
-
- <programlisting>public static class Fibonacci {
- private int sequence;
- private long value;
-
- ... setters and getters go here...
-}</programlisting>
- </example>
-
- <para>Execute the example:</para>
-
- <orderedlist>
- <listitem>
- <para>Open the class <classname>org.drools.examples.FibonacciExample</classname> in your Eclipse IDE</para>
- </listitem>
-
- <listitem>
- <para>Right-click the class an select "Run as..." -> "Java application"</para>
- </listitem>
- </orderedlist>
-
- <para>And Eclipse shows the following output in its console, "...snip..." shows repeated bits removed to save space:</para>
-
- <example>
- <title>Fibonacci Example Console Output</title>
-
- <programlisting>recurse for 50
-recurse for 49
-recurse for 48
-recurse for 47
-...snip...
-recurse for 5
-recurse for 4
-recurse for 3
-recurse for 2
-1 == 1
-2 == 1
-3 == 2
-4 == 3
-5 == 5
-6 == 8
-...snip...
-47 == 2971215073
-48 == 4807526976
-49 == 7778742049
-50 == 12586269025
-</programlisting>
- </example>
-
- <para>To kick this off from java we only insert a single Fibonacci object, with a sequence of 50, a recurse rule is then used to insert the other 49 Fibonacci objects. This example doesn't use PropertyChangeSupport and uses the MVEL dialect, this means we can use the <emphasis role="bold">modify</emphasis> keyword, which allows a block setter action which also notifies the engine of changes.</para>
-
- <example>
- <title>Fibonacci Example Execution</title>
-
- <programlisting>session.insert( new Fibonacci( 50 ) );
-session.fireAllRules();</programlisting>
- </example>
-
- <para>The recurse rule is very simple, it matches each asserted Fibonacci object with a value of -1, it then creates and asserts a new Fibonacci object with a sequence of one less than the currently matched object. Each time a Fibonacci object is added, as long as one with a "sequence == 1" does not exist, the rule re-matches again and fires; causing the recursion. The 'not' conditional element is used to stop the rule matching once we have all 50 Fibonacci objects in memory. The rule also has a salience value, this is because we need to have all 50 Fibonacci objects asserted before we execute the Bootstrap rule.</para>
-
- <example>
- <title>Fibonacci Example : Rule "Recurse"</title>
-
- <programlisting>rule Recurse
- salience 10
- when
- f : Fibonacci ( value == -1 )
- not ( Fibonacci ( sequence == 1 ) )
- then
- insert( new Fibonacci( f.sequence - 1 ) );
- System.out.println( "recurse for " + f.sequence );
-end</programlisting>
- </example>
-
- <para>The audit view shows the original assertion of the Fibonacci object with a sequence of 50, this was done from Java land. From there the audit view shows the continual recursion of the rule, each asserted Fibonacci causes the "Recurse" rule to become activate again, which then fires.</para>
-
- <figure>
- <title>Fibonacci Example "Recurse" Audit View 1</title>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="fibonacci1.png" />
- </imageobject>
- </mediaobject>
- </figure>
-
- <para>When a Fibonacci with a sequence of 2 is asserted the "Bootstrap" rule is matched and activated along with the "Recurse" rule.</para>
-
- <example>
- <title>Fibonacci Example : Rule "Bootstrap"</title>
-
- <programlisting>rule Bootstrap
- when
- f : Fibonacci( sequence == 1 || == 2, value == -1 ) // this is a multi-restriction || on a single field
- then
- modify ( f ){ value = 1 };
- System.out.println( f.sequence + " == " + f.value );
-end</programlisting>
- </example>
-
- <para>At this point the Agenda looks like the figure shown below. However the "Bootstrap" rule does not fire as the "Recurse" rule has a higher salience.</para>
-
- <figure>
- <title>Fibonacci Example "Recurse" Agenda View 1</title>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="fibonacci_agenda1.png" />
- </imageobject>
- </mediaobject>
- </figure>
-
- <para>When a Fibonacci with a sequence of 1 is asserted the "Bootstrap" rule is matched again, causing two activations for this rule; note that the "Recurse" rule does not match and activate because the 'not conditional element stops the rule matching when a Fibonacci with a sequence of 1 exists.</para>
-
- <figure>
- <title>Fibonacci Example "Recurse" Agenda View 2</title>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="fibonacci_agenda2.png" />
- </imageobject>
- </mediaobject>
- </figure>
-
- <para>Once we have two Fibonacci objects both with values not equal to -1 the "calculate" rule is able to match; remember it was the "Bootstrap" rule that set the Fibonacci's with sequences 1 and 2 to values of 1. At this point we have 50 Fibonacci objects in the Working Memory and we some how need to select the correct ones to calculate each of their values in turn. With three Fibonacci patterns in a rule with no field constriants to correctly constrain the available cross products we have 50x50x50 possible permutations, thats 125K possible rule firings. The "Calculate" rule uses the field constraints to correctly constraint the thee Fibonacci patterns and in the correct order; this technique is called "cross product matching". The first pattern finds any Fibonacci with a value != -1 and binds both the pattern and the field. The second Fibonacci does too but it adds an additional field constraint to make sure that its sequence is one greater than the Fibonacci bound to f!
1. When this rule first fires we know that only sequences 1 and 2 have values of 1 and the two constraints ensure that f1 references sequence 1 and f2 references sequence2. The final pattern finds the Fibonacci of a value == -1 with a sequence one greater than f2. At this point we have three Fibonacci objects correctly selected from the available cross products and we can do the maths calculating the value for Fibonacci sequence = 3.</para>
-
- <example>
- <title>Fibonacci Example : Rule "Calculate"</title>
-
- <programlisting>rule Calculate
- when
- f1 : Fibonacci( s1 : sequence, value != -1 ) // here we bind sequence
- f2 : Fibonacci( sequence == (s1 + 1 ), value != -1 ) // here we don't, just to demonstrate the different way bindings can be used
- f3 : Fibonacci( s3 : sequence == (f2.sequence + 1 ), value == -1 )
- then
- modify ( f3 ) { value = f1.value + f2.value };
- System.out.println( s3 + " == " + f3.value ); // see how you can access pattern and field bindings
-end
-</programlisting>
- </example>
-
- <para>The MVEL modify keyword updated the value of the Fibonacci object bound to f3, this means we have a new Fibonacci object with a value != -1, this allows the "Calculate" rule to rematch and calculate the next Fibonacci number. The Audit view below shows the how the firing of the last "Bootstrap" modifies the Fibonacci object enabling the "Calculate" rule to match, which then modifies another Fibonacci object allowing the "Calculate" rule to rematch. This continues till the value is set for all Fibonacci objects.</para>
-
- <figure>
- <title>Fibonacci Example "Bootstrap" Audit View 1</title>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="fibonacci4.png" />
- </imageobject>
- </mediaobject>
- </figure>
- </section>
\ No newline at end of file
Added: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/FibonacciExample/fibonacci_agenda1.png
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/FibonacciExample/fibonacci_agenda1.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/FibonacciExample/fibonacci_agenda2.png
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/FibonacciExample/fibonacci_agenda2.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Property changes on: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/HelloWorldExample
___________________________________________________________________
Name: svn:ignore
+ *.db
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/HelloWorldExample/Section-HelloWorldExample.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/HelloWorldExample/Section-HelloWorldExample.xml 2008-06-14 01:58:02 UTC (rev 20478)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/HelloWorldExample/Section-HelloWorldExample.xml 2008-06-14 13:00:09 UTC (rev 20479)
@@ -1,285 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<section>
- <title>Hello World</title>
-
- <screen><emphasis role="bold">Name:</emphasis> Hello World
-<emphasis role="bold">Main class:</emphasis> org.drools.examples.HelloWorldExample
-<emphasis role="bold">Type:</emphasis> java application
-<emphasis role="bold">Rules file:</emphasis> HelloWorld.drl
-<emphasis role="bold">Objective:</emphasis> demonstrate basic rules in use</screen>
-
- <para>The "Hello World" example shows a simple example of rules usage, and
- both the MVEL and Java dialects.</para>
-
- <para>In this example it will be shown how to build rulebases and sessions
- and how to add audit logging and debug outputs, this information is ommitted
- from other examples as it's all very similar. PackageBuilder is used to turn
- a drl source file into Package objects which the RuleBase can consume,
- addPackageFromDrl takes a Reader interface as the parameter. Reader can be
- used to retrieve a source drl file from various locations, in this case the
- drl file is being retrieved from the classpath as an InputStream which we
- turn into a Reader by wrapping it with InputStreamReader; but it could come
- the disk or a url. The use of the Reader interface means that Drools does
- not have to care. In this case we only add a single drl source file, but
- multiple drl files can be added and all are merged into a single Package.
- All drl files added to the PackageBuilder must declare themselves in the
- same package namespace, if you wish to build a Package in a different
- namespace a new instance of PackageBuilder must be created; multiple
- packages of differerent namespaces can be added to the same RuleBase. When
- all the drl files have been added we should check the builder for errors;
- while the RuleBase will validate the packge it will only have access to the
- error information as a String, so if you wish to debug the error information
- you should do it on the builder instance. Once we know the builder is error
- free get the Package, instantiate a RuleBase from the RuleBaseFactory and
- add the package.</para>
-
- <example>
- <title>HelloWorld example: Creating the RuleBase and Session</title>
-
- <programlisting>//read in the source
-Reader source = new InputStreamReader( HelloWorldExample.class.getResourceAsStream( "HelloWorld.drl" ) );
-
-PackageBuilder builder = new PackageBuilder();
-
-//this will parse and compile in one step
-builder.addPackageFromDrl( source );
-
-// Check the builder for errors
-if ( builder.hasErrors() ) {
- System.out.println( builder.getErrors().toString() );
- throw new RuntimeException( "Unable to compile \"HelloWorld.drl\".");
-}
-
-//get the compiled package (which is serializable)
-Package pkg = builder.getPackage();
-
-//add the package to a rulebase (deploy the rule package).
-RuleBase ruleBase = RuleBaseFactory.newRuleBase();
-ruleBase.addPackage( pkg );
-
-StatefulSession session = ruleBase.newStatefulSession();</programlisting>
- </example>
-
- <para>Drools has an event model that exposes much of what's happening
- internally, two default debug listeners are supplied
- DebugAgendaEventListener and DebugWorkingMemoryEventListener which print out
- debug event information to the err console, adding listeners to a session is
- trivial and shown below. The WorkingMemoryFileLogger provides execution
- auditing which can be viewed in a graphical viewer; it's actually a
- specialised implementation built on the agenda and working memory listeners,
- when the engine has finished executing logger.writeToDisk() must be
- called.</para>
-
- <para>Most of the examples use the Audit logging features of Drools to
- record execution flow for later inspection.</para>
-
- <example>
- <title>HelloWorld example: Event logging and Auditing</title>
-
- <programlisting>// setup the debug listeners
-session.addEventListener( new DebugAgendaEventListener() );
-session.addEventListener( new DebugWorkingMemoryEventListener() );
-
-// setup the audit logging
-WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger( session );
-logger.setFileName( "log/helloworld" ); </programlisting>
- </example>
-
- <para>The single class used in this example is very simple, it has two
- fields: the message, which is a String and the status which can be either
- the int HELLO or the int GOODBYE.</para>
-
- <example>
- <title>HelloWorld example: Message Class</title>
-
- <programlisting>public static class Message {
- public static final int HELLO = 0;
- public static final int GOODBYE = 1;
-
- private String message;
- private int status;
- ...
-}</programlisting>
- </example>
-
- <para>A single Message object is created with the message "Hello World" and
- status HELLO and then inserted into the engine, at which point
- fireAllRules() is executed. Remember all the network evaluation is done
- during the insert time, by the time the program execution reaches the
- fireAllRules() method it already knows which rules are fully matches and
- able to fire.</para>
-
- <example>
- <title>HelloWorld example: Execution</title>
-
- <programlisting>Message message = new Message();
-message.setMessage( "Hello World" );
-message.setStatus( Message.HELLO );
-session.insert( message );
-
-session.fireAllRules();
-
-logger.writeToDisk();
-
-session.dispose(); </programlisting>
- </example>
-
- <para>To execute the example from Java.</para>
-
- <orderedlist>
- <listitem>
- <para>Open the class org.drools.examples.FibonacciExample in your
- Eclipse IDE</para>
- </listitem>
-
- <listitem>
- <para>Right-click the class an select "Run as..." -> "Java
- application"</para>
- </listitem>
- </orderedlist>
-
- <para>If we put a breakpoint on the fireAllRules() method and select the
- session variable we can see that the "Hello World" view is already activated
- and on the Agenda, showing that all the pattern matching work was already
- done during the insert.</para>
-
- <figure>
- <title>Hello World : fireAllRules Agenda View</title>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="helloworld_agenda1.png" />
- </imageobject>
- </mediaobject>
- </figure>
-
- <para>The may application print outs go to to System.out while the debug
- listener print outs go to System.err.</para>
-
- <example>
- <title>HelloWorld example: Console.out</title>
-
- <programlisting>Hello World
-Goodbye cruel world</programlisting>
- </example>
-
- <example>
- <title>HelloWorld example: Console.err</title>
-
- <programlisting>==>[ActivationCreated(0): rule=Hello World;
- tuple=[fid:1:1:org.drools.examples.HelloWorldExample$Message at 17cec96]]
-[ObjectInserted: handle=[fid:1:1:org.drools.examples.HelloWorldExample$Message at 17cec96];
- object=org.drools.examples.HelloWorldExample$Message at 17cec96]
-[BeforeActivationFired: rule=Hello World;
- tuple=[fid:1:1:org.drools.examples.HelloWorldExample$Message at 17cec96]]
-==>[ActivationCreated(4): rule=Good Bye;
- tuple=[fid:1:2:org.drools.examples.HelloWorldExample$Message at 17cec96]]
-[ObjectUpdated: handle=[fid:1:2:org.drools.examples.HelloWorldExample$Message at 17cec96];
- old_object=org.drools.examples.HelloWorldExample$Message at 17cec96;
- new_object=org.drools.examples.HelloWorldExample$Message at 17cec96]
-[AfterActivationFired(0): rule=Hello World]
-[BeforeActivationFired: rule=Good Bye;
- tuple=[fid:1:2:org.drools.examples.HelloWorldExample$Message at 17cec96]]
-[AfterActivationFired(4): rule=Good Bye] </programlisting>
- </example>
-
- <para>The <emphasis role="bold">LHS (when)</emphasis> section of the rule
- states that it will be activated for each <emphasis>Message</emphasis>
- object inserted into the working memory whose <emphasis>status</emphasis> is
- <emphasis>Message.HELLO</emphasis>. Besides that, two variable binds are
- created: "<emphasis>message</emphasis>" variable is bound to the
- <emphasis>message</emphasis> attribute and "<emphasis>m</emphasis>" variable
- is bound to the <emphasis>object matched pattern</emphasis> itself.</para>
-
- <para>The <emphasis role="bold">RHS (consequence, then)</emphasis> section
- of the rule is written using the MVEL expression language, as declared by
- the rule's attribute <emphasis>dialect</emphasis>. After printing the
- content of the <emphasis>message</emphasis> bound variable to the default
- console, the rule changes the values of the <emphasis>message</emphasis> and
- <emphasis>status</emphasis> attributes of the <emphasis>m</emphasis> bound
- variable; using MVEL's 'modify' keyword which allows you to apply a block of
- setters in one statement, with the engine being automatically notified of
- the changes at the end of the block.</para>
-
- <example>
- <title>HelloWorld example: rule "Hello World"</title>
-
- <programlisting>rule "Hello World"
- dialect "mvel"
- when
- m : Message( status == Message.HELLO, message : message )
- then
- System.out.println( message );
- modify ( m ) { message = "Goodbyte cruel world",
- status = Message.GOODBYE };
-end</programlisting>
- </example>
-
- <para>We can add a break point into the DRL for when modify is called during
- the execution of the "Hello World" consequence and inspect the Agenda view
- again. Notice this time we "Debug As" a "Drools application" and not a "Java
- application".</para>
-
- <orderedlist>
- <listitem>
- <para>Open the class org.drools.examples.FibonacciExample in your
- Eclipse IDE</para>
- </listitem>
-
- <listitem>
- <para>Right-click the class an select "Debug as..." -> "Drools
- application"</para>
- </listitem>
- </orderedlist>
-
- <para>Now we can see that the other rule "Good Bye" which uses the java
- dialect is activated and placed on the agenda.</para>
-
- <figure>
- <title>Hello World : rule "Hello World" Agenda View</title>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="helloworld_agenda2.png" />
- </imageobject>
- </mediaobject>
- </figure>
-
- <para>The "Good Bye" rule is similar to the "Hello World" rule but matches
- Message objects whose status is Message.GOODBYE instead, printing its
- message to the default console, it specifies the "java" dialect.</para>
-
- <example>
- <title>HelloWorld example: rule "Good Bye"</title>
-
- <programlisting>rule "Good Bye"
- dialect "java"
- when
- Message( status == Message.GOODBYE, message : message )
- then
- System.out.println( message );
-end</programlisting>
- </example>
-
- <para>If you remember at the start of this example in the java code we
- created a WorkingMemoryFileLogger and called logger.writeToDisk() at the
- end, this created an audit log file that can be shown in the Audit view. We
- use the audit view in many of the examples to try and understand the example
- execution flow. In the view below we can see the object is inserted which
- creates an activation for the "Hello World" rule, the activation is then
- executed which updated the Message object causing the "Good Bye" rule to
- activate, the "Good Bye" rule then also executes. When an event in the Audit
- view is select it highlights the origin event in green, so below the
- Activation created event is highlighted in greed as the origin of the
- Activation executed event.</para>
-
- <figure>
- <title>Hello World : Audit View</title>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="helloworld_auditview1.png" />
- </imageobject>
- </mediaobject>
- </figure>
-</section>
\ No newline at end of file
Property changes on: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/HonestPolitician
___________________________________________________________________
Name: svn:ignore
+ *.db
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/HonestPolitician/honest_politician_audit.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/honest_politician_audit.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Manners/guests_at_table.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/guests_at_table.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Manners/guests_at_table.vsd (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/guests_at_table.vsd)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Manners/make_path.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/make_path.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Manners/make_path.vsd (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/make_path.vsd)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Manners/manners_activity_diagram.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/manners_activity_diagram.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Manners/manners_activity_diagram.svg (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/manners_activity_diagram.svg)
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Manners/manners_activity_diagram.svg (rev 0)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Manners/manners_activity_diagram.svg 2008-06-14 13:00:09 UTC (rev 20479)
@@ -0,0 +1,559 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated by Microsoft Visio 11.0, SVG Export, v1.0 manners_activity_diagram.svg Page-1 --><svg xmlns="http://www.w3.org/2000/svg" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" xmlns:xlink="http://www.w3.org/1999/xlink" width="7.89733in" height="6.9885in" viewBox="0 0 568.608 503.172" xml:space="preserve" color-interpolation-filters="sRGB" class="st14" preserveAspectRatio="xMidYMid meet" zoomAndPan="magnify" version="1.0" contentScriptType="text/ecmascript" contentStyleType="text/css">
+ <v:documentProperties v:langID="1033" v:metric="true"/>
+
+ <style type="text/css" xml:space="preserve">
+
+ .st1 {fill:none;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72}
+ .st2 {fill:#000000;font-family:Arial;font-size:1.00001em}
+ .st3 {font-size:1em}
+ .st4 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72}
+ .st5 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72}
+ .st6 {fill:#000000;font-family:Arial;font-size:0.666664em}
+ .st7 {fill:#000000;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.24}
+ .st8 {fill:#000000;stroke:none;stroke-width:1}
+ .st9 {marker-end:url(#mrkr3-71);stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.48}
+ .st10 {fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:0.10810806741051}
+ .st11 {fill:none}
+ .st12 {stroke:#000000;stroke-dasharray:5.04,3.6;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72}
+ .st13 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.24}
+ .st14 {fill:none;fill-rule:evenodd;font-size:12;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
+
+ </style>
+
+ <defs id="Markers">
+ <g id="lend3">
+ <path d="M 2 1 L 0 0 L 2 -1 " style="stroke-linecap:round;stroke-linejoin:round;fill:none"/>
+ </g>
+ <marker xmlns="http://www.w3.org/TR/xhtml1/transitional" overflow="visible" id="mrkr3-71" class="st10" v:arrowType="3" v:arrowSize="4" orient="auto" markerUnits="strokeWidth" preserveAspectRatio="xMidYMid meet">
+ <use xmlns="http://www.w3.org/2000/svg" xlink:href="#lend3" transform="scale(-9.2500034821895,-9.2500034821895) " xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
+ </marker>
+ </defs>
+ <g v:mID="0" v:index="1" v:groupContext="foregroundPage">
+ <title content="structured text">Page-1</title>
+ <v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394" v:shadowOffsetY="-8.50394"/>
+ <v:layer v:name="Swimlanes" v:index="0" v:snap="false" v:glue="false"/>
+ <g id="shape1-1" v:mID="1" v:groupContext="shape" v:layerMember="0" transform="translate(454.263,-0.720106)">
+ <title content="structured text">Swimlane.41</title>
+ <desc content="structured text">PRINT RESULTS</desc>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(63):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({3D0B90F0-7997-4048-B958-E2D430F8F96C})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a partition for organizing responsibility for activities.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197" v:verticalAlign="0"/>
+ <v:textRect cx="56.6929" cy="252.306" width="113.39" height="501.732"/>
+ <rect x="0" y="1.44021" width="113.386" height="501.732" class="st1"/>
+ <text x="9.36" y="16.24" class="st2" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>PRINT RESULTS</text> </g>
+ <g id="shape2-4" v:mID="2" v:groupContext="shape" v:layerMember="0" transform="translate(340.877,-0.720106)">
+ <title content="structured text">Swimlane.40</title>
+ <desc content="structured text">CHECK DONE</desc>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(63):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({B70CD6A2-C8F2-41E7-8A0B-4364B926C213})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a partition for organizing responsibility for activities.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197" v:verticalAlign="0"/>
+ <v:textRect cx="56.6929" cy="252.306" width="113.39" height="501.732"/>
+ <rect x="0" y="1.44021" width="113.386" height="501.732" class="st1"/>
+ <text x="16.69" y="16.24" class="st2" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>CHECK DONE</text> </g>
+ <g id="shape3-7" v:mID="3" v:groupContext="shape" v:layerMember="0" transform="translate(227.492,-0.720106)">
+ <title content="structured text">Swimlane.39</title>
+ <desc content="structured text">MAK PATH</desc>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(63):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({2BDF3D67-E7C5-4A9B-A36F-B092FDAD9B83})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a partition for organizing responsibility for activities.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197" v:verticalAlign="0"/>
+ <v:textRect cx="56.6929" cy="252.306" width="113.39" height="501.732"/>
+ <rect x="0" y="1.44021" width="113.386" height="501.732" class="st1"/>
+ <text x="22.02" y="16.24" class="st2" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>MAK<tspan class="st3" v:langID="2057">E</tspan> PATH</text> </g>
+ <g id="shape4-11" v:mID="4" v:groupContext="shape" v:layerMember="0" transform="translate(114.106,-0.720106)">
+ <title content="structured text">Swimlane.38</title>
+ <desc content="structured text">ASSIGN SEATS</desc>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(63):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({5FE20143-2F05-4843-84D8-69654A33246B})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a partition for organizing responsibility for activities.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197" v:verticalAlign="0"/>
+ <v:textRect cx="56.6929" cy="252.306" width="113.39" height="501.732"/>
+ <rect x="0" y="1.44021" width="113.386" height="501.732" class="st1"/>
+ <text x="12.68" y="16.24" class="st2" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>ASSIGN SEATS</text> </g>
+ <g id="shape5-14" v:mID="5" v:groupContext="shape" v:layerMember="0" transform="translate(0.72,-0.720106)">
+ <title content="structured text">Swimlane</title>
+ <desc content="structured text">START UP</desc>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(63):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({75512333-30FD-445E-A107-21F276DEBAB2})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a partition for organizing responsibility for activities.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197" v:verticalAlign="0"/>
+ <v:textRect cx="56.6929" cy="252.306" width="113.39" height="501.732"/>
+ <rect x="0" y="1.44021" width="113.386" height="501.732" class="st1"/>
+ <text x="27.03" y="16.24" class="st2" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>START UP</text> </g>
+ <g id="group6-17" transform="translate(21.6928,-370.641)" v:mID="6" v:groupContext="group">
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(40):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({DB57AEDC-DB06-4A74-9314-493961D4DB78})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
+ <v:ud v:nameU="UMLSuppressOption" v:val="VT0(32):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="UMLAutoLockTextEdit" v:val="VT0(1):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a condition during which an object satisfies some condition, performs an action or waits for an event.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <title content="structured text">State</title>
+ <g id="shape7-18" v:mID="7" v:groupContext="shape" transform="translate(-3.59712E-013,-0.002)">
+ <title content="structured text">Sheet.7</title>
+ <path d="M9 503.17 L62.44 503.17 A9 9 -180 0 0 71.44 494.17 L71.44 486.66 A9 9 -180 0 0 62.44 477.66 L9 477.66 A9 9 -180 0 0 -0 486.66 L0 494.17 A9 9 -180 0 0 9 503.17 Z" class="st4"/>
+ </g>
+ <g id="shape8-20" v:mID="8" v:groupContext="shape" transform="translate(0,-0.002)">
+ <title content="structured text">Transitions</title>
+ <path d="M0 503.17 L53.86 503.17 L0 503.17 Z" class="st5"/>
+ </g>
+ <g id="shape9-22" v:mID="9" v:groupContext="shape">
+ <title content="structured text">Name</title>
+ <desc content="structured text">Assign First Seat</desc>
+ <v:userDefs/>
+ <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
+ <v:textRect cx="35.7202" cy="490.572" width="71.45" height="25.2"/>
+ <rect x="0" y="477.972" width="71.4403" height="25.2" class="st5"/>
+ <text x="5.49" y="492.97" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Assign First Seat</text> </g>
+ </g>
+ <g id="shape10-25" v:mID="10" v:groupContext="shape" transform="translate(48.909,-459.93)">
+ <title content="structured text">Initial State</title>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(42):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({D3A1415C-7F84-4D75-B77E-54E0988D4921})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOptions" v:val="VT0(3):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents the point at which a newly created object starts. )"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <path d="M0 494.67 A8.505 8.505 0 0 1 17.01 494.67 A8.505 8.505 0 0 1 0 494.67 Z" class="st7"/>
+ </g>
+ <g id="group11-27" transform="translate(128.279,-370.641)" v:mID="11" v:groupContext="group">
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(40):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({E425FBE2-6092-4F19-BCF9-83EBE6D8AA54})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
+ <v:ud v:nameU="UMLSuppressOption" v:val="VT0(32):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="UMLAutoLockTextEdit" v:val="VT0(1):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a condition during which an object satisfies some condition, performs an action or waits for an event.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <title content="structured text">State.7</title>
+ <g id="shape12-28" v:mID="12" v:groupContext="shape" transform="translate(0,-0.002)">
+ <title content="structured text">Sheet.12</title>
+ <path d="M9 503.17 L45 503.17 A9 9 -180 0 0 54 494.17 L54 486.66 A9 9 -180 0 0 45 477.66 L9 477.66 A9 9 -180 0 0 -0 486.66 L0 494.17 A9 9 -180 0 0 9 503.17 Z" class="st4"/>
+ </g>
+ <g id="shape13-30" v:mID="13" v:groupContext="shape" transform="translate(-2.63789E-013,-0.002)">
+ <title content="structured text">Transitions</title>
+ <path d="M0 503.17 L53.86 503.17 L0 503.17 Z" class="st5"/>
+ </g>
+ <g id="shape14-32" v:mID="14" v:groupContext="shape">
+ <title content="structured text">Name</title>
+ <desc content="structured text">Assign Seat</desc>
+ <v:userDefs/>
+ <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
+ <v:textRect cx="27" cy="490.572" width="54" height="25.2"/>
+ <rect x="0" y="477.972" width="54" height="25.2" class="st5"/>
+ <text x="5.65" y="492.97" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Assign Seat</text> </g>
+ </g>
+ <g id="group15-35" transform="translate(268.817,-278.515)" v:mID="15" v:groupContext="group">
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(40):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({78CF0676-A242-4FF4-9B81-3A830037047F})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
+ <v:ud v:nameU="UMLSuppressOption" v:val="VT0(32):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="UMLAutoLockTextEdit" v:val="VT0(1):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a condition during which an object satisfies some condition, performs an action or waits for an event.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <title content="structured text">State.11</title>
+ <g id="shape16-36" v:mID="16" v:groupContext="shape" transform="translate(0,-0.002)">
+ <title content="structured text">Sheet.16</title>
+ <path d="M9 503.17 L45 503.17 A9 9 -180 0 0 54 494.17 L54 486.66 A9 9 -180 0 0 45 477.66 L9 477.66 A9 9 -180 0 0 -0 486.66 L0 494.17 A9 9 -180 0 0 9 503.17 Z" class="st4"/>
+ </g>
+ <g id="shape17-38" v:mID="17" v:groupContext="shape" transform="translate(-2.63789E-013,-0.002)">
+ <title content="structured text">Transitions</title>
+ <path d="M0 503.17 L53.86 503.17 L0 503.17 Z" class="st5"/>
+ </g>
+ <g id="shape18-40" v:mID="18" v:groupContext="shape">
+ <title content="structured text">Name</title>
+ <desc content="structured text">Make Path</desc>
+ <v:userDefs/>
+ <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
+ <v:textRect cx="27" cy="490.572" width="54" height="25.2"/>
+ <rect x="0" y="477.972" width="54" height="25.2" class="st5"/>
+ <text x="7.88" y="492.97" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Make Path</text> </g>
+ </g>
+ <g id="group19-43" transform="translate(268.817,-190.641)" v:mID="19" v:groupContext="group">
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(40):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({657E0538-CBB4-4B62-B170-CA54F78F0FC3})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
+ <v:ud v:nameU="UMLSuppressOption" v:val="VT0(32):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="UMLAutoLockTextEdit" v:val="VT0(1):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a condition during which an object satisfies some condition, performs an action or waits for an event.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <title content="structured text">State.15</title>
+ <g id="shape20-44" v:mID="20" v:groupContext="shape" transform="translate(0,-0.002)">
+ <title content="structured text">Sheet.20</title>
+ <path d="M9 503.17 L45 503.17 A9 9 -180 0 0 54 494.17 L54 486.66 A9 9 -180 0 0 45 477.66 L9 477.66 A9 9 -180 0 0 -0 486.66 L0 494.17 A9 9 -180 0 0 9 503.17 Z" class="st4"/>
+ </g>
+ <g id="shape21-46" v:mID="21" v:groupContext="shape" transform="translate(-2.63789E-013,-0.002)">
+ <title content="structured text">Transitions</title>
+ <path d="M0 503.17 L53.86 503.17 L0 503.17 Z" class="st5"/>
+ </g>
+ <g id="shape22-48" v:mID="22" v:groupContext="shape">
+ <title content="structured text">Name</title>
+ <desc content="structured text">Path Done</desc>
+ <v:userDefs/>
+ <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
+ <v:textRect cx="27" cy="490.572" width="54" height="25.2"/>
+ <rect x="0" y="477.972" width="54" height="25.2" class="st5"/>
+ <text x="8.1" y="492.97" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Path Done</text> </g>
+ </g>
+ <g id="group23-51" transform="translate(357.885,-114.106)" v:mID="23" v:groupContext="group">
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(40):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({0CB21845-E36D-4CDF-B78A-00B75363D7E2})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
+ <v:ud v:nameU="UMLSuppressOption" v:val="VT0(32):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="UMLAutoLockTextEdit" v:val="VT0(1):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a condition during which an object satisfies some condition, performs an action or waits for an event.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <title content="structured text">State.19</title>
+ <g id="shape24-52" v:mID="24" v:groupContext="shape" transform="translate(3.83693E-013,-0.002)">
+ <title content="structured text">Sheet.24</title>
+ <path d="M9 503.17 L68.67 503.17 A9 9 -180 0 0 77.67 494.17 L77.67 486.66 A9 9 -180 0 0 68.67 477.66 L9 477.66 A9 9 -180 0 0 0 486.66 L0 494.17 A9 9 -180 0 0 9 503.17 Z" class="st4"/>
+ </g>
+ <g id="shape25-54" v:mID="25" v:groupContext="shape" transform="translate(-3.8769E-013,-0.002)">
+ <title content="structured text">Transitions</title>
+ <path d="M0 503.17 L53.86 503.17 L0 503.17 Z" class="st5"/>
+ </g>
+ <g id="shape26-56" v:mID="26" v:groupContext="shape">
+ <title content="structured text">Name</title>
+ <desc content="structured text">Are We Done Yet?</desc>
+ <v:userDefs/>
+ <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
+ <v:textRect cx="38.8371" cy="490.572" width="77.68" height="25.2"/>
+ <rect x="0" y="477.972" width="77.6742" height="25.2" class="st5"/>
+ <text x="5.5" y="492.97" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Are We Done Yet?</text> </g>
+ </g>
+ <g id="group27-59" transform="translate(499.433,-14.8903)" v:mID="27" v:groupContext="group">
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(43):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({B1433F32-F2A4-439C-B8CC-D61EC899F625})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOptions" v:val="VT0(3):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents the final occurrence of an event at the enclosing state or the completion of activity in the enclosing state.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ <v:ud v:nameU="UMLPresOption1" v:prompt="" v:val="VT0(3):26"/>
+ </v:userDefs>
+ <title content="structured text">Final State</title>
+ <g id="shape28-60" v:mID="28" v:groupContext="shape" transform="translate(1.7,-1.7)">
+ <title content="structured text">Sheet.28</title>
+ <path d="M0 496.37 A6.805 6.805 0 1 1 13.61 496.37 A6.805 6.805 0 1 1 -0 496.37 Z" class="st8"/>
+ </g>
+ <g id="shape29-62" v:mID="29" v:groupContext="shape" transform="translate(1.7,-1.7)">
+ <title content="structured text">Sheet.29</title>
+ <path d="M0 496.37 A6.805 6.805 0 1 1 13.61 496.37 A6.805 6.805 0 1 1 -0 496.37 Z" class="st1"/>
+ </g>
+ <g id="shape30-64" v:mID="30" v:groupContext="shape">
+ <title content="structured text">Sheet.30</title>
+ <path d="M0 494.67 A8.505 8.505 0 0 1 17.01 494.67 A8.505 8.505 0 1 1 -0 494.67 Z" class="st1"/>
+ </g>
+ </g>
+ <g id="shape31-66" v:mID="31" v:groupContext="shape" transform="translate(93.1331,-383.393)">
+ <title content="structured text">Transition</title>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({B3C07C44-3D10-4AD1-A487-A918B63E7036})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <path d="M0 503.17 L35.15 503.17" class="st9"/>
+ </g>
+ <g id="shape32-72" v:mID="32" v:groupContext="shape" transform="translate(155.279,-291.273)">
+ <title content="structured text">Transition.26</title>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({4F3E71C3-C7E3-4C97-BCE4-9EE74B61A90E})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <path d="M0 423.8 L0 503.17 L113.54 503.17" class="st9"/>
+ </g>
+ <g id="shape33-77" v:mID="33" v:groupContext="shape" transform="translate(295.82,-216.157)">
+ <title content="structured text">Transition.27</title>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({504935DB-8552-4C36-BB2A-679D59656DF9})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <path d="M0 440.81 L0 503.17" class="st9"/>
+ </g>
+ <g id="shape34-82" v:mID="34" v:groupContext="shape" transform="translate(322.817,-203.393)">
+ <title content="structured text">Transition.23</title>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({57E139FF-A173-426F-820B-4F7C9BFEC138})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <path d="M0 503.17 L63.98 503.17" class="st9"/>
+ </g>
+ <g id="shape35-87" v:mID="35" v:groupContext="shape" transform="translate(507.94,-31.8981)">
+ <title content="structured text">Transition.28</title>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({5FECE46A-D06F-418F-981D-461303A12B44})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <path d="M0 420.96 L0 503.17" class="st9"/>
+ </g>
+ <g id="shape36-92" v:mID="36" v:groupContext="shape" transform="translate(182.277,-298.36)">
+ <title content="structured text">Transition.29</title>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({2C74DA93-74E8-41A5-92D8-33F11DFE1CC4})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <path d="M216.64 503.17 L216.64 418.13 L0 418.13" class="st9"/>
+ </g>
+ <g id="shape37-97" v:mID="37" v:groupContext="shape" transform="translate(57.4163,-396.155)">
+ <title content="structured text">Transition.30</title>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({184492BD-048C-4EF2-8A9B-8858BE1127F1})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <path d="M0 439.39 L0 503.17" class="st9"/>
+ </g>
+ <g id="shape38-102" v:mID="38" v:groupContext="shape" transform="translate(386.801,-193.478)">
+ <title content="structured text">Decision</title>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(62):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({92B419EA-931A-4897-B261-6E85B2B91766})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption1" v:val="VT0(3):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Expresses a decision when guard conditions are used to indicate different possible transitions that are Boolean dependent.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <path d="M9.92 483.33 L19.84 493.25 L9.92 503.17 L0 493.25 L9.92 483.33 Z" class="st4"/>
+ </g>
+ <g id="shape39-104" v:mID="39" v:groupContext="shape" transform="translate(396.726,-139.618)">
+ <title content="structured text">Transition.32</title>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({0C0D162D-C8BA-4916-9E41-0251B2A289C3})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <path d="M0 449.31 L0 503.17" class="st9"/>
+ </g>
+ <g id="group40-109" transform="translate(406.645,-203.395)" v:mID="40" v:groupContext="group">
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(45):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({9E3814E0-25B1-43C1-A187-E4B1218E0059})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="UMLPresOption1" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Use to place a comment on a diagram. )"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <title content="structured text">Note</title>
+ <g id="shape41-110" v:mID="41" v:groupContext="shape">
+ <title content="structured text">Sheet.41</title>
+ <path d="M109.98 472.41 L0 503.17 L109.98 472.41 Z" class="st11"/>
+ <path d="M109.98 472.41 L0 503.17" class="st12"/>
+ </g>
+ <g id="shape42-113" v:mID="42" v:groupContext="shape" transform="translate(66.5014,-12.76)">
+ <title content="structured text">Name</title>
+ <desc content="structured text">Has the last seat been assigned?</desc>
+ <v:userDefs/>
+ <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
+ <v:textRect cx="43.4786" cy="485.174" width="86.96" height="36"/>
+ <path d="M86.96 477.97 L77.96 467.17 L77.96 477.97 L86.96 477.97 Z M0 503.17 L86.96 503.17 L86.96 477.97 L77.96 477.97 L77.96 467.17 L0 467.17 L0 503.17 Z" class="st13"/>
+ <text x="4" y="477.97" class="st6" v:langID="1033"><v:paragraph/><v:tabList/>Has the last seat<v:newlineChar/><v:newlineChar/><tspan x="4" dy="2.4em" class="st3">been assigned</tspan>?</text> </g>
+ </g>
+ <g id="shape43-117" v:mID="43" v:groupContext="shape" transform="translate(241.247,-162.295)">
+ <title content="structured text">Transition.36</title>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({4CA9F553-D55B-452E-AC25-34A2387F9FF8})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <path d="M54.57 474.82 L54.57 503.17 L0 503.17 L0 462.07 L27.57 462.07" class="st9"/>
+ </g>
+ <g id="group44-122" transform="translate(479.775,-114.106)" v:mID="44" v:groupContext="group">
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(40):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({45A56721-BBBC-4499-92F5-D1460BF36DFC})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
+ <v:ud v:nameU="UMLSuppressOption" v:val="VT0(32):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="UMLAutoLockTextEdit" v:val="VT0(1):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a condition during which an object satisfies some condition, performs an action or waits for an event.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <title content="structured text">State.42</title>
+ <g id="shape45-123" v:mID="45" v:groupContext="shape" transform="translate(2.79776E-013,-0.002)">
+ <title content="structured text">Sheet.45</title>
+ <path d="M9 503.17 L47.32 503.17 A9 9 -180 0 0 56.32 494.17 L56.32 486.66 A9 9 -180 0 0 47.32 477.66 L9 477.66 A9 9 -180 0 0 -0 486.66 L0 494.17 A9 9 -180 0 0 9 503.17 Z" class="st4"/>
+ </g>
+ <g id="shape46-125" v:mID="46" v:groupContext="shape" transform="translate(-2.79776E-013,-0.002)">
+ <title content="structured text">Transitions</title>
+ <path d="M0 503.17 L53.86 503.17 L0 503.17 Z" class="st5"/>
+ </g>
+ <g id="shape47-127" v:mID="47" v:groupContext="shape">
+ <title content="structured text">Name</title>
+ <desc content="structured text">Print Results</desc>
+ <v:userDefs/>
+ <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
+ <v:textRect cx="28.1617" cy="490.572" width="56.33" height="25.2"/>
+ <rect x="0" y="477.972" width="56.3234" height="25.2" class="st5"/>
+ <text x="5.5" y="492.97" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Print Results</text> </g>
+ </g>
+ <g id="shape48-130" v:mID="48" v:groupContext="shape" transform="translate(435.56,-126.857)">
+ <title content="structured text">Transition.46</title>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({1E830686-D9A6-494E-BFB9-A2EC4ECC87E5})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <path d="M0 503.17 L44.22 503.17" class="st9"/>
+ </g>
+ <g id="shape49-135" v:mID="49" v:groupContext="shape" transform="translate(507.939,-126.865)">
+ <title content="structured text">Transition.47</title>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({522F1FDF-7CC6-4604-AE43-C0C5FBC68F58})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <path d="M28.16 503.17 L48.37 503.17 L48.37 464.91 L0 464.91 L0 490.42" class="st9"/>
+ </g>
+ <g id="group50-140" transform="translate(371.917,-272.846)" v:mID="50" v:groupContext="group">
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(40):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({279920C9-96D3-48C9-B5C7-9BD96A5EA82B})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
+ <v:ud v:nameU="UMLSuppressOption" v:val="VT0(32):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="UMLAutoLockTextEdit" v:val="VT0(1):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a condition during which an object satisfies some condition, performs an action or waits for an event.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <title content="structured text">State.48</title>
+ <g id="shape51-141" v:mID="51" v:groupContext="shape" transform="translate(0,-0.002)">
+ <title content="structured text">Sheet.51</title>
+ <path d="M9 503.17 L45 503.17 A9 9 -180 0 0 54 494.17 L54 486.66 A9 9 -180 0 0 45 477.66 L9 477.66 A9 9 -180 0 0 0 486.66 L0 494.17 A9 9 -180 0 0 9 503.17 Z" class="st4"/>
+ </g>
+ <g id="shape52-143" v:mID="52" v:groupContext="shape" transform="translate(-2.67786E-013,-0.002)">
+ <title content="structured text">Transitions</title>
+ <path d="M0 503.17 L53.86 503.17 L0 503.17 Z" class="st5"/>
+ </g>
+ <g id="shape53-145" v:mID="53" v:groupContext="shape">
+ <title content="structured text">Name</title>
+ <desc content="structured text">Continue?</desc>
+ <v:userDefs/>
+ <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
+ <v:textRect cx="27" cy="490.572" width="54" height="25.2"/>
+ <rect x="0" y="477.972" width="54" height="25.2" class="st5"/>
+ <text x="8.76" y="492.97" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Continue?</text> </g>
+ </g>
+ <g id="shape54-148" v:mID="54" v:groupContext="shape" transform="translate(396.723,-213.32)">
+ <title content="structured text">Transition.52</title>
+ <v:userDefs>
+ <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
+ <v:ud v:nameU="UMLObjectGUID" v:val="VT4({9C4F3353-5467-4385-8431-508C3C950FD2})"/>
+ <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
+ <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
+ <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
+ <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
+ <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
+ </v:userDefs>
+ <path d="M0 503.17 L2.19 443.64" class="st9"/>
+ </g>
+ </g>
+</svg>
\ No newline at end of file
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Manners/manners_activity_diagram.vsd (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/manners_activity_diagram.vsd)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/NumberGuess/numberguess-constraint-toohigh.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/numberguess-constraint-toohigh.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/NumberGuess/numberguess-editconstraints.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/numberguess-editconstraints.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/NumberGuess/numberguess-ruleflow-properties.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/numberguess-ruleflow-properties.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/NumberGuess/numberguess-ruleflow.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/numberguess-ruleflow.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-BankingExample.xml (from rev 20478, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/BankingExample/Section-BankingExample.xml)
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-BankingExample.xml (rev 0)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-BankingExample.xml 2008-06-14 13:00:09 UTC (rev 20479)
@@ -0,0 +1,592 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <section xml:base="../">
+ <title>Banking Tutorial</title>
+
+ <screen><emphasis role="bold">Name:</emphasis> BankingTutorial
+<emphasis role="bold">Main class:</emphasis> org.drools.tutorials.banking.*
+<emphasis role="bold">Type:</emphasis> java application
+<emphasis role="bold">Rules file:</emphasis> org.drools.tutorials.banking.*
+<emphasis role="bold">Objective:</emphasis> tutorial that builds up knowledge of pattern matching, basic sorting and calculation rules.</screen>
+
+ <para>This tutorial will demonstrate the process of developing a complete personal banking application that will handle credits, debits, currencies and that will use a set of design patterns that have been created for the process. In order to make the examples documented here clear and modular, I will try and steer away from re-visiting existing code to add new functionality, and will instead extend and inject where appropriate.</para>
+
+ <para>The RuleRunner class is a simple harness to execute one or more drls against a set of data. It compiles the Packages and creates the RuleBase for each execution, this allows us to easy execute each scenario and see the outputs. In reality this is not a good solution for a production system where the RuleBase should be built just once and cached, but for the purposes of this tutorial it shall suffice.</para>
+
+ <example>
+ <title>Banking Tutorial : RuleRunner</title>
+
+ <programlisting>public class RuleRunner {
+
+ public RuleRunner() {
+ }
+
+ public void runRules(String[] rules,
+ Object[] facts) throws Exception {
+
+ RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+ PackageBuilder builder = new PackageBuilder();
+
+ for ( int i = 0; i < rules.length; i++ ) {
+ String ruleFile = rules[i];
+ System.out.println( "Loading file: " + ruleFile );
+ builder.addPackageFromDrl(new InputStreamReader( RuleRunner.class.getResourceAsStream( ruleFile ) ) );
+ }
+
+ Package pkg = builder.getPackage();
+ ruleBase.addPackage( pkg );
+ WorkingMemory workingMemory = ruleBase.newStatefulSession();
+
+ for ( int i = 0; i < facts.length; i++ ) {
+ Object fact = facts[i];
+ System.out.println( "Inserting fact: " + fact );
+ workingMemory.insert( fact );
+ }
+
+ workingMemory.fireAllRules();
+ }
+}</programlisting>
+ </example>
+
+ <para>This is our first Example1.java class it loads and executes a single drl file "Example.drl" but inserts no data.</para>
+
+ <example>
+ <title>Banking Tutorial : Java Example1</title>
+
+ <programlisting>public class Example1 {
+ public static void main(String[] args) throws Exception {
+ new RuleRunner().runRules( new String[] { "Example1.drl" },
+ new Object[0] );
+ }
+}</programlisting>
+ </example>
+
+ <para>And this is the first simple rule to execute. It has a single "eval" condition that will alway be true, thus this rul will always match and fire.</para>
+
+ <example>
+ <title>Banking Tutorial : Rule Example1</title>
+
+ <programlisting>rule "Rule 01"
+ when
+ eval (1==1)
+ then
+ System.out.println("Rule 01 Works");
+endh</programlisting>
+ </example>
+
+ <para>The output for the rule is below, the rule matches and executes the single print statement.</para>
+
+ <example>
+ <title>Banking Tutorial : Output Example1</title>
+
+ <programlisting>Loading file: Example1.drl
+Rule 01 Works</programlisting>
+ </example>
+
+ <para>The next step is to assert some simple facts and print them out. </para>
+
+ <example>
+ <title>Banking Tutorial : Java Example2</title>
+
+ <programlisting>public class Example2 {
+ public static void main(String[] args) throws Exception {
+ Number[] numbers = new Number[] {wrap(3), wrap(1), wrap(4), wrap(1), wrap(5)};
+ new RuleRunner().runRules( new String[] { "Example2.drl" },
+ numbers );
+ }
+
+ private static Integer wrap(int i) {
+ return new Integer(i);
+ }
+}</programlisting>
+ </example>
+
+ <para>This doesnât use any specific facts but instead asserts a set of java.lang.Integerâs. This is not considered "best practice" as a number of a collection is not a fact, it is not a thing. A Bank acount has a number, its balance, thus the Account is the fact; but to get started asserting Integers shall suffice for demonstration purposes as the complexity is built up.</para>
+
+ <para>Now we will create a simple rule to print out these numbers.</para>
+
+ <example>
+ <title>Banking Tutorial : Rule Example2</title>
+
+ <programlisting>rule "Rule 02"
+ when
+ Number( $intValue : intValue )
+ then
+ System.out.println("Number found with value: " + $intValue);
+end</programlisting>
+ </example>
+
+ <para>Once again, this rule does nothing special. It identifies any facts that are Numbers and prints out the values. Notice the user of interfaces here, we inserted Integers but the pattern matching engine is able to match the interfaces and super classes of the asserted objects.</para>
+
+ <para>The output shows the drl being loaded, the facts inserted and then the matched and fired rules. We can see that each inserted number is matched and fired and thus printed.</para>
+
+ <example>
+ <title>Banking Tutorial : Output Example2</title>
+
+ <programlisting>Loading file: Example2.drl
+Inserting fact: 3
+Inserting fact: 1
+Inserting fact: 4
+Inserting fact: 1
+Inserting fact: 5
+Number found with value: 5
+Number found with value: 1
+Number found with value: 4
+Number found with value: 1
+Number found with value: 3
+</programlisting>
+ </example>
+
+ <para>here are probably a hundred and one better ways to sort numbers; but we will need to apply some cashflows in date order when we start looking at banking rules so letâs look at a simple rule based example.</para>
+
+ <example>
+ <title>Banking Tutorial : Java Example3</title>
+
+ <programlisting>public class Example3 {
+ public static void main(String[] args) throws Exception {
+ Number[] numbers = new Number[] {wrap(3), wrap(1), wrap(4), wrap(1), wrap(5)};
+ new RuleRunner().runRules( new String[] { "Example3.drl" },
+ numbers );
+ }
+
+ private static Integer wrap(int i) {
+ return new Integer(i);
+ }
+}</programlisting>
+ </example>
+
+ <para>Again we insert our Integers as before, this time the rule is slightly different:</para>
+
+ <example>
+ <title>Banking Tutorial : Rule Example3</title>
+
+ <programlisting>rule "Rule 03"
+ when
+ $number : Number( )
+ not Number( intValue < $number.intValue )
+ then
+ System.out.println("Number found with value: " + $number.intValue() );
+ retract( $number );
+end</programlisting>
+ </example>
+
+ <para>The first line of the rules identifies a Number and extracts the value. The second line ensures that there does not exist a smaller number than the one found. By executing this rule, we might expect to find only one number - the smallest in the set. However, the retraction of the number after it has been printed, means that the smallest number has been removed, revealing the next smallest number, and so on. </para>
+
+ <para>So, the output we generate is, notice the numbers are now sorted numerically.</para>
+
+ <example>
+ <title>Banking Tutorial : Output Example3</title>
+
+ <programlisting>Loading file: Example3.drl
+Inserting fact: 3
+Inserting fact: 1
+Inserting fact: 4
+Inserting fact: 1
+Inserting fact: 5
+Number found with value: 1
+Number found with value: 1
+Number found with value: 3
+Number found with value: 4
+Number found with value: 5
+</programlisting>
+ </example>
+
+ <para>Now we want to start moving towards our personal accounting rules. The first step is to create a Cashflow POJO.</para>
+
+ <example>
+ <title>Banking Tutoria : Class Cashflow</title>
+
+ <programlisting>public class Cashflow {
+ private Date date;
+ private double amount;
+
+ public Cashflow() {
+ }
+
+ public Cashflow(Date date,
+ double amount) {
+ this.date = date;
+ this.amount = amount;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ public double getAmount() {
+ return amount;
+ }
+
+ public void setAmount(double amount) {
+ this.amount = amount;
+ }
+
+ public String toString() {
+ return "Cashflow[date=" + date + ",amount=" + amount + "]";
+ }
+}</programlisting>
+ </example>
+
+ <para>The Cashflow has two simple attributes, a date and an amount. I have added a toString method to print it and overloaded the constructor to set the values. The Example4 java code inserts 5 Cashflow objecst with varying dates and amounts.</para>
+
+ <example>
+ <title>Banking Tutorial : Java Example4</title>
+
+ <programlisting>public class Example4 {
+ public static void main(String[] args) throws Exception {
+ Object[] cashflows = {
+ new Cashflow(new SimpleDate("01/01/2007"), 300.00),
+ new Cashflow(new SimpleDate("05/01/2007"), 100.00),
+ new Cashflow(new SimpleDate("11/01/2007"), 500.00),
+ new Cashflow(new SimpleDate("07/01/2007"), 800.00),
+ new Cashflow(new SimpleDate("02/01/2007"), 400.00),
+ };
+
+ new RuleRunner().runRules( new String[] { "Example4.drl" },
+ cashflows );
+ }
+}</programlisting>
+ </example>
+
+ <para>SimpleDate is a simple class that extends Date and takes a String as input. It allows for pre-formatted Data classes, for convienience. The code is listed below</para>
+
+ <example>
+ <title>Banking Tutorial : Java SimpleDate</title>
+
+ <programlisting>public class SimpleDate extends Date {
+ private static final SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
+
+ public SimpleDate(String datestr) throws Exception {
+ setTime(format.parse(datestr).getTime());
+ }
+}</programlisting>
+ </example>
+
+ <para>Now, letâs look at rule04.drl to see how we print the sorted Cashflows:</para>
+
+ <example>
+ <title>Banking Tutorial : Rule Example4</title>
+
+ <programlisting>rule "Rule 04"
+ when
+ $cashflow : Cashflow( $date : date, $amount : amount )
+ not Cashflow( date < $date)
+ then
+ System.out.println("Cashflow: "+$date+" :: "+$amount);
+ retract($cashflow);
+end</programlisting>
+ </example>
+
+ <para>Here, we identify a Cashflow and extract the date and the amount. In the second line of the rules we ensure that there is not a Cashflow with an earlier date than the one found. In the consequences, we print the Cashflow that satisfies the rules and then retract it, making way for the next earliest Cashflow. So, the output we generate is:</para>
+
+ <example>
+ <title>Banking Tutorial : Output Example4</title>
+
+ <programlisting>Loading file: Example4.drl
+Inserting fact: Cashflow[date=Mon Jan 01 00:00:00 GMT 2007,amount=300.0]
+Inserting fact: Cashflow[date=Fri Jan 05 00:00:00 GMT 2007,amount=100.0]
+Inserting fact: Cashflow[date=Thu Jan 11 00:00:00 GMT 2007,amount=500.0]
+Inserting fact: Cashflow[date=Sun Jan 07 00:00:00 GMT 2007,amount=800.0]
+Inserting fact: Cashflow[date=Tue Jan 02 00:00:00 GMT 2007,amount=400.0]
+Cashflow: Mon Jan 01 00:00:00 GMT 2007 :: 300.0
+Cashflow: Tue Jan 02 00:00:00 GMT 2007 :: 400.0
+Cashflow: Fri Jan 05 00:00:00 GMT 2007 :: 100.0
+Cashflow: Sun Jan 07 00:00:00 GMT 2007 :: 800.0
+Cashflow: Thu Jan 11 00:00:00 GMT 2007 :: 500.0
+</programlisting>
+ </example>
+
+ <para>Here we extend our Cashflow to give a TypedCashflow which can be CREDIT or DEBIT. Ideally, we would just add this to the Cashflow type, but so that we can keep all the examples simple, we will go with the extensions.</para>
+
+ <example>
+ <title>Banking Tutoria : Class TypedCashflow</title>
+
+ <programlisting>public class TypedCashflow extends Cashflow {
+ public static final int CREDIT = 0;
+ public static final int DEBIT = 1;
+
+ private int type;
+
+ public TypedCashflow() {
+ }
+
+ public TypedCashflow(Date date,
+ int type,
+ double amount) {
+ super( date,
+ amount );
+ this.type = type;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public String toString() {
+ return "TypedCashflow[date=" + getDate() + ",type=" + (type == CREDIT ? "Credit" : "Debit") + ",amount=" + getAmount() + "]";
+ }
+}</programlisting>
+ </example>
+
+ <para>There are lots of ways to improve this code, but for the sake of the example this will do.</para>
+
+ <para>Nows lets create the Example5 runner.</para>
+
+ <example>
+ <title>Banking Tutorial : Java Example5</title>
+
+ <programlisting>public class Example5 {
+ public static void main(String[] args) throws Exception {
+ Object[] cashflows = {
+ new TypedCashflow(new SimpleDate("01/01/2007"),
+ TypedCashflow.CREDIT, 300.00),
+ new TypedCashflow(new SimpleDate("05/01/2007"),
+ TypedCashflow.CREDIT, 100.00),
+ new TypedCashflow(new SimpleDate("11/01/2007"),
+ TypedCashflow.CREDIT, 500.00),
+ new TypedCashflow(new SimpleDate("07/01/2007"),
+ TypedCashflow.DEBIT, 800.00),
+ new TypedCashflow(new SimpleDate("02/01/2007"),
+ TypedCashflow.DEBIT, 400.00),
+ };
+
+ new RuleRunner().runRules( new String[] { "Example5.drl" },
+ cashflows );
+ }
+}</programlisting>
+ </example>
+
+ <para>Here, we simply create a set of Cashflows which are either CREDIT or DEBIT Cashflows and supply them and rule05.drl to the RuleEngine. </para>
+
+ <para>Now, letâs look at rule0 Example5.drl to see how we print the sorted Cashflows:</para>
+
+ <example>
+ <title>Banking Tutorial : Rule Example5</title>
+
+ <programlisting>rule "Rule 05"
+ when
+ $cashflow : TypedCashflow( $date : date,
+ $amount : amount,
+ type == TypedCashflow.CREDIT )
+ not TypedCashflow( date < $date,
+ type == TypedCashflow.CREDIT )
+ then
+ System.out.println("Credit: "+$date+" :: "+$amount);
+ retract($cashflow);
+end</programlisting>
+ </example>
+
+ <para>Here, we identify a Cashflow with a type of CREDIT and extract the date and the amount. In the second line of the rules we ensure that there is not a Cashflow of type CREDIT with an earlier date than the one found. In the consequences, we print the Cashflow that satisfies the rules and then retract it, making way for the next earliest Cashflow of type CREDIT.</para>
+
+ <para>So, the output we generate is</para>
+
+ <example>
+ <title>Banking Tutorial : Output Example5</title>
+
+ <screen>Loading file: Example5.drl
+Inserting fact: TypedCashflow[date=Mon Jan 01 00:00:00 GMT 2007,type=Credit,amount=300.0]
+Inserting fact: TypedCashflow[date=Fri Jan 05 00:00:00 GMT 2007,type=Credit,amount=100.0]
+Inserting fact: TypedCashflow[date=Thu Jan 11 00:00:00 GMT 2007,type=Credit,amount=500.0]
+Inserting fact: TypedCashflow[date=Sun Jan 07 00:00:00 GMT 2007,type=Debit,amount=800.0]
+Inserting fact: TypedCashflow[date=Tue Jan 02 00:00:00 GMT 2007,type=Debit,amount=400.0]
+Credit: Mon Jan 01 00:00:00 GMT 2007 :: 300.0
+Credit: Fri Jan 05 00:00:00 GMT 2007 :: 100.0
+Credit: Thu Jan 11 00:00:00 GMT 2007 :: 500.0
+</screen>
+ </example>
+
+ <para>Here we are going to process both CREDITs and DEBITs on 2 bank accounts to calculate the account balance. In order to do this, I am going to create two separate Account Objects and inject them into the Cashflows before passing them to the Rule Engine. The reason for this is to provide easy access to the correct Bank Accounts without having to resort to Helper classes. Letâs take a look at the Account class first. This is a simple POJO with an account number and balance:</para>
+
+ <example>
+ <title>Banking Tutoria : Class Account</title>
+
+ <programlisting>public class Account {
+ private long accountNo;
+ private double balance = 0;
+
+ public Account() {
+ }
+
+ public Account(long accountNo) {
+ this.accountNo = accountNo;
+ }
+
+ public long getAccountNo() {
+ return accountNo;
+ }
+
+ public void setAccountNo(long accountNo) {
+ this.accountNo = accountNo;
+ }
+
+ public double getBalance() {
+ return balance;
+ }
+
+ public void setBalance(double balance) {
+ this.balance = balance;
+ }
+
+ public String toString() {
+ return "Account[" + "accountNo=" + accountNo + ",balance=" + balance + "]";
+ }
+}</programlisting>
+ </example>
+
+ <para>Now letâs extend our TypedCashflow to give AllocatedCashflow (allocated to an account).</para>
+
+ <example>
+ <title>Banking Tutoria : Class AllocatedCashflow</title>
+
+ <programlisting>public class AllocatedCashflow extends TypedCashflow {
+ private Account account;
+
+ public AllocatedCashflow() {
+ }
+
+ public AllocatedCashflow(Account account,
+ Date date,
+ int type,
+ double amount) {
+ super( date,
+ type,
+ amount );
+ this.account = account;
+ }
+
+ public Account getAccount() {
+ return account;
+ }
+
+ public void setAccount(Account account) {
+ this.account = account;
+ }
+
+ public String toString() {
+ return "AllocatedCashflow[" + "account=" + account + ",date=" + getDate() +
+ ",type=" + (getType() == CREDIT ? "Credit" : "Debit") +
+ ",amount=" + getAmount() + "]";
+ }
+}</programlisting>
+ </example>
+
+ <para>Now, letâs java code for Example5 execution. Here we create two Account objects and inject one into each cashflow as appropriate. For simplicity I have simply included them in the constructor.</para>
+
+ <example>
+ <title>Banking Tutorial : Java Example5</title>
+
+ <programlisting>public class Example6 {
+ public static void main(String[] args) throws Exception {
+ Account acc1 = new Account(1);
+ Account acc2 = new Account(2);
+
+ Object[] cashflows = {
+ new AllocatedCashflow(acc1,new SimpleDate("01/01/2007"),
+ TypedCashflow.CREDIT, 300.00),
+ new AllocatedCashflow(acc1,new SimpleDate("05/02/2007"),
+ TypedCashflow.CREDIT, 100.00),
+ new AllocatedCashflow(acc2,new SimpleDate("11/03/2007"),
+ TypedCashflow.CREDIT, 500.00),
+ new AllocatedCashflow(acc1,new SimpleDate("07/02/2007"),
+ TypedCashflow.DEBIT, 800.00),
+ new AllocatedCashflow(acc2,new SimpleDate("02/03/2007"),
+ TypedCashflow.DEBIT, 400.00),
+ new AllocatedCashflow(acc1,new SimpleDate("01/04/2007"),
+ TypedCashflow.CREDIT, 200.00),
+ new AllocatedCashflow(acc1,new SimpleDate("05/04/2007"),
+ TypedCashflow.CREDIT, 300.00),
+ new AllocatedCashflow(acc2,new SimpleDate("11/05/2007"),
+ TypedCashflow.CREDIT, 700.00),
+ new AllocatedCashflow(acc1,new SimpleDate("07/05/2007"),
+ TypedCashflow.DEBIT, 900.00),
+ new AllocatedCashflow(acc2,new SimpleDate("02/05/2007"),
+ TypedCashflow.DEBIT, 100.00)
+ };
+
+ new RuleRunner().runRules( new String[] { "Example6.drl" },
+ cashflows );
+ }
+}</programlisting>
+ </example>
+
+ <para>Now, letâs look at rule Example06.drl to see how we apply each cashflow in date order and calculate and print the balance. </para>
+
+ <example>
+ <title>Banking Tutorial : Rule Example6</title>
+
+ <programlisting>rule "Rule 06 - Credit"
+ when
+ $cashflow : AllocatedCashflow( $account : account,
+ $date : date, $amount : amount,
+ type==TypedCashflow.CREDIT )
+ not AllocatedCashflow( account == $account, date < $date)
+ then
+ System.out.println("Credit: " + $date + " :: " + $amount);
+ $account.setBalance($account.getBalance()+$amount);
+ System.out.println("Account: " + $account.getAccountNo() +
+ " - new balance: " + $account.getBalance());
+ retract($cashflow);
+end
+
+rule "Rule 06 - Debit"
+ when
+ $cashflow : AllocatedCashflow( $account : account,
+ $date : date, $amount : amount,
+ type==TypedCashflow.DEBIT )
+ not AllocatedCashflow( account == $account, date < $date)
+ then
+ System.out.println("Debit: " + $date + " :: " + $amount);
+ $account.setBalance($account.getBalance() - $amount);
+ System.out.println("Account: " + $account.getAccountNo() +
+ " - new balance: " + $account.getBalance());
+ retract($cashflow);
+end</programlisting>
+ </example>
+
+ <para>Here, we have separate rules for CREDITs and DEBITs, however we do not specify a type when checking for earlier cashflows. This is so that all cashflows are applied in date order regardless of which type of cashflow type they are. In the rule section we identify the correct account to work with and in the consequences we update it with the cashflow amount.</para>
+
+ <example>
+ <title>Banking Tutorial : Output Example6</title>
+
+ <programlisting>Loading file: Example6.drl
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Mon Jan 01 00:00:00 GMT 2007,type=Credit,amount=300.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Mon Feb 05 00:00:00 GMT 2007,type=Credit,amount=100.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Sun Mar 11 00:00:00 GMT 2007,type=Credit,amount=500.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Wed Feb 07 00:00:00 GMT 2007,type=Debit,amount=800.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Fri Mar 02 00:00:00 GMT 2007,type=Debit,amount=400.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Sun Apr 01 00:00:00 BST 2007,type=Credit,amount=200.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Thu Apr 05 00:00:00 BST 2007,type=Credit,amount=300.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Fri May 11 00:00:00 BST 2007,type=Credit,amount=700.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Mon May 07 00:00:00 BST 2007,type=Debit,amount=900.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Wed May 02 00:00:00 BST 2007,type=Debit,amount=100.0]
+Debit: Fri Mar 02 00:00:00 GMT 2007 :: 400.0
+Account: 2 - new balance: -400.0
+Credit: Sun Mar 11 00:00:00 GMT 2007 :: 500.0
+Account: 2 - new balance: 100.0
+Debit: Wed May 02 00:00:00 BST 2007 :: 100.0
+Account: 2 - new balance: 0.0
+Credit: Fri May 11 00:00:00 BST 2007 :: 700.0
+Account: 2 - new balance: 700.0
+Credit: Mon Jan 01 00:00:00 GMT 2007 :: 300.0
+Account: 1 - new balance: 300.0
+Credit: Mon Feb 05 00:00:00 GMT 2007 :: 100.0
+Account: 1 - new balance: 400.0
+Debit: Wed Feb 07 00:00:00 GMT 2007 :: 800.0
+Account: 1 - new balance: -400.0
+Credit: Sun Apr 01 00:00:00 BST 2007 :: 200.0
+Account: 1 - new balance: -200.0
+Credit: Thu Apr 05 00:00:00 BST 2007 :: 300.0
+Account: 1 - new balance: 100.0
+Debit: Mon May 07 00:00:00 BST 2007 :: 900.0
+Account: 1 - new balance: -800.0
+</programlisting>
+ </example>
+
+ </section>
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-Examples.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-Examples.xml 2008-06-14 01:58:02 UTC (rev 20478)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-Examples.xml 2008-06-14 13:00:09 UTC (rev 20479)
@@ -8,355 +8,14 @@
<para>Make sure the Drools Eclipse plugin is installed, which needs GEF dependency installed first. Then download and extract the drools-examples zip file, which includes an already created Eclipse project. Import that project into a new Eclipse workspace. The rules all have example classes that execute the rules. If you want to try the examples in another project (or another IDE) then you will need to setup the dependencies by hand of course. Many, but not all of the examples are documented below, enjoy :)</para>
</section>
- <xi:include href="Section-HelloWorldExample/Section-HelloWorldExample.xml" />
- <xi:include href="Section-StateExample/Section-StateExample.xml" />
- <xi:include href="Section-FibonacciExample/Section-FibonacciExample.xml" />
- <xi:include href="Section-BankingExample/Section-BankingExample.xml" />
+ <xi:include href="Section-HelloWorldExample.xml" />
+ <xi:include href="Section-StateExample.xml" />
+ <xi:include href="Section-FibonacciExample.xml" />
+ <xi:include href="Section-BankingExample.xml" />
- <section>
- <title>Golfing Example</title>
- <screen><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> golf.drl
-<emphasis role="bold">Objective:</emphasis> Configuration example that finds the solution from a large number of available cross products
-</screen>
+ <section >
- <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>
-
- <screen>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]) );
- }
- }
-} </screen>
-
- <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>Conclusion</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>
- <title>Trouble Ticket</title>
-
- <para>The trouble ticket example shows how to use the duration attribute for temporal rules, and also includes an alternative version using a dsl.</para>
-
- <programlisting><emphasis role="bold">Name:</emphasis> TroubleTicket
-<emphasis role="bold">Main class:</emphasis> org.drools.examples.TroubleTicketExample, org.drools.examples.TroubleTicketExampleWithDSL
-<emphasis role="bold">Type:</emphasis> java application
-<emphasis role="bold">Rules file:</emphasis> TroubleTicket.drl, TroubleTicketWithDSL.dslr
-<emphasis role="bold">Objective:</emphasis> Show temporal rules in action
-</programlisting>
-
- <para>The trouble ticket example is based around the idea of raising a "ticket" (ie an issue) with a vendor (these are the vendors rules). Each customer has a subscription class assigned to it (eg Gold, Silver etc) and their class determines how the ticket is treated with respect to time, and escalating the issue. The normal drl version will be discussed here, but logically the DSL version is the same (it just uses a DSL defined language instead of the normal DRL).</para>
-
- <para>We have 2 types of facts, Customer and Ticket. A Ticket belongs to one and only one customer. A Customer has a name and a "subscription" type (Gold, Silver or Platinum). A ticket also has a "status" - which determines (obviously) what state it is in. The state may be set externally, or by the rules engine (eg it starts out "New", and then the system user determines that it is "Done" at some later point). The rules exist to ensure that the tickets are escalated appropriately based on the customer subscription class.</para>
-
- <para>Customers can choose Silver, Gold, or Platinum (in order of increasing responsiveness). Platinum subscriptions also come with a set of steak knives, and a personal butler to lodge the ticket for you (but obviously it costs more).</para>
- </section>
-
- <section>
- <title>Executing the Example</title>
-
- <para>The example creates 4 customers, with their name and subscription class, it then creates 4 tickets for each of the customers, note that the ticket takes the customer in the constructor (that sets up the object relationship. The tickets and the customers are then inserted. Notice that we keep a fact handle - which we will use to notify the engine that that specific ticket changed later on. The last line has the all important fireAllRules(), which tells the engine to take action on the data it has.</para>
-
- <example>
- <title>Trouble Ticket Example : Creating and Inserting Facts</title>
-
- <programlisting>Customer a = new Customer( "A",
- "Gold" );
-Customer b = new Customer( "B",
- "Platinum" );
-Customer c = new Customer( "C",
- "Silver" );
-Customer d = new Customer( "D",
- "Silver" );
-
-Ticket t1 = new Ticket( a );
-Ticket t2 = new Ticket( b );
-Ticket t3 = new Ticket( c );
-Ticket t4 = new Ticket( d );
-
-session.insert( a );
-session.insert( b );
-session.insert( c );
-session.insert( d );
-
-session.insert( t1 );
-session.insert( t2 );
-FactHandle ft3 = session.insert( t3 );
-session.insert( t4 );
-
-session.fireAllRules();</programlisting>
- </example>
-
- <para>We have the "New Ticket" rule which has the highest priority (salience of 10 - the default is zero), The purpose of this is simply to log the fact that a new ticket has arrived in the system:</para>
-
- <programlisting>rule "New Ticket"
- salience 10
- when
- customer : Customer( )
- ticket : Ticket( customer == customer, status == "New" )
- then
- System.out.println( "New : " + ticket );
-end </programlisting>
-
- <para>Note that we are "joining" the ticket fact with the customer fact. It's not really needed in this case, as we don't do anything (yet) with the customer fact. If you look in the TroubleTicketExample.java, you will also see that the facts are being inserted into the engine - note that we assert BOTH Customer and Ticket object (even though the ticket belongs to a customer - this allows the engine to join the objects together how it wants - this is what is meant by "relational" programming - we let the rule engine define what the relationships are. For instance, although the code is structured so that a ticket belongs to a customer, we may be interested in looking at tickets from different customers of the same type in the future).</para>
-
- <para>If we run the rules, we should expect that the "New Ticket" rule will be activated for all tickets, so looking at the audit log view (by opening the file which was saved automatically when the rules were run):</para>
-
- <figure>
- <title>Audit view</title>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="tt_audit_view.png" />
- </imageobject>
- </mediaobject>
- </figure>
-
- <para>Referring to the above audit log, we can see each customer asserted, but nothing happens. As soon as the first ticket gets asserted, it joins it with the customer, and creates some activations: one is the "new ticket" rule, the other is for the appropriate priority (which we will show below). Note that items in the above view do not mean the rule fired at that point.</para>
-
- <para>Also, don't forget to use "fireAllRules()" - a common mistake ! (In this case we are using a statefull session, so this is necessary).</para>
-
- <para>If we run the rules, we should expect that the "New Ticket" rule will be activated for all tickets, so looking at the audit log view (by opening the file which was saved automatically when the rules were run):</para>
-
- <figure>
- <title>Audit view</title>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="tt_audit_view.png" />
- </imageobject>
- </mediaobject>
- </figure>
-
- <para>Referring to the above audit log, we can see each customer asserted, but nothing happens. As soon as the first ticket gets asserted, it joins it with the customer, and creates some activations: one is the "new ticket" rule, the other is for the appropriate priority (which we will show below). Note that items in the above view do not mean the rule fired at that point.</para>
-
- </section>
-
- <section>
- <title>Platinum gets the best service</title>
-
- <para>All the wonderful platinum customers have to get great service, so first thing to note is that as soon as a ticket arrives, we escalate if it is for a platinum customer:</para>
-
- <programlisting>rule "Platinum Priority"
- when
- customer : Customer( subscription == "Platinum" )
- ticket : Ticket( customer == customer, status == "New" )
- then;
- ticket.setStatus( "Escalate" );
- update( ticket );
-end </programlisting>
-
- <para>Here we are joining Ticket to customer again (customer == customer), but we are also checking that the customer is "Platinum". When this is the case, we set the ticket status to "Escalate" and call update (which tells the engine that the ticket has changed).</para>
-
- </section>
-
- <section>
- <title>Silver and Gold</title>
-
- <para>For silver and gold class, its a similar story to platinum:</para>
-
- <programlisting>rule "Silver Priority"
- duration 3000
- when
- customer : Customer( subscription == "Silver" )
- ticket : Ticket( customer == customer, status == "New" )
- then
- ticket.setStatus( "Escalate" );
- update( ticket );
-end
-
-rule "Gold Priority"
- duration 1000
- when
- customer : Customer( subscription == "Gold" )
- ticket : Ticket( customer == customer, status == "New" )
- then
- ticket.setStatus( "Escalate" );
- update( ticket );
-end </programlisting>
-
- <para>In this case, note the use of "duration XXX" - XXX is the number of milliseconds to wait to check that this rule holds true. Should it do so, after XXX milliseconds, then the action takes effect. So in the above case, after 3 seconds the "Silver" priority kicks in, but after 1 second "Gold" does. In both cases the tickets are escalated (just like with platinum. This is what we mean by temporal rules (rules that take effect over time).</para>
-
- </section>
-
- <section>
- <title>Escalating</title>
-
- <para>The actual escalation of a ticket happens in a rule:</para>
-
- <programlisting>rule "Escalate"
- when
- customer : Customer( )
- ticket : Ticket( customer == customer, status == "Escalate" )
- then
- sendEscalationEmail( customer, ticket );
-end </programlisting>
-
- <para>In this case, the action is to call a function which sends an email (the function is defined down the bottom of the drl file). This rule reacts to the rules which update the ticket and set its status to escalate.</para>
-
- <para>In the code that launches the example, we have a "sleep" to make sure all this happens (and print out the results). Note also that after the rules are fired, we modify the status of the Customer "C" to "Done" - and then tell the engine. This causes it to evaluate and fire the rule that looks for "tickets" that are "Done" (in which is just logs a message).</para>
-
- </section>
-
- <section>
- <title>Running it</title>
-
- <para>Running the example (by launching the TroubleTicket.java class as an application) should yield the output:</para>
-
- <programlisting>New : [Ticket [Customer D : Silver] : New]
-New : [Ticket [Customer C : Silver] : New]
-New : [Ticket [Customer B : Platinum] : New]
-New : [Ticket [Customer A : Gold] : New]
-Email : [Ticket [Customer B : Platinum] : Escalate]
-[[ Sleeping 5 seconds ]]
-Email : [Ticket [Customer A : Gold] : Escalate]
-Done : [Ticket [Customer C : Silver] : Done]
-Email : [Ticket [Customer D : Silver] : Escalate]
-[[ awake ]] </programlisting>
-
- <figure>
- <title>Audit log</title>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="tt_audit_firing.png" />
- </imageobject>
- </mediaobject>
- </figure>
-
- <para>Referring to the above audit log, we can see the events as they happen. Once the rules start firing, the first items are the "Activation Executed" for the new tickets, as expected (they do nothing, just log the fact). Note the "Activation executed" item for the platinum ticket - that is the next one to go (remember it has the default salience, so it happens after the "New ticket" rule, but otherwise it is immediate - there is no "duration" delay for it). The platinum activation results in a Object modification (which is the escalation) - this in turn creates an activation record for the "escalate ticket" rule - which is what we wanted. Straight after that it executes the action to escalate the ticket.</para>
-
- <para>The next event to occur is due to the:</para>
- <programlisting>t3.setStatus( "Done" );
-
-session.update( ft3,
- t3 );
-</programlisting>
- <para>in the code (outside of rules) - this simulates a customer service officer maarking a ticket as done (and of course, uses the fact handle we kept from before). This results in a cancelled activation (as we no longer have a New Silvert customer ticket - it is done) and a new activation to log the fact it was done.</para>
-
- <para>In all the excitement, in parallel the engine has been watching the time pass, and it happens that the Gold tickets start to escalate, and then silver (as expected).</para>
-
- </section>
-
- </section>
-
- <!-- Trouble Ticket example -->
-
- <section>
<title>Pricing Rule Decision Table Example</title>
<para>The Pricing Rule decision table demonstrates the use of a decision table in a spreadsheet (XLS format) in calculating the retail cost of an insurance policy. The purpose of the set of rules provided is to calculate a base price, and an additional discount for a car driver applying for a specific policy. The drivers age, history and the policy type all contribute to what the basic premium is, and an additional chunk of rules deals with refining this with a subtractive percentage discount.</para>
@@ -397,7 +56,7 @@
<mediaobject>
<imageobject>
- <imagedata fileref="DT_Config.png" />
+ <imagedata fileref="TroubleTicket/DT_Config.png" />
</imageobject>
</mediaobject>
</figure>
@@ -413,7 +72,7 @@
<mediaobject>
<imageobject>
- <imagedata fileref="DT_Table1.png" />
+ <imagedata fileref="TroubleTicket/DT_Table1.png" />
</imageobject>
</mediaobject>
</figure>
@@ -425,7 +84,7 @@
<mediaobject>
<imageobject>
- <imagedata fileref="DT_Table2.png" />
+ <imagedata fileref="TroubleTicket/DT_Table2.png" />
</imageobject>
</mediaobject>
</figure>
@@ -434,7 +93,9 @@
<para>It is important to note that decision tables generate rules, this means they aren't simply top down logic, but more a means to capture data that generate rules (this is a subtle difference that confuses some people). The evaluation of the rules is not "top down" necessarily, all the normal indexing and mechanics of the rule engine still apply.</para>
</section>
- </section>
+ </section>
+
+
<section>
<title>Shopping Example</title>
@@ -1054,158 +715,8 @@
<!---<para>Todo : Add Audit and Agenda Views for this sample.</para>-->
</section>
- <section>
- <title>Honest Politician Example</title>
+ <xi:include href="Section-HonestPolitician.xml" />
- <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>
-
- <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><example>
- <title>Politician Class</title>
-
- <programlisting>public class Politician {
- private String name;
- private boolean honest;
- ...
-}</programlisting>
- </example><example>
- <title>Honest Politician Example 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);
-
-session.insert( blair );
-session.insert( bush );
-session.insert( chirac );
-session.insert( schroder );
-
-session.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>
-
- <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>
- <title>Honest Politician Example : Rule "We have an honest
- politician"</title>
-
- <programlisting>rule "We have an honest Politician"
- salience 10
- when
- exists( Politician( honest == true ) )
- then
- insertLogical( new Hope() );
-end</programlisting>
- </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>
-
- <example>
- <title>Honest Politician Example : Rule "Hope Lives"</title>
-
- <programlisting>rule "Hope Lives"
- salience 10
- 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 hvae an honest Politician" is no longer true and
- the object it logical inserts "new Hope()" is automatically
- retracted.</para>
-
- <example>
- <title>Honest Politician Example : Rule "Corrupt the Honest"</title>
-
- <programlisting>rule "Corrupt the Honest"
- when
- politician : Politician( honest == true )
- exists( Hope() )
- then
- System.out.println( "I'm an evil corporation and I have corrupted " + politician.getName() );
- modify ( politician ) { honest = false };
-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>
-
- <example>
- <title>Honest Politician Example : Rule "Hope is Dead"</title>
-
- <programlisting>rule "Hope is Dead"
- when
- not( Hope() )
- then
- System.out.println( "We are all Doomed!!! Democracy is Dead" );
-end</programlisting>
- </example>
-
- <para>lets take a look the audit trail for this application:</para>
-
- <figure>
- <title>Honest Politician Example Audit View</title>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="honest_politician_audit.png" />
- </imageobject>
- </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
- dead" activates and fires printing "We are all Doomed!!! Democracy is
- Dead".</para>
-
- </section>
-
<section>
<title>Sudoku Example</title>
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample.xml (from rev 20478, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/FibonacciExample/Section-FibonacciExample.xml)
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample.xml (rev 0)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample.xml 2008-06-14 13:00:09 UTC (rev 20479)
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <section xml:base="../">
+ <title>Fibonacci Example</title>
+
+ <screen><emphasis role="bold">Name:</emphasis> Fibonacci
+<emphasis role="bold">Main class:</emphasis> org.drools.examples.FibonacciExample
+<emphasis role="bold">Type:</emphasis> java application
+<emphasis role="bold">Rules file:</emphasis> Fibonacci.drl
+<emphasis role="bold">Objective:</emphasis> Demonsrates Recursion, 'not' CEs and Cross Product Matching</screen>
+
+ <para>The Fibonacci Numbers, <ulink url="http://en.wikipedia.org/wiki/Fibonacci_number">http://en.wikipedia.org/wiki/Fibonacci_number</ulink>, invented by Leonardo of Pisa, <ulink url="http://en.wikipedia.org/wiki/Fibonacci">http://en.wikipedia.org/wiki/Fibonacci</ulink>, are obtained by starting with 0 and 1, and then produce the next Fibonacci number by adding the two previous Fibonacci numbers. The first Fibonacci numbers for n = 0, 1,... are: * 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946... The Fibonacci Example demonstrates recursion and conflict resolution with Salience values.</para>
+
+ <para>A single fact Class is used in this example, Fibonacci. It has two fields, sequence and value. The sequence field is used to indicate the position of the object in the Fibonacci number sequence and the value field shows the value of that Fibonacci object for that sequence position.</para>
+
+ <example>
+ <title>Fibonacci Class</title>
+
+ <programlisting>public static class Fibonacci {
+ private int sequence;
+ private long value;
+
+ ... setters and getters go here...
+}</programlisting>
+ </example>
+
+ <para>Execute the example:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Open the class <classname>org.drools.examples.FibonacciExample</classname> in your Eclipse IDE</para>
+ </listitem>
+
+ <listitem>
+ <para>Right-click the class an select "Run as..." -> "Java application"</para>
+ </listitem>
+ </orderedlist>
+
+ <para>And Eclipse shows the following output in its console, "...snip..." shows repeated bits removed to save space:</para>
+
+ <example>
+ <title>Fibonacci Example Console Output</title>
+
+ <programlisting>recurse for 50
+recurse for 49
+recurse for 48
+recurse for 47
+...snip...
+recurse for 5
+recurse for 4
+recurse for 3
+recurse for 2
+1 == 1
+2 == 1
+3 == 2
+4 == 3
+5 == 5
+6 == 8
+...snip...
+47 == 2971215073
+48 == 4807526976
+49 == 7778742049
+50 == 12586269025
+</programlisting>
+ </example>
+
+ <para>To kick this off from java we only insert a single Fibonacci object, with a sequence of 50, a recurse rule is then used to insert the other 49 Fibonacci objects. This example doesn't use PropertyChangeSupport and uses the MVEL dialect, this means we can use the <emphasis role="bold">modify</emphasis> keyword, which allows a block setter action which also notifies the engine of changes.</para>
+
+ <example>
+ <title>Fibonacci Example Execution</title>
+
+ <programlisting>session.insert( new Fibonacci( 50 ) );
+session.fireAllRules();</programlisting>
+ </example>
+
+ <para>The recurse rule is very simple, it matches each asserted Fibonacci object with a value of -1, it then creates and asserts a new Fibonacci object with a sequence of one less than the currently matched object. Each time a Fibonacci object is added, as long as one with a "sequence == 1" does not exist, the rule re-matches again and fires; causing the recursion. The 'not' conditional element is used to stop the rule matching once we have all 50 Fibonacci objects in memory. The rule also has a salience value, this is because we need to have all 50 Fibonacci objects asserted before we execute the Bootstrap rule.</para>
+
+ <example>
+ <title>Fibonacci Example : Rule "Recurse"</title>
+
+ <programlisting>rule Recurse
+ salience 10
+ when
+ f : Fibonacci ( value == -1 )
+ not ( Fibonacci ( sequence == 1 ) )
+ then
+ insert( new Fibonacci( f.sequence - 1 ) );
+ System.out.println( "recurse for " + f.sequence );
+end</programlisting>
+ </example>
+
+ <para>The audit view shows the original assertion of the Fibonacci object with a sequence of 50, this was done from Java land. From there the audit view shows the continual recursion of the rule, each asserted Fibonacci causes the "Recurse" rule to become activate again, which then fires.</para>
+
+ <figure>
+ <title>Fibonacci Example "Recurse" Audit View 1</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="FibonacciExample/fibonacci1.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>When a Fibonacci with a sequence of 2 is asserted the "Bootstrap" rule is matched and activated along with the "Recurse" rule.</para>
+
+ <example>
+ <title>Fibonacci Example : Rule "Bootstrap"</title>
+
+ <programlisting>rule Bootstrap
+ when
+ f : Fibonacci( sequence == 1 || == 2, value == -1 ) // this is a multi-restriction || on a single field
+ then
+ modify ( f ){ value = 1 };
+ System.out.println( f.sequence + " == " + f.value );
+end</programlisting>
+ </example>
+
+ <para>At this point the Agenda looks like the figure shown below. However the "Bootstrap" rule does not fire as the "Recurse" rule has a higher salience.</para>
+
+ <figure>
+ <title>Fibonacci Example "Recurse" Agenda View 1</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="FibonacciExample/fibonacci_agenda1.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>When a Fibonacci with a sequence of 1 is asserted the "Bootstrap" rule is matched again, causing two activations for this rule; note that the "Recurse" rule does not match and activate because the 'not conditional element stops the rule matching when a Fibonacci with a sequence of 1 exists.</para>
+
+ <figure>
+ <title>Fibonacci Example "Recurse" Agenda View 2</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="FibonacciExample/fibonacci_agenda2.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Once we have two Fibonacci objects both with values not equal to -1 the "calculate" rule is able to match; remember it was the "Bootstrap" rule that set the Fibonacci's with sequences 1 and 2 to values of 1. At this point we have 50 Fibonacci objects in the Working Memory and we some how need to select the correct ones to calculate each of their values in turn. With three Fibonacci patterns in a rule with no field constriants to correctly constrain the available cross products we have 50x50x50 possible permutations, thats 125K possible rule firings. The "Calculate" rule uses the field constraints to correctly constraint the thee Fibonacci patterns and in the correct order; this technique is called "cross product matching". The first pattern finds any Fibonacci with a value != -1 and binds both the pattern and the field. The second Fibonacci does too but it adds an additional field constraint to make sure that its sequence is one greater than the Fibonacci bound to f!
1. When this rule first fires we know that only sequences 1 and 2 have values of 1 and the two constraints ensure that f1 references sequence 1 and f2 references sequence2. The final pattern finds the Fibonacci of a value == -1 with a sequence one greater than f2. At this point we have three Fibonacci objects correctly selected from the available cross products and we can do the maths calculating the value for Fibonacci sequence = 3.</para>
+
+ <example>
+ <title>Fibonacci Example : Rule "Calculate"</title>
+
+ <programlisting>rule Calculate
+ when
+ f1 : Fibonacci( s1 : sequence, value != -1 ) // here we bind sequence
+ f2 : Fibonacci( sequence == (s1 + 1 ), value != -1 ) // here we don't, just to demonstrate the different way bindings can be used
+ f3 : Fibonacci( s3 : sequence == (f2.sequence + 1 ), value == -1 )
+ then
+ modify ( f3 ) { value = f1.value + f2.value };
+ System.out.println( s3 + " == " + f3.value ); // see how you can access pattern and field bindings
+end
+</programlisting>
+ </example>
+
+ <para>The MVEL modify keyword updated the value of the Fibonacci object bound to f3, this means we have a new Fibonacci object with a value != -1, this allows the "Calculate" rule to rematch and calculate the next Fibonacci number. The Audit view below shows the how the firing of the last "Bootstrap" modifies the Fibonacci object enabling the "Calculate" rule to match, which then modifies another Fibonacci object allowing the "Calculate" rule to rematch. This continues till the value is set for all Fibonacci objects.</para>
+
+ <figure>
+ <title>Fibonacci Example "Bootstrap" Audit View 1</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="FibonacciExample/fibonacci4.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+ </section>
\ No newline at end of file
Added: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-GolfingExample.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-GolfingExample.xml (rev 0)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-GolfingExample.xml 2008-06-14 13:00:09 UTC (rev 20479)
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <section xml:base="../">
+ <title>Golfing Example</title>
+
+ <screen><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> golf.drl
+<emphasis role="bold">Objective:</emphasis> Configuration example that finds the solution from a large number of available cross products
+</screen>
+
+ <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 Freds 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 isnt in position one or four, and he isnt 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>
+
+ <screen>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]) );
+ }
+ }
+} </screen>
+
+ <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>Conclusion</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>
+ <title>Trouble Ticket</title>
+
+ <para>The trouble ticket example shows how to use the duration attribute for temporal rules, and also includes an alternative version using a dsl.</para>
+
+ <programlisting><emphasis role="bold">Name:</emphasis> TroubleTicket
+<emphasis role="bold">Main class:</emphasis> org.drools.examples.TroubleTicketExample, org.drools.examples.TroubleTicketExampleWithDSL
+<emphasis role="bold">Type:</emphasis> java application
+<emphasis role="bold">Rules file:</emphasis> TroubleTicket.drl, TroubleTicketWithDSL.dslr
+<emphasis role="bold">Objective:</emphasis> Show temporal rules in action
+</programlisting>
+
+ <para>The trouble ticket example is based around the idea of raising a "ticket" (ie an issue) with a vendor (these are the vendors rules). Each customer has a subscription class assigned to it (eg Gold, Silver etc) and their class determines how the ticket is treated with respect to time, and escalating the issue. The normal drl version will be discussed here, but logically the DSL version is the same (it just uses a DSL defined language instead of the normal DRL).</para>
+
+ <para>We have 2 types of facts, Customer and Ticket. A Ticket belongs to one and only one customer. A Customer has a name and a "subscription" type (Gold, Silver or Platinum). A ticket also has a "status" - which determines (obviously) what state it is in. The state may be set externally, or by the rules engine (eg it starts out "New", and then the system user determines that it is "Done" at some later point). The rules exist to ensure that the tickets are escalated appropriately based on the customer subscription class.</para>
+
+ <para>Customers can choose Silver, Gold, or Platinum (in order of increasing responsiveness). Platinum subscriptions also come with a set of steak knives, and a personal butler to lodge the ticket for you (but obviously it costs more).</para>
+ </section>
\ No newline at end of file
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HelloWorldExample.xml (from rev 20478, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/HelloWorldExample/Section-HelloWorldExample.xml)
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HelloWorldExample.xml (rev 0)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HelloWorldExample.xml 2008-06-14 13:00:09 UTC (rev 20479)
@@ -0,0 +1,285 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<section xml:base="../">
+ <title>Hello World</title>
+
+ <screen><emphasis role="bold">Name:</emphasis> Hello World
+<emphasis role="bold">Main class:</emphasis> org.drools.examples.HelloWorldExample
+<emphasis role="bold">Type:</emphasis> java application
+<emphasis role="bold">Rules file:</emphasis> HelloWorld.drl
+<emphasis role="bold">Objective:</emphasis> demonstrate basic rules in use</screen>
+
+ <para>The "Hello World" example shows a simple example of rules usage, and
+ both the MVEL and Java dialects.</para>
+
+ <para>In this example it will be shown how to build rulebases and sessions
+ and how to add audit logging and debug outputs, this information is ommitted
+ from other examples as it's all very similar. PackageBuilder is used to turn
+ a drl source file into Package objects which the RuleBase can consume,
+ addPackageFromDrl takes a Reader interface as the parameter. Reader can be
+ used to retrieve a source drl file from various locations, in this case the
+ drl file is being retrieved from the classpath as an InputStream which we
+ turn into a Reader by wrapping it with InputStreamReader; but it could come
+ the disk or a url. The use of the Reader interface means that Drools does
+ not have to care. In this case we only add a single drl source file, but
+ multiple drl files can be added and all are merged into a single Package.
+ All drl files added to the PackageBuilder must declare themselves in the
+ same package namespace, if you wish to build a Package in a different
+ namespace a new instance of PackageBuilder must be created; multiple
+ packages of differerent namespaces can be added to the same RuleBase. When
+ all the drl files have been added we should check the builder for errors;
+ while the RuleBase will validate the packge it will only have access to the
+ error information as a String, so if you wish to debug the error information
+ you should do it on the builder instance. Once we know the builder is error
+ free get the Package, instantiate a RuleBase from the RuleBaseFactory and
+ add the package.</para>
+
+ <example>
+ <title>HelloWorld example: Creating the RuleBase and Session</title>
+
+ <programlisting>//read in the source
+Reader source = new InputStreamReader( HelloWorldExample.class.getResourceAsStream( "HelloWorld.drl" ) );
+
+PackageBuilder builder = new PackageBuilder();
+
+//this will parse and compile in one step
+builder.addPackageFromDrl( source );
+
+// Check the builder for errors
+if ( builder.hasErrors() ) {
+ System.out.println( builder.getErrors().toString() );
+ throw new RuntimeException( "Unable to compile \"HelloWorld.drl\".");
+}
+
+//get the compiled package (which is serializable)
+Package pkg = builder.getPackage();
+
+//add the package to a rulebase (deploy the rule package).
+RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+ruleBase.addPackage( pkg );
+
+StatefulSession session = ruleBase.newStatefulSession();</programlisting>
+ </example>
+
+ <para>Drools has an event model that exposes much of what's happening
+ internally, two default debug listeners are supplied
+ DebugAgendaEventListener and DebugWorkingMemoryEventListener which print out
+ debug event information to the err console, adding listeners to a session is
+ trivial and shown below. The WorkingMemoryFileLogger provides execution
+ auditing which can be viewed in a graphical viewer; it's actually a
+ specialised implementation built on the agenda and working memory listeners,
+ when the engine has finished executing logger.writeToDisk() must be
+ called.</para>
+
+ <para>Most of the examples use the Audit logging features of Drools to
+ record execution flow for later inspection.</para>
+
+ <example>
+ <title>HelloWorld example: Event logging and Auditing</title>
+
+ <programlisting>// setup the debug listeners
+session.addEventListener( new DebugAgendaEventListener() );
+session.addEventListener( new DebugWorkingMemoryEventListener() );
+
+// setup the audit logging
+WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger( session );
+logger.setFileName( "log/helloworld" ); </programlisting>
+ </example>
+
+ <para>The single class used in this example is very simple, it has two
+ fields: the message, which is a String and the status which can be either
+ the int HELLO or the int GOODBYE.</para>
+
+ <example>
+ <title>HelloWorld example: Message Class</title>
+
+ <programlisting>public static class Message {
+ public static final int HELLO = 0;
+ public static final int GOODBYE = 1;
+
+ private String message;
+ private int status;
+ ...
+}</programlisting>
+ </example>
+
+ <para>A single Message object is created with the message "Hello World" and
+ status HELLO and then inserted into the engine, at which point
+ fireAllRules() is executed. Remember all the network evaluation is done
+ during the insert time, by the time the program execution reaches the
+ fireAllRules() method it already knows which rules are fully matches and
+ able to fire.</para>
+
+ <example>
+ <title>HelloWorld example: Execution</title>
+
+ <programlisting>Message message = new Message();
+message.setMessage( "Hello World" );
+message.setStatus( Message.HELLO );
+session.insert( message );
+
+session.fireAllRules();
+
+logger.writeToDisk();
+
+session.dispose(); </programlisting>
+ </example>
+
+ <para>To execute the example from Java.</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Open the class org.drools.examples.FibonacciExample in your
+ Eclipse IDE</para>
+ </listitem>
+
+ <listitem>
+ <para>Right-click the class an select "Run as..." -> "Java
+ application"</para>
+ </listitem>
+ </orderedlist>
+
+ <para>If we put a breakpoint on the fireAllRules() method and select the
+ session variable we can see that the "Hello World" view is already activated
+ and on the Agenda, showing that all the pattern matching work was already
+ done during the insert.</para>
+
+ <figure>
+ <title>Hello World : fireAllRules Agenda View</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="HelloWorldExample/helloworld_agenda1.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>The may application print outs go to to System.out while the debug
+ listener print outs go to System.err.</para>
+
+ <example>
+ <title>HelloWorld example: Console.out</title>
+
+ <programlisting>Hello World
+Goodbye cruel world</programlisting>
+ </example>
+
+ <example>
+ <title>HelloWorld example: Console.err</title>
+
+ <programlisting>==>[ActivationCreated(0): rule=Hello World;
+ tuple=[fid:1:1:org.drools.examples.HelloWorldExample$Message at 17cec96]]
+[ObjectInserted: handle=[fid:1:1:org.drools.examples.HelloWorldExample$Message at 17cec96];
+ object=org.drools.examples.HelloWorldExample$Message at 17cec96]
+[BeforeActivationFired: rule=Hello World;
+ tuple=[fid:1:1:org.drools.examples.HelloWorldExample$Message at 17cec96]]
+==>[ActivationCreated(4): rule=Good Bye;
+ tuple=[fid:1:2:org.drools.examples.HelloWorldExample$Message at 17cec96]]
+[ObjectUpdated: handle=[fid:1:2:org.drools.examples.HelloWorldExample$Message at 17cec96];
+ old_object=org.drools.examples.HelloWorldExample$Message at 17cec96;
+ new_object=org.drools.examples.HelloWorldExample$Message at 17cec96]
+[AfterActivationFired(0): rule=Hello World]
+[BeforeActivationFired: rule=Good Bye;
+ tuple=[fid:1:2:org.drools.examples.HelloWorldExample$Message at 17cec96]]
+[AfterActivationFired(4): rule=Good Bye] </programlisting>
+ </example>
+
+ <para>The <emphasis role="bold">LHS (when)</emphasis> section of the rule
+ states that it will be activated for each <emphasis>Message</emphasis>
+ object inserted into the working memory whose <emphasis>status</emphasis> is
+ <emphasis>Message.HELLO</emphasis>. Besides that, two variable binds are
+ created: "<emphasis>message</emphasis>" variable is bound to the
+ <emphasis>message</emphasis> attribute and "<emphasis>m</emphasis>" variable
+ is bound to the <emphasis>object matched pattern</emphasis> itself.</para>
+
+ <para>The <emphasis role="bold">RHS (consequence, then)</emphasis> section
+ of the rule is written using the MVEL expression language, as declared by
+ the rule's attribute <emphasis>dialect</emphasis>. After printing the
+ content of the <emphasis>message</emphasis> bound variable to the default
+ console, the rule changes the values of the <emphasis>message</emphasis> and
+ <emphasis>status</emphasis> attributes of the <emphasis>m</emphasis> bound
+ variable; using MVEL's 'modify' keyword which allows you to apply a block of
+ setters in one statement, with the engine being automatically notified of
+ the changes at the end of the block.</para>
+
+ <example>
+ <title>HelloWorld example: rule "Hello World"</title>
+
+ <programlisting>rule "Hello World"
+ dialect "mvel"
+ when
+ m : Message( status == Message.HELLO, message : message )
+ then
+ System.out.println( message );
+ modify ( m ) { message = "Goodbyte cruel world",
+ status = Message.GOODBYE };
+end</programlisting>
+ </example>
+
+ <para>We can add a break point into the DRL for when modify is called during
+ the execution of the "Hello World" consequence and inspect the Agenda view
+ again. Notice this time we "Debug As" a "Drools application" and not a "Java
+ application".</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Open the class org.drools.examples.FibonacciExample in your
+ Eclipse IDE</para>
+ </listitem>
+
+ <listitem>
+ <para>Right-click the class an select "Debug as..." -> "Drools
+ application"</para>
+ </listitem>
+ </orderedlist>
+
+ <para>Now we can see that the other rule "Good Bye" which uses the java
+ dialect is activated and placed on the agenda.</para>
+
+ <figure>
+ <title>Hello World : rule "Hello World" Agenda View</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="HelloWorldExample/helloworld_agenda2.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>The "Good Bye" rule is similar to the "Hello World" rule but matches
+ Message objects whose status is Message.GOODBYE instead, printing its
+ message to the default console, it specifies the "java" dialect.</para>
+
+ <example>
+ <title>HelloWorld example: rule "Good Bye"</title>
+
+ <programlisting>rule "Good Bye"
+ dialect "java"
+ when
+ Message( status == Message.GOODBYE, message : message )
+ then
+ System.out.println( message );
+end</programlisting>
+ </example>
+
+ <para>If you remember at the start of this example in the java code we
+ created a WorkingMemoryFileLogger and called logger.writeToDisk() at the
+ end, this created an audit log file that can be shown in the Audit view. We
+ use the audit view in many of the examples to try and understand the example
+ execution flow. In the view below we can see the object is inserted which
+ creates an activation for the "Hello World" rule, the activation is then
+ executed which updated the Message object causing the "Good Bye" rule to
+ activate, the "Good Bye" rule then also executes. When an event in the Audit
+ view is select it highlights the origin event in green, so below the
+ Activation created event is highlighted in greed as the origin of the
+ Activation executed event.</para>
+
+ <figure>
+ <title>Hello World : Audit View</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="HelloWorldExample/helloworld_auditview1.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+</section>
\ No newline at end of file
Added: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HonestPolitician.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HonestPolitician.xml (rev 0)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HonestPolitician.xml 2008-06-14 13:00:09 UTC (rev 20479)
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <section xml:base="../">
+ <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>
+
+ <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><example>
+ <title>Politician Class</title>
+
+ <programlisting>public class Politician {
+ private String name;
+ private boolean honest;
+ ...
+}</programlisting>
+ </example><example>
+ <title>Honest Politician Example 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);
+
+session.insert( blair );
+session.insert( bush );
+session.insert( chirac );
+session.insert( schroder );
+
+session.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>
+
+ <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>
+ <title>Honest Politician Example : Rule "We have an honest
+ politician"</title>
+
+ <programlisting>rule "We have an honest Politician"
+ salience 10
+ when
+ exists( Politician( honest == true ) )
+ then
+ insertLogical( new Hope() );
+end</programlisting>
+ </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>
+
+ <example>
+ <title>Honest Politician Example : Rule "Hope Lives"</title>
+
+ <programlisting>rule "Hope Lives"
+ salience 10
+ 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 hvae an honest Politician" is no longer true and
+ the object it logical inserts "new Hope()" is automatically
+ retracted.</para>
+
+ <example>
+ <title>Honest Politician Example : Rule "Corrupt the Honest"</title>
+
+ <programlisting>rule "Corrupt the Honest"
+ when
+ politician : Politician( honest == true )
+ exists( Hope() )
+ then
+ System.out.println( "I'm an evil corporation and I have corrupted " + politician.getName() );
+ modify ( politician ) { honest = false };
+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>
+
+ <example>
+ <title>Honest Politician Example : Rule "Hope is Dead"</title>
+
+ <programlisting>rule "Hope is Dead"
+ when
+ not( Hope() )
+ then
+ System.out.println( "We are all Doomed!!! Democracy is Dead" );
+end</programlisting>
+ </example>
+
+ <para>lets take a look the audit trail for this application:</para>
+
+ <figure>
+ <title>Honest Politician Example Audit View</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="honest_politician_audit.png" />
+ </imageobject>
+ </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
+ dead" activates and fires printing "We are all Doomed!!! Democracy is
+ Dead".</para>
+
+ </section>
Added: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-StateExample.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-StateExample.xml (rev 0)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-StateExample.xml 2008-06-14 13:00:09 UTC (rev 20479)
@@ -0,0 +1,289 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <section xml:base="../" >
+ <title>State Example</title>
+
+ <para>This example is actually implemented in three different versions to demonstrate different ways of implementing the same basic behavior: rules forward chaining, i.e., the ability the engine has to evaluate, activate and fire rules in sequence, based on changes on the facts in the working memory.</para>
+
+ <section>
+ <title>Understanding the State Example</title>
+
+ <screen><emphasis role="bold">Name:</emphasis> State Example
+<emphasis role="bold">Main class:</emphasis> org.drools.examples.StateExampleUsingSalience
+<emphasis role="bold">Type:</emphasis> java application
+<emphasis role="bold">Rules file:</emphasis> StateExampleUsingSalience.drl
+<emphasis role="bold">Objective:</emphasis> Demonstrates basic rule use and Conflict Resolution for rule firing priority.</screen>
+
+ <para>Each State class has fields for its name and its current state (see org.drools.examples.State class). The two possible states for each objects are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>NOTRUN</para>
+ </listitem>
+
+ <listitem>
+ <para>FINISHED</para>
+ </listitem>
+ </itemizedlist>
+
+ <example>
+ <title>State Class</title>
+
+ <programlisting>public class State {
+ public static final int NOTRUN = 0;
+ public static final int FINISHED = 1;
+
+ private final PropertyChangeSupport changes = new PropertyChangeSupport( this );
+
+ private String name;
+ private int state;
+
+ ... setters and getters go here...
+}</programlisting>
+ </example>
+
+ <para>Ignore the PropertyChangeSupport for now, that will be explained later. In the example we create four State objects with names: A, B, C and D. Initially all are set to state NOTRUN, which is default for the used constructor. Each instance is asserted in turn into the session and then fireAllRules() is called.</para>
+
+ <example>
+ <title>Salience State Example Execution</title>
+
+ <programlisting>State a = new State( "A" );
+State b = new State( "B" );
+State c = new State( "C" );
+final State d = new State( "D" );
+
+// By setting dynamic to TRUE, Drools will use JavaBean
+// PropertyChangeListeners so you don't have to call update().
+boolean dynamic = true;
+
+session.insert( a,
+ dynamic );
+session.insert( b,
+ dynamic );
+session.insert( c,
+ dynamic );
+session.insert( d,
+ dynamic );
+
+session.fireAllRules();
+session.dispose(); // Stateful rule session must always be disposed when finished</programlisting>
+ </example>
+
+ <para>To execute the application:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Open the class org.drools.examples.StateExampleUsingSalience in your Eclipse IDE</para>
+ </listitem>
+
+ <listitem>
+ <para>Right-click the class an select "Run as..." -> "Java application"</para>
+ </listitem>
+ </orderedlist>
+
+ <para>And you will see the following output in the Eclipse console output:</para>
+
+ <example>
+ <title>Salience State Example Console Output</title>
+
+ <programlisting>A finished
+B finished
+C finished
+D finished
+</programlisting>
+ </example>
+
+ <para>There are four rules in total, first a Bootstrap rule fires setting A to state FINISHED which then causes B to change to state FINISHED. C and D are both dependent on B - causing a conflict which is resolved by setting salience values. First lets look at how this was executed</para>
+
+ <para>The best way to understand what is happening is to use the "Audit Log" feature to graphically see the results of each operation. The Audit log was generated when the example was previously run. To view the Audit log in Eclipse:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>If the "Audit View" is not visible, click on: "Window"->"Show View"->"Other..."->"Drools"->"Audit View"</para>
+ </listitem>
+
+ <listitem>
+ <para>In the "Audit View" click in the "Open Log" button and select the file "<drools-examples-drl-dir>/log/state.log"</para>
+ </listitem>
+ </orderedlist>
+
+ <para>After that, the "Audit view" will look like the following screenshot.</para>
+
+ <figure>
+ <title>Salience State Example Audit View</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="StateExample/state_example_audit1.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Reading the log in the "Audit View", top to down, we see every action and the corresponding changes in the working memory. This way we see that the assertion of the State "A" object with the "NOTRUN" state activates the "Bootstrap" rule, while the assertions of the other state objects have no immediate effect.</para>
+
+ <example>
+ <title>Salience State Example: Rule "Bootstrap"</title>
+
+ <programlisting>rule Bootstrap
+ when
+ a : State(name == "A", state == State.NOTRUN )
+ then
+ System.out.println(a.getName() + " finished" );
+ a.setState( State.FINISHED );
+end</programlisting>
+ </example>
+
+ <para>The execution of "Bootstrap" rule changes the state of "A" to "FINISHED", that in turn activates the "A to B" rule.</para>
+
+ <example>
+ <title>Salience State Example: Rule "A to B"</title>
+
+ <programlisting>rule "A to B"
+ when
+ State(name == "A", state == State.FINISHED )
+ b : State(name == "B", state == State.NOTRUN )
+ then
+ System.out.println(b.getName() + " finished" );
+ b.setState( State.FINISHED );
+end
+</programlisting>
+ </example>
+
+ <para>The execution of "A to B" rule changes the state of "B" to "FINISHED", which activates both rules "B to C" and "B to D", placing both Activations onto the Agenda. In this moment the two rules may fire and are said to be in conflict. The conflict resolution strategy allows the engine's Agenda to decide which rule to fire. As the "B to C" rule has a <emphasis role="bold">higher salience value</emphasis> (10 versus the default salience value of 0), it fires first, modifying the "C" object to state "FINISHED". The Audit view above shows the modification of the State object in the rule "A to B" which results in two highlighted activations being in conflict. The Agenda view can also be used to investigate the state of the Agenda, debug points can be placed in the rules themselves and the Agenda view opened; the screen shot below shows the break point in the rule "A to B" and the state of the Agenda with the two conflicting rules.</para>
+
+ <figure>
+ <title>State Example Agenda View</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="StateExample/state_example_agenda1.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <example>
+ <title>Salience State Example: Rule "B to C"</title>
+
+ <programlisting>rule "B to C"
+ salience 10
+ when
+ State(name == "B", state == State.FINISHED )
+ c : State(name == "C", state == State.NOTRUN )
+ then
+ System.out.println(c.getName() + " finished" );
+ c.setState( State.FINISHED );
+end
+</programlisting>
+ </example>
+
+ <para>The "B to D" rule fires last, modifying the "D" object to state "FINISHED".</para>
+
+ <example>
+ <title>Salience State Example: Rule "B to D"</title>
+
+ <programlisting>rule "B to D"
+ when
+ State(name == "B", state == State.FINISHED )
+ d : State(name == "D", state == State.NOTRUN )
+ then
+ System.out.println(d.getName() + " finished" );
+ d.setState( State.FINISHED );
+end</programlisting>
+ </example>
+
+ <para>There are no more rules to execute and so the engine stops.</para>
+
+ <para>Another notable concept in this example is the use of <emphasis role="bold">dynamic facts</emphasis>, which is the PropertyChangeListener part. As mentioned previously in the documentation, in order for the engine to see and react to fact's properties change, the application must tell the engine that changes occurred. This can be done explicitly in the rules, by calling the <emphasis role="bold">update()</emphasis> memory action, or implicitly by letting the engine know that the facts implement PropertyChangeSupport as defined by the <emphasis>Javabeans specification</emphasis>. This example demonstrates how to use PropertyChangeSupport to avoid the need for explicit update() calls in the rules. To make use of this feature, make sure your facts implement the PropertyChangeSupport as the org.drools.example.State class does and use the following code to insert the facts into the working memory:</para>
+
+ <example>
+ <title>Inserting a Dynamic Fact</title>
+
+ <programlisting>// By setting dynamic to TRUE, Drools will use JavaBean
+// PropertyChangeListeners so you don't have to call update().
+final boolean dynamic = true;
+
+session.insert( fact,
+ dynamic );
+</programlisting>
+ </example>
+
+ <para>When using PropertyChangeListeners each setter must implement a little extra code to do the notification, here is the state setter for thte org.drools.examples.State class:</para>
+
+ <example>
+ <title>Setter Example with PropertyChangeSupport</title>
+
+ <programlisting>public void setState(final int newState) {
+ int oldState = this.state;
+ this.state = newState;
+ this.changes.firePropertyChange( "state",
+ oldState,
+ newState );
+}</programlisting>
+ </example>
+
+ <para>There are two other State examples: StateExampleUsingAgendGroup and StateExampleWithDynamicRules. Both execute from A to B to C to D, as just shown, the StateExampleUsingAgendGroup uses agenda-groups to control the rule conflict and which one fires first and StateExampleWithDynamicRules shows how an additional rule can be added to an already running WorkingMemory with all the existing data applying to it at runtime.</para>
+
+ <para>Agenda groups are a way to partition the agenda into groups and controlling which groups can execute. All rules by default are in the "MAIN" agenda group, by simply using the "agenda-group" attribute you specify a different agenda group for the rule. A working memory initially only has focus on the "MAIN" agenda group, only when other groups are given the focus can their rules fire; this can be achieved by either using the method setFocus() or the rule attribute "auto-focus". "auto-focus" means that the rule automatically sets the focus to it's agenda group when the rule is matched and activated. It is this "auto-focus" that enables "B to C" to fire before "B to D".</para>
+
+ <example>
+ <title>Agenda Group State Example: Rule "B to C"</title>
+
+ <programlisting>rule "B to C"
+ agenda-group "B to C"
+ auto-focus true
+ when
+ State(name == "B", state == State.FINISHED )
+ c : State(name == "C", state == State.NOTRUN )
+ then
+ System.out.println(c.getName() + " finished" );
+ c.setState( State.FINISHED );
+ drools.setFocus( "B to D" );
+end</programlisting>
+ </example>
+
+ <para>The rule "B to C" calls "drools.setFocus( "B to D" );" which gives the agenda group "B to D" focus allowing its active rules to fire; which allows the rule "B to D" to fire.</para>
+
+ <example>
+ <title>Agenda Group State Example: Rule "B to D"</title>
+
+ <programlisting>rule "B to D"
+ agenda-group "B to D"
+ when
+ State(name == "B", state == State.FINISHED )
+ d : State(name == "D", state == State.NOTRUN )
+ then
+ System.out.println(d.getName() + " finished" );
+ d.setState( State.FINISHED );
+end</programlisting>
+ </example>
+
+ <para>The example StateExampleWithDynamicRules adds another rule to the RuleBase after fireAllRules(), the rule it adds is just another State transition.</para>
+
+ <example>
+ <title>Dynamic State Example: Rule "D to E"</title>
+
+ <programlisting>rule "D to E"
+ when
+ State(name == "D", state == State.FINISHED )
+ e : State(name == "E", state == State.NOTRUN )
+ then
+ System.out.println(e.getName() + " finished" );
+ e.setState( State.FINISHED );
+end</programlisting>
+ </example>
+
+ <para>It gives the following expected output:</para>
+
+ <example>
+ <title>Dynamic Sate Example Output</title>
+
+ <programlisting>A finished
+B finished
+C finished
+D finished
+E finished
+</programlisting>
+ </example>
+
+ </section>
+
+ </section>
\ No newline at end of file
Added: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-TroubleTicketExample.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-TroubleTicketExample.xml (rev 0)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-TroubleTicketExample.xml 2008-06-14 13:00:09 UTC (rev 20479)
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <section xml:base="../">
+ <!-- Trouble Ticket example -->
+ <title>Pricing Rule Decision Table Example</title>
+
+ <para>The Pricing Rule decision table demonstrates the use of a decision table in a spreadsheet (XLS format) in calculating the retail cost of an insurance policy. The purpose of the set of rules provided is to calculate a base price, and an additional discount for a car driver applying for a specific policy. The drivers age, history and the policy type all contribute to what the basic premium is, and an additional chunk of rules deals with refining this with a subtractive percentage discount.</para>
+
+ <programlisting><emphasis role="bold">Name:</emphasis> Example Policy Pricing
+<emphasis role="bold">Main class:</emphasis> org.drools.examples.PricingRuleDTExample
+<emphasis role="bold">Type:</emphasis> java application
+<emphasis role="bold">Rules file:</emphasis> ExamplePolicyPricing.xls
+<emphasis role="bold">Objective:</emphasis> demonstrate spreadsheet based decision tables. </programlisting>
+
+ <section>
+ <title>Executing the example</title>
+
+ <para>Open the PricingRuleDTExample.java and execute it as a Java application. It should produce the following console output:</para>
+
+ <programlisting>Cheapest possible
+BASE PRICE IS: 120
+DISCOUNT IS: 20 </programlisting>
+
+ <para>The code to the execute the example is very similar to the other examples. The rules are loaded, the facts inserted and a stateless session is used. What is different is how the rules are obtained:</para>
+
+ <programlisting>SpreadsheetCompiler compiler = new SpreadsheetCompiler();
+String drl = compiler.compile(getSpreadsheetStream(), InputType.XLS);
+</programlisting>
+
+ <para>Note the use of the SpreadsheetCompiler class. It is what takes the XLS (as a binary InputStream to the XLS file), and outputs ordinary DRL (which is then dealt with in the usual way). You can (if you like) also print out the DRL. If you use the BRMS, all this is of course taken care of for you.</para>
+
+ <para>There are 2 facts used in this example, Driver, and Policy. Both are used with their default values. The Driver is 30 years old, has had no prior claims and currently has a risk profile of LOW. The Policy being applied for is COMPREHENSIVE, and the policy has not yet been approved.</para>
+ </section>
+
+ <section>
+ <title>The decision table</title>
+
+ <para>In this decision table, each row is a rule, and each column is a condition or an action.</para>
+
+ <figure>
+ <title>Decision table configuration</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="TroubleTicket/DT_Config.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Referring to the above, we have the RuleSet declaration, which provides the package name. There are also other optional items you can have here, such as Variables for global variables, and Imports for importing classes. In this case, the namespace of the rules is the same as the fact classes we are using, so we can omit it.</para>
+
+ <para>Moving further down, we can see the RuleTable declaration. The name after this (Pricing bracket) is used as the prefix for all the generated rules. Below that, we have CONDITION or ACTION - this indicates the purpose of the column (ie does it form part of the condition, or an action of a rule that will be generated).</para>
+
+ <para>You can see there is a Driver which is spanned across 3 cells, this means the template expressions below it apply to that fact. So we look at the drivers age range (which uses $1 and $2 with comma separated values), locationRiskProfile, and priorClaims in the respective columns. In the action columns, we are setting the policy base price, and then logging a message.</para>
+
+ <figure>
+ <title>Base price calculation</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="TroubleTicket/DT_Table1.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Referring to the above, we can see there are broad category brackets (indicated by the comment in the left most column). As we know the details of our driver and their policy, we can tell (with a bit of thought) that they should match row number 18, as they have no prior accidents, and are 30 years old. This gives us a base price of 120.</para>
+
+ <figure>
+ <title>Discount calculation</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="TroubleTicket/DT_Table2.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Referring to the above, we are seeing if there is any discount we can give our driver. Based on the Age bracket, number of priot claims, and the policy type, a discount is provided. In our case, the drive is 3, with no priors, and they are applying for COMPREHENSIVE, this means we can give a discount of 20%. Note that this is actually a separate table, but in the same worksheet. This different templates apply.</para>
+
+ <para>It is important to note that decision tables generate rules, this means they aren't simply top down logic, but more a means to capture data that generate rules (this is a subtle difference that confuses some people). The evaluation of the rules is not "top down" necessarily, all the normal indexing and mechanics of the rule engine still apply.</para>
+ </section>
+ </section>
\ No newline at end of file
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Soduki/sudoku1.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku1.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Soduki/sudoku2.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku2.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Soduki/sudoku3.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku3.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Soduki/sudoku4.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku4.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Soduki/sudoku5.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku5.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Soduki/sudoku6.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku6.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Soduki/sudoku7.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku7.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Soduki/sudoku8.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku8.png)
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/StateExample
___________________________________________________________________
Name: svn:ignore
+ *.db
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/TroubleTicket/tt_audit_firing.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/tt_audit_firing.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/TroubleTicket/tt_audit_view.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/tt_audit_view.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/TroubleTicket/tt_initial.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/tt_initial.png)
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/guests_at_table.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/guests_at_table.vsd
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/honest_politician_audit.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/make_path.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/make_path.vsd
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/manners_activity_diagram.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/manners_activity_diagram.svg
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/manners_activity_diagram.svg 2008-06-14 01:58:02 UTC (rev 20478)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/manners_activity_diagram.svg 2008-06-14 13:00:09 UTC (rev 20479)
@@ -1,559 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated by Microsoft Visio 11.0, SVG Export, v1.0 manners_activity_diagram.svg Page-1 --><svg xmlns="http://www.w3.org/2000/svg" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" xmlns:xlink="http://www.w3.org/1999/xlink" width="7.89733in" height="6.9885in" viewBox="0 0 568.608 503.172" xml:space="preserve" color-interpolation-filters="sRGB" class="st14" preserveAspectRatio="xMidYMid meet" zoomAndPan="magnify" version="1.0" contentScriptType="text/ecmascript" contentStyleType="text/css">
- <v:documentProperties v:langID="1033" v:metric="true"/>
-
- <style type="text/css" xml:space="preserve">
-
- .st1 {fill:none;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72}
- .st2 {fill:#000000;font-family:Arial;font-size:1.00001em}
- .st3 {font-size:1em}
- .st4 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72}
- .st5 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72}
- .st6 {fill:#000000;font-family:Arial;font-size:0.666664em}
- .st7 {fill:#000000;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.24}
- .st8 {fill:#000000;stroke:none;stroke-width:1}
- .st9 {marker-end:url(#mrkr3-71);stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.48}
- .st10 {fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:0.10810806741051}
- .st11 {fill:none}
- .st12 {stroke:#000000;stroke-dasharray:5.04,3.6;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72}
- .st13 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.24}
- .st14 {fill:none;fill-rule:evenodd;font-size:12;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
-
- </style>
-
- <defs id="Markers">
- <g id="lend3">
- <path d="M 2 1 L 0 0 L 2 -1 " style="stroke-linecap:round;stroke-linejoin:round;fill:none"/>
- </g>
- <marker xmlns="http://www.w3.org/TR/xhtml1/transitional" overflow="visible" id="mrkr3-71" class="st10" v:arrowType="3" v:arrowSize="4" orient="auto" markerUnits="strokeWidth" preserveAspectRatio="xMidYMid meet">
- <use xmlns="http://www.w3.org/2000/svg" xlink:href="#lend3" transform="scale(-9.2500034821895,-9.2500034821895) " xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>
- </marker>
- </defs>
- <g v:mID="0" v:index="1" v:groupContext="foregroundPage">
- <title content="structured text">Page-1</title>
- <v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394" v:shadowOffsetY="-8.50394"/>
- <v:layer v:name="Swimlanes" v:index="0" v:snap="false" v:glue="false"/>
- <g id="shape1-1" v:mID="1" v:groupContext="shape" v:layerMember="0" transform="translate(454.263,-0.720106)">
- <title content="structured text">Swimlane.41</title>
- <desc content="structured text">PRINT RESULTS</desc>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(63):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({3D0B90F0-7997-4048-B958-E2D430F8F96C})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a partition for organizing responsibility for activities.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197" v:verticalAlign="0"/>
- <v:textRect cx="56.6929" cy="252.306" width="113.39" height="501.732"/>
- <rect x="0" y="1.44021" width="113.386" height="501.732" class="st1"/>
- <text x="9.36" y="16.24" class="st2" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>PRINT RESULTS</text> </g>
- <g id="shape2-4" v:mID="2" v:groupContext="shape" v:layerMember="0" transform="translate(340.877,-0.720106)">
- <title content="structured text">Swimlane.40</title>
- <desc content="structured text">CHECK DONE</desc>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(63):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({B70CD6A2-C8F2-41E7-8A0B-4364B926C213})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a partition for organizing responsibility for activities.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197" v:verticalAlign="0"/>
- <v:textRect cx="56.6929" cy="252.306" width="113.39" height="501.732"/>
- <rect x="0" y="1.44021" width="113.386" height="501.732" class="st1"/>
- <text x="16.69" y="16.24" class="st2" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>CHECK DONE</text> </g>
- <g id="shape3-7" v:mID="3" v:groupContext="shape" v:layerMember="0" transform="translate(227.492,-0.720106)">
- <title content="structured text">Swimlane.39</title>
- <desc content="structured text">MAK PATH</desc>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(63):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({2BDF3D67-E7C5-4A9B-A36F-B092FDAD9B83})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a partition for organizing responsibility for activities.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197" v:verticalAlign="0"/>
- <v:textRect cx="56.6929" cy="252.306" width="113.39" height="501.732"/>
- <rect x="0" y="1.44021" width="113.386" height="501.732" class="st1"/>
- <text x="22.02" y="16.24" class="st2" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>MAK<tspan class="st3" v:langID="2057">E</tspan> PATH</text> </g>
- <g id="shape4-11" v:mID="4" v:groupContext="shape" v:layerMember="0" transform="translate(114.106,-0.720106)">
- <title content="structured text">Swimlane.38</title>
- <desc content="structured text">ASSIGN SEATS</desc>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(63):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({5FE20143-2F05-4843-84D8-69654A33246B})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a partition for organizing responsibility for activities.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197" v:verticalAlign="0"/>
- <v:textRect cx="56.6929" cy="252.306" width="113.39" height="501.732"/>
- <rect x="0" y="1.44021" width="113.386" height="501.732" class="st1"/>
- <text x="12.68" y="16.24" class="st2" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>ASSIGN SEATS</text> </g>
- <g id="shape5-14" v:mID="5" v:groupContext="shape" v:layerMember="0" transform="translate(0.72,-0.720106)">
- <title content="structured text">Swimlane</title>
- <desc content="structured text">START UP</desc>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(63):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({75512333-30FD-445E-A107-21F276DEBAB2})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a partition for organizing responsibility for activities.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197" v:verticalAlign="0"/>
- <v:textRect cx="56.6929" cy="252.306" width="113.39" height="501.732"/>
- <rect x="0" y="1.44021" width="113.386" height="501.732" class="st1"/>
- <text x="27.03" y="16.24" class="st2" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>START UP</text> </g>
- <g id="group6-17" transform="translate(21.6928,-370.641)" v:mID="6" v:groupContext="group">
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(40):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({DB57AEDC-DB06-4A74-9314-493961D4DB78})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
- <v:ud v:nameU="UMLSuppressOption" v:val="VT0(32):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="UMLAutoLockTextEdit" v:val="VT0(1):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a condition during which an object satisfies some condition, performs an action or waits for an event.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <title content="structured text">State</title>
- <g id="shape7-18" v:mID="7" v:groupContext="shape" transform="translate(-3.59712E-013,-0.002)">
- <title content="structured text">Sheet.7</title>
- <path d="M9 503.17 L62.44 503.17 A9 9 -180 0 0 71.44 494.17 L71.44 486.66 A9 9 -180 0 0 62.44 477.66 L9 477.66 A9 9 -180 0 0 -0 486.66 L0 494.17 A9 9 -180 0 0 9 503.17 Z" class="st4"/>
- </g>
- <g id="shape8-20" v:mID="8" v:groupContext="shape" transform="translate(0,-0.002)">
- <title content="structured text">Transitions</title>
- <path d="M0 503.17 L53.86 503.17 L0 503.17 Z" class="st5"/>
- </g>
- <g id="shape9-22" v:mID="9" v:groupContext="shape">
- <title content="structured text">Name</title>
- <desc content="structured text">Assign First Seat</desc>
- <v:userDefs/>
- <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
- <v:textRect cx="35.7202" cy="490.572" width="71.45" height="25.2"/>
- <rect x="0" y="477.972" width="71.4403" height="25.2" class="st5"/>
- <text x="5.49" y="492.97" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Assign First Seat</text> </g>
- </g>
- <g id="shape10-25" v:mID="10" v:groupContext="shape" transform="translate(48.909,-459.93)">
- <title content="structured text">Initial State</title>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(42):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({D3A1415C-7F84-4D75-B77E-54E0988D4921})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOptions" v:val="VT0(3):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents the point at which a newly created object starts. )"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <path d="M0 494.67 A8.505 8.505 0 0 1 17.01 494.67 A8.505 8.505 0 0 1 0 494.67 Z" class="st7"/>
- </g>
- <g id="group11-27" transform="translate(128.279,-370.641)" v:mID="11" v:groupContext="group">
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(40):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({E425FBE2-6092-4F19-BCF9-83EBE6D8AA54})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
- <v:ud v:nameU="UMLSuppressOption" v:val="VT0(32):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="UMLAutoLockTextEdit" v:val="VT0(1):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a condition during which an object satisfies some condition, performs an action or waits for an event.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <title content="structured text">State.7</title>
- <g id="shape12-28" v:mID="12" v:groupContext="shape" transform="translate(0,-0.002)">
- <title content="structured text">Sheet.12</title>
- <path d="M9 503.17 L45 503.17 A9 9 -180 0 0 54 494.17 L54 486.66 A9 9 -180 0 0 45 477.66 L9 477.66 A9 9 -180 0 0 -0 486.66 L0 494.17 A9 9 -180 0 0 9 503.17 Z" class="st4"/>
- </g>
- <g id="shape13-30" v:mID="13" v:groupContext="shape" transform="translate(-2.63789E-013,-0.002)">
- <title content="structured text">Transitions</title>
- <path d="M0 503.17 L53.86 503.17 L0 503.17 Z" class="st5"/>
- </g>
- <g id="shape14-32" v:mID="14" v:groupContext="shape">
- <title content="structured text">Name</title>
- <desc content="structured text">Assign Seat</desc>
- <v:userDefs/>
- <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
- <v:textRect cx="27" cy="490.572" width="54" height="25.2"/>
- <rect x="0" y="477.972" width="54" height="25.2" class="st5"/>
- <text x="5.65" y="492.97" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Assign Seat</text> </g>
- </g>
- <g id="group15-35" transform="translate(268.817,-278.515)" v:mID="15" v:groupContext="group">
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(40):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({78CF0676-A242-4FF4-9B81-3A830037047F})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
- <v:ud v:nameU="UMLSuppressOption" v:val="VT0(32):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="UMLAutoLockTextEdit" v:val="VT0(1):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a condition during which an object satisfies some condition, performs an action or waits for an event.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <title content="structured text">State.11</title>
- <g id="shape16-36" v:mID="16" v:groupContext="shape" transform="translate(0,-0.002)">
- <title content="structured text">Sheet.16</title>
- <path d="M9 503.17 L45 503.17 A9 9 -180 0 0 54 494.17 L54 486.66 A9 9 -180 0 0 45 477.66 L9 477.66 A9 9 -180 0 0 -0 486.66 L0 494.17 A9 9 -180 0 0 9 503.17 Z" class="st4"/>
- </g>
- <g id="shape17-38" v:mID="17" v:groupContext="shape" transform="translate(-2.63789E-013,-0.002)">
- <title content="structured text">Transitions</title>
- <path d="M0 503.17 L53.86 503.17 L0 503.17 Z" class="st5"/>
- </g>
- <g id="shape18-40" v:mID="18" v:groupContext="shape">
- <title content="structured text">Name</title>
- <desc content="structured text">Make Path</desc>
- <v:userDefs/>
- <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
- <v:textRect cx="27" cy="490.572" width="54" height="25.2"/>
- <rect x="0" y="477.972" width="54" height="25.2" class="st5"/>
- <text x="7.88" y="492.97" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Make Path</text> </g>
- </g>
- <g id="group19-43" transform="translate(268.817,-190.641)" v:mID="19" v:groupContext="group">
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(40):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({657E0538-CBB4-4B62-B170-CA54F78F0FC3})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
- <v:ud v:nameU="UMLSuppressOption" v:val="VT0(32):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="UMLAutoLockTextEdit" v:val="VT0(1):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a condition during which an object satisfies some condition, performs an action or waits for an event.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <title content="structured text">State.15</title>
- <g id="shape20-44" v:mID="20" v:groupContext="shape" transform="translate(0,-0.002)">
- <title content="structured text">Sheet.20</title>
- <path d="M9 503.17 L45 503.17 A9 9 -180 0 0 54 494.17 L54 486.66 A9 9 -180 0 0 45 477.66 L9 477.66 A9 9 -180 0 0 -0 486.66 L0 494.17 A9 9 -180 0 0 9 503.17 Z" class="st4"/>
- </g>
- <g id="shape21-46" v:mID="21" v:groupContext="shape" transform="translate(-2.63789E-013,-0.002)">
- <title content="structured text">Transitions</title>
- <path d="M0 503.17 L53.86 503.17 L0 503.17 Z" class="st5"/>
- </g>
- <g id="shape22-48" v:mID="22" v:groupContext="shape">
- <title content="structured text">Name</title>
- <desc content="structured text">Path Done</desc>
- <v:userDefs/>
- <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
- <v:textRect cx="27" cy="490.572" width="54" height="25.2"/>
- <rect x="0" y="477.972" width="54" height="25.2" class="st5"/>
- <text x="8.1" y="492.97" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Path Done</text> </g>
- </g>
- <g id="group23-51" transform="translate(357.885,-114.106)" v:mID="23" v:groupContext="group">
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(40):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({0CB21845-E36D-4CDF-B78A-00B75363D7E2})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
- <v:ud v:nameU="UMLSuppressOption" v:val="VT0(32):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="UMLAutoLockTextEdit" v:val="VT0(1):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a condition during which an object satisfies some condition, performs an action or waits for an event.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <title content="structured text">State.19</title>
- <g id="shape24-52" v:mID="24" v:groupContext="shape" transform="translate(3.83693E-013,-0.002)">
- <title content="structured text">Sheet.24</title>
- <path d="M9 503.17 L68.67 503.17 A9 9 -180 0 0 77.67 494.17 L77.67 486.66 A9 9 -180 0 0 68.67 477.66 L9 477.66 A9 9 -180 0 0 0 486.66 L0 494.17 A9 9 -180 0 0 9 503.17 Z" class="st4"/>
- </g>
- <g id="shape25-54" v:mID="25" v:groupContext="shape" transform="translate(-3.8769E-013,-0.002)">
- <title content="structured text">Transitions</title>
- <path d="M0 503.17 L53.86 503.17 L0 503.17 Z" class="st5"/>
- </g>
- <g id="shape26-56" v:mID="26" v:groupContext="shape">
- <title content="structured text">Name</title>
- <desc content="structured text">Are We Done Yet?</desc>
- <v:userDefs/>
- <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
- <v:textRect cx="38.8371" cy="490.572" width="77.68" height="25.2"/>
- <rect x="0" y="477.972" width="77.6742" height="25.2" class="st5"/>
- <text x="5.5" y="492.97" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Are We Done Yet?</text> </g>
- </g>
- <g id="group27-59" transform="translate(499.433,-14.8903)" v:mID="27" v:groupContext="group">
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(43):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({B1433F32-F2A4-439C-B8CC-D61EC899F625})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOptions" v:val="VT0(3):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents the final occurrence of an event at the enclosing state or the completion of activity in the enclosing state.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- <v:ud v:nameU="UMLPresOption1" v:prompt="" v:val="VT0(3):26"/>
- </v:userDefs>
- <title content="structured text">Final State</title>
- <g id="shape28-60" v:mID="28" v:groupContext="shape" transform="translate(1.7,-1.7)">
- <title content="structured text">Sheet.28</title>
- <path d="M0 496.37 A6.805 6.805 0 1 1 13.61 496.37 A6.805 6.805 0 1 1 -0 496.37 Z" class="st8"/>
- </g>
- <g id="shape29-62" v:mID="29" v:groupContext="shape" transform="translate(1.7,-1.7)">
- <title content="structured text">Sheet.29</title>
- <path d="M0 496.37 A6.805 6.805 0 1 1 13.61 496.37 A6.805 6.805 0 1 1 -0 496.37 Z" class="st1"/>
- </g>
- <g id="shape30-64" v:mID="30" v:groupContext="shape">
- <title content="structured text">Sheet.30</title>
- <path d="M0 494.67 A8.505 8.505 0 0 1 17.01 494.67 A8.505 8.505 0 1 1 -0 494.67 Z" class="st1"/>
- </g>
- </g>
- <g id="shape31-66" v:mID="31" v:groupContext="shape" transform="translate(93.1331,-383.393)">
- <title content="structured text">Transition</title>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({B3C07C44-3D10-4AD1-A487-A918B63E7036})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <path d="M0 503.17 L35.15 503.17" class="st9"/>
- </g>
- <g id="shape32-72" v:mID="32" v:groupContext="shape" transform="translate(155.279,-291.273)">
- <title content="structured text">Transition.26</title>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({4F3E71C3-C7E3-4C97-BCE4-9EE74B61A90E})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <path d="M0 423.8 L0 503.17 L113.54 503.17" class="st9"/>
- </g>
- <g id="shape33-77" v:mID="33" v:groupContext="shape" transform="translate(295.82,-216.157)">
- <title content="structured text">Transition.27</title>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({504935DB-8552-4C36-BB2A-679D59656DF9})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <path d="M0 440.81 L0 503.17" class="st9"/>
- </g>
- <g id="shape34-82" v:mID="34" v:groupContext="shape" transform="translate(322.817,-203.393)">
- <title content="structured text">Transition.23</title>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({57E139FF-A173-426F-820B-4F7C9BFEC138})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <path d="M0 503.17 L63.98 503.17" class="st9"/>
- </g>
- <g id="shape35-87" v:mID="35" v:groupContext="shape" transform="translate(507.94,-31.8981)">
- <title content="structured text">Transition.28</title>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({5FECE46A-D06F-418F-981D-461303A12B44})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <path d="M0 420.96 L0 503.17" class="st9"/>
- </g>
- <g id="shape36-92" v:mID="36" v:groupContext="shape" transform="translate(182.277,-298.36)">
- <title content="structured text">Transition.29</title>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({2C74DA93-74E8-41A5-92D8-33F11DFE1CC4})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <path d="M216.64 503.17 L216.64 418.13 L0 418.13" class="st9"/>
- </g>
- <g id="shape37-97" v:mID="37" v:groupContext="shape" transform="translate(57.4163,-396.155)">
- <title content="structured text">Transition.30</title>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({184492BD-048C-4EF2-8A9B-8858BE1127F1})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <path d="M0 439.39 L0 503.17" class="st9"/>
- </g>
- <g id="shape38-102" v:mID="38" v:groupContext="shape" transform="translate(386.801,-193.478)">
- <title content="structured text">Decision</title>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(62):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({92B419EA-931A-4897-B261-6E85B2B91766})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption1" v:val="VT0(3):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Expresses a decision when guard conditions are used to indicate different possible transitions that are Boolean dependent.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <path d="M9.92 483.33 L19.84 493.25 L9.92 503.17 L0 493.25 L9.92 483.33 Z" class="st4"/>
- </g>
- <g id="shape39-104" v:mID="39" v:groupContext="shape" transform="translate(396.726,-139.618)">
- <title content="structured text">Transition.32</title>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({0C0D162D-C8BA-4916-9E41-0251B2A289C3})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <path d="M0 449.31 L0 503.17" class="st9"/>
- </g>
- <g id="group40-109" transform="translate(406.645,-203.395)" v:mID="40" v:groupContext="group">
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(45):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({9E3814E0-25B1-43C1-A187-E4B1218E0059})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="UMLPresOption1" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Use to place a comment on a diagram. )"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <title content="structured text">Note</title>
- <g id="shape41-110" v:mID="41" v:groupContext="shape">
- <title content="structured text">Sheet.41</title>
- <path d="M109.98 472.41 L0 503.17 L109.98 472.41 Z" class="st11"/>
- <path d="M109.98 472.41 L0 503.17" class="st12"/>
- </g>
- <g id="shape42-113" v:mID="42" v:groupContext="shape" transform="translate(66.5014,-12.76)">
- <title content="structured text">Name</title>
- <desc content="structured text">Has the last seat been assigned?</desc>
- <v:userDefs/>
- <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
- <v:textRect cx="43.4786" cy="485.174" width="86.96" height="36"/>
- <path d="M86.96 477.97 L77.96 467.17 L77.96 477.97 L86.96 477.97 Z M0 503.17 L86.96 503.17 L86.96 477.97 L77.96 477.97 L77.96 467.17 L0 467.17 L0 503.17 Z" class="st13"/>
- <text x="4" y="477.97" class="st6" v:langID="1033"><v:paragraph/><v:tabList/>Has the last seat<v:newlineChar/><v:newlineChar/><tspan x="4" dy="2.4em" class="st3">been assigned</tspan>?</text> </g>
- </g>
- <g id="shape43-117" v:mID="43" v:groupContext="shape" transform="translate(241.247,-162.295)">
- <title content="structured text">Transition.36</title>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({4CA9F553-D55B-452E-AC25-34A2387F9FF8})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <path d="M54.57 474.82 L54.57 503.17 L0 503.17 L0 462.07 L27.57 462.07" class="st9"/>
- </g>
- <g id="group44-122" transform="translate(479.775,-114.106)" v:mID="44" v:groupContext="group">
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(40):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({45A56721-BBBC-4499-92F5-D1460BF36DFC})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
- <v:ud v:nameU="UMLSuppressOption" v:val="VT0(32):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="UMLAutoLockTextEdit" v:val="VT0(1):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a condition during which an object satisfies some condition, performs an action or waits for an event.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <title content="structured text">State.42</title>
- <g id="shape45-123" v:mID="45" v:groupContext="shape" transform="translate(2.79776E-013,-0.002)">
- <title content="structured text">Sheet.45</title>
- <path d="M9 503.17 L47.32 503.17 A9 9 -180 0 0 56.32 494.17 L56.32 486.66 A9 9 -180 0 0 47.32 477.66 L9 477.66 A9 9 -180 0 0 -0 486.66 L0 494.17 A9 9 -180 0 0 9 503.17 Z" class="st4"/>
- </g>
- <g id="shape46-125" v:mID="46" v:groupContext="shape" transform="translate(-2.79776E-013,-0.002)">
- <title content="structured text">Transitions</title>
- <path d="M0 503.17 L53.86 503.17 L0 503.17 Z" class="st5"/>
- </g>
- <g id="shape47-127" v:mID="47" v:groupContext="shape">
- <title content="structured text">Name</title>
- <desc content="structured text">Print Results</desc>
- <v:userDefs/>
- <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
- <v:textRect cx="28.1617" cy="490.572" width="56.33" height="25.2"/>
- <rect x="0" y="477.972" width="56.3234" height="25.2" class="st5"/>
- <text x="5.5" y="492.97" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Print Results</text> </g>
- </g>
- <g id="shape48-130" v:mID="48" v:groupContext="shape" transform="translate(435.56,-126.857)">
- <title content="structured text">Transition.46</title>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({1E830686-D9A6-494E-BFB9-A2EC4ECC87E5})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <path d="M0 503.17 L44.22 503.17" class="st9"/>
- </g>
- <g id="shape49-135" v:mID="49" v:groupContext="shape" transform="translate(507.939,-126.865)">
- <title content="structured text">Transition.47</title>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({522F1FDF-7CC6-4604-AE43-C0C5FBC68F58})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <path d="M28.16 503.17 L48.37 503.17 L48.37 464.91 L0 464.91 L0 490.42" class="st9"/>
- </g>
- <g id="group50-140" transform="translate(371.917,-272.846)" v:mID="50" v:groupContext="group">
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(40):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({279920C9-96D3-48C9-B5C7-9BD96A5EA82B})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption1" v:val="VT0(1):26"/>
- <v:ud v:nameU="UMLSuppressOption" v:val="VT0(32):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="UMLAutoLockTextEdit" v:val="VT0(1):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a condition during which an object satisfies some condition, performs an action or waits for an event.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <title content="structured text">State.48</title>
- <g id="shape51-141" v:mID="51" v:groupContext="shape" transform="translate(0,-0.002)">
- <title content="structured text">Sheet.51</title>
- <path d="M9 503.17 L45 503.17 A9 9 -180 0 0 54 494.17 L54 486.66 A9 9 -180 0 0 45 477.66 L9 477.66 A9 9 -180 0 0 0 486.66 L0 494.17 A9 9 -180 0 0 9 503.17 Z" class="st4"/>
- </g>
- <g id="shape52-143" v:mID="52" v:groupContext="shape" transform="translate(-2.67786E-013,-0.002)">
- <title content="structured text">Transitions</title>
- <path d="M0 503.17 L53.86 503.17 L0 503.17 Z" class="st5"/>
- </g>
- <g id="shape53-145" v:mID="53" v:groupContext="shape">
- <title content="structured text">Name</title>
- <desc content="structured text">Continue?</desc>
- <v:userDefs/>
- <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
- <v:textRect cx="27" cy="490.572" width="54" height="25.2"/>
- <rect x="0" y="477.972" width="54" height="25.2" class="st5"/>
- <text x="8.76" y="492.97" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Continue?</text> </g>
- </g>
- <g id="shape54-148" v:mID="54" v:groupContext="shape" transform="translate(396.723,-213.32)">
- <title content="structured text">Transition.52</title>
- <v:userDefs>
- <v:ud v:nameU="UMLShapeType" v:val="VT0(44):26"/>
- <v:ud v:nameU="UMLObjectGUID" v:val="VT4({9C4F3353-5467-4385-8431-508C3C950FD2})"/>
- <v:ud v:nameU="UMLError" v:val="VT0(0):26"/>
- <v:ud v:nameU="UMLPresOption2" v:val="VT0(98306):26"/>
- <v:ud v:nameU="UMLVersion" v:val="VT0(2):26"/>
- <v:ud v:nameU="visDescription" v:val="VT4(Represents a transition from one state to another.)"/>
- <v:ud v:nameU="visVersion" v:val="VT0(11):26"/>
- </v:userDefs>
- <path d="M0 503.17 L2.19 443.64" class="st9"/>
- </g>
- </g>
-</svg>
\ No newline at end of file
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/manners_activity_diagram.vsd
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/numberguess-constraint-toohigh.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/numberguess-editconstraints.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/numberguess-ruleflow-properties.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/numberguess-ruleflow.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku1.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku2.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku3.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku4.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku5.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku6.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku7.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/sudoku8.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/tt_audit_firing.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/tt_audit_view.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/tt_initial.png
===================================================================
(Binary files differ)
More information about the jboss-svn-commits
mailing list