From: <jbo...@li...> - 2006-05-19 09:16:51
|
Author: mar...@jb... Date: 2006-05-19 05:16:42 -0400 (Fri, 19 May 2006) New Revision: 4324 Added: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Male_People.png labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Male_People.svg labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Rules.xml Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Rule_Engine.vsd labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-What_is_a_Rule_Engine.xml labs/jbossrules/trunk/documentation/manual/en/master.xml Log: Added: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Male_People.png =================================================================== (Binary files differ) Property changes on: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Male_People.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Male_People.svg =================================================================== --- labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Male_People.svg 2006-05-19 01:11:06 UTC (rev 4323) +++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Male_People.svg 2006-05-19 09:16:42 UTC (rev 4324) @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Generated by Microsoft Visio 11.0, SVG Export, v1.0 Male_People.svg Page-1 --> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="6.52453in" + height="3.99817in" viewBox="0 0 469.766 287.869" xml:space="preserve" color-interpolation-filters="sRGB" class="st10"> + <v:documentProperties v:langID="1033" v:metric="true" v:viewMarkup="false"/> + + <style type="text/css"> + <![CDATA[ + .st1 {fill:#ffffff} + .st2 {stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st3 {fill:#000000;font-family:Arial;font-size:1.5em} + .st4 {font-size:1em} + .st5 {fill:#000000;font-family:Arial;font-size:1.66667em} + .st6 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.24} + .st7 {marker-end:url(#mrkr13-24);stroke:#4677bf;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.24} + .st8 {fill:#4677bf;fill-opacity:1;stroke:#4677bf;stroke-opacity:1;stroke-width:0.08695652173913} + .st9 {marker-end:url(#mrkr4-35);stroke:#4677bf;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.24} + .st10 {fill:none;fill-rule:evenodd;font-size:12;overflow:visible;stroke-linecap:square;stroke-miterlimit:3} + ]]> + </style> + + <defs id="Markers"> + <g id="lend13"> + <path d="M 3 1 L 0 0 L 3 -1 L 3 1 " style="stroke:none"/> + </g> + <marker id="mrkr13-24" class="st8" v:arrowType="13" v:arrowSize="2" v:setback="34.5" refX="-34.5" orient="auto" + markerUnits="strokeWidth"> + <use xlink:href="#lend13" transform="scale(-11.5,-11.5) "/> + </marker> + <g id="lend4"> + <path d="M 2 1 L 0 0 L 2 -1 L 2 1 " style="stroke:none"/> + </g> + <marker id="mrkr4-35" class="st8" v:arrowType="4" v:arrowSize="2" v:setback="23" refX="-23" orient="auto" + markerUnits="strokeWidth"> + <use xlink:href="#lend4" transform="scale(-11.5,-11.5) "/> + </marker> + </defs> + <g v:mID="0" v:index="1" v:groupContext="foregroundPage"> + <title>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="Network" v:index="0"/> + <v:layer v:name="Connector" v:index="1"/> + <g id="shape1-1" v:mID="1" v:groupContext="shape" v:layerMember="0" transform="translate(0.72,-187.327)"> + <title>Datastore.12</title> + <desc>People.sex == “male”</desc> + <v:custProps> + <v:cp v:nameU="Manufacturer" v:lbl="Manufacturer" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" + v:langID="1033" v:val="VT4()"/> + <v:cp v:nameU="ProductNumber" v:lbl="Product Number" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" + v:langID="1033" v:val="VT4()"/> + <v:cp v:nameU="PartNumber" v:lbl="Part Number" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" + v:langID="1033" v:val="VT4()"/> + <v:cp v:nameU="ProductDescription" v:lbl="Product Description" v:type="0" v:sortKey="1" v:invis="false" + v:ask="false" v:langID="1033" v:val="VT4()"/> + <v:cp v:nameU="AssetNumber" v:lbl="Asset Number" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" + v:langID="1033" v:val="VT4()"/> + <v:cp v:nameU="SerialNumber" v:lbl="Serial Number" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" + v:langID="1033" v:val="VT4()"/> + <v:cp v:nameU="Location" v:lbl="Location" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" v:langID="1033" + v:val="VT4()"/> + <v:cp v:nameU="Building" v:lbl="Building" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" v:langID="1033" + v:val="VT4()"/> + <v:cp v:nameU="Room" v:lbl="Room" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" v:langID="1033" + v:val="VT4()"/> + <v:cp v:nameU="Department" v:lbl="Department" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" + v:langID="1033" v:val="VT4()"/> + </v:custProps> + <v:userDefs> + <v:ud v:nameU="visDescription" + v:val="VT4(Use to add a a database, data source, or data storage device to your system diagram.)"/> + <v:ud v:nameU="visVersion" v:val="VT0(11):26"/> + </v:userDefs> + <v:textBlock v:margins="rect(0,0,0,0)" v:tabSpace="42.5197"/> + <v:textRect cx="49.9109" cy="244.196" width="99.83" height="62.3887"/> + <path d="M0 200.52 L0 275.39 A49.9109 12.4777 -180 1 0 99.82 275.39 L99.82 200.52 A49.9109 12.4777 -180 0 0 0 200.52 Z" + class="st1"/> + <path d="M0 200.52 L0 275.39 A49.9109 12.4777 -180 1 0 99.82 275.39 L99.82 200.52 A49.9109 12.4777 -180 0 0 0 200.52" + class="st2"/> + <path d="M0 200.52 A49.9109 12.4777 -180 0 0 99.82 200.52" class="st2"/> + <text x="5.37" y="238.8" class="st3" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>People.sex <tspan + x="11.39" dy="1.2em" class="st4">== </tspan>“male”</text> </g> + <g id="shape2-7" v:mID="2" v:groupContext="shape" v:layerMember="0" transform="translate(369.224,-187.327)"> + <title>Datastore.13</title> + <desc>People</desc> + <v:custProps> + <v:cp v:nameU="Manufacturer" v:lbl="Manufacturer" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" + v:langID="1033" v:val="VT4()"/> + <v:cp v:nameU="ProductNumber" v:lbl="Product Number" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" + v:langID="1033" v:val="VT4()"/> + <v:cp v:nameU="PartNumber" v:lbl="Part Number" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" + v:langID="1033" v:val="VT4()"/> + <v:cp v:nameU="ProductDescription" v:lbl="Product Description" v:type="0" v:sortKey="1" v:invis="false" + v:ask="false" v:langID="1033" v:val="VT4()"/> + <v:cp v:nameU="AssetNumber" v:lbl="Asset Number" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" + v:langID="1033" v:val="VT4()"/> + <v:cp v:nameU="SerialNumber" v:lbl="Serial Number" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" + v:langID="1033" v:val="VT4()"/> + <v:cp v:nameU="Location" v:lbl="Location" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" v:langID="1033" + v:val="VT4()"/> + <v:cp v:nameU="Building" v:lbl="Building" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" v:langID="1033" + v:val="VT4()"/> + <v:cp v:nameU="Room" v:lbl="Room" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" v:langID="1033" + v:val="VT4()"/> + <v:cp v:nameU="Department" v:lbl="Department" v:type="0" v:sortKey="1" v:invis="false" v:ask="false" + v:langID="1033" v:val="VT4()"/> + </v:custProps> + <v:userDefs> + <v:ud v:nameU="visDescription" + v:val="VT4(Use to add a a database, data source, or data storage device to your system diagram.)"/> + <v:ud v:nameU="visVersion" v:val="VT0(11):26"/> + </v:userDefs> + <v:textBlock v:margins="rect(0,0,0,0)" v:tabSpace="42.5197"/> + <v:textRect cx="49.9109" cy="244.196" width="99.83" height="62.3887"/> + <path d="M0 200.52 L0 275.39 A49.9109 12.4777 -180 1 0 99.82 275.39 L99.82 200.52 A49.9109 12.4777 -180 0 0 0 200.52 Z" + class="st1"/> + <path d="M0 200.52 L0 275.39 A49.9109 12.4777 -180 1 0 99.82 275.39 L99.82 200.52 A49.9109 12.4777 -180 0 0 0 200.52" + class="st2"/> + <path d="M0 200.52 A49.9109 12.4777 -180 0 0 99.82 200.52" class="st2"/> + <text x="18.76" y="250.2" class="st5" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>People</text> </g> + <g id="shape3-12" v:mID="3" v:groupContext="shape" transform="translate(161.182,-138.464)"> + <title>Rectangle.18</title> + <desc>Inference Engine</desc> + <v:userDefs> + <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="73.7008" cy="259.522" width="147.41" height="56.6929"/> + <rect x="0" y="231.176" width="147.402" height="56.6929" class="st6"/> + <text x="32.01" y="253.18" class="st5" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>Inference <tspan + x="42.56" dy="1.2em" class="st4">Engine</tspan></text> </g> + <g id="shape4-16" v:mID="4" v:groupContext="shape" transform="translate(164.017,-0.24)"> + <title>Rectangle.22</title> + <desc>Results</desc> + <v:userDefs> + <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:textRect cx="70.8661" cy="262.357" width="141.74" height="51.0236"/> + <rect x="0" y="236.845" width="141.732" height="51.0236" class="st6"/> + <text x="37.53" y="268.36" class="st5" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>Results</text> </g> + <g id="shape5-19" v:mID="5" v:groupContext="shape" v:layerMember="1" transform="translate(100.542,-237.238)"> + <title>Dynamic connector.18</title> + <v:userDefs> + <v:ud v:nameU="visVersion" v:val="VT0(11):26"/> + </v:userDefs> + <path d="M0 287.87 L10.63 287.87 A10.6299 10.6299 0 0 1 21.26 298.5 L21.26 338.61 A19.6902 19.6902 -180 0 0 40.95 358.3 + L52.36 358.3" class="st7"/> + </g> + <g id="shape6-25" v:mID="6" v:groupContext="shape" v:layerMember="1" transform="translate(369.224,-237.238)"> + <title>Dynamic connector.19</title> + <v:userDefs> + <v:ud v:nameU="visVersion" v:val="VT0(11):26"/> + </v:userDefs> + <path d="M0 287.87 L-10.63 287.87 A10.6299 10.6299 -180 0 0 -21.26 298.5 L-21.26 338.61 A19.6902 19.6902 0 0 1 -40.95 + 358.3 L-52.36 358.3" class="st7"/> + </g> + <g id="shape7-30" v:mID="7" v:groupContext="shape" v:layerMember="1" transform="translate(227.796,-138.464)"> + <title>Dynamic connector.6</title> + <v:userDefs> + <v:ud v:nameU="visVersion" v:val="VT0(11):26"/> + </v:userDefs> + <path d="M7.09 287.87 L7.09 369.55" class="st9"/> + </g> + </g> +</svg> Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Rule_Engine.vsd =================================================================== (Binary files differ) Added: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Rules.xml =================================================================== --- labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Rules.xml 2006-05-19 01:11:06 UTC (rev 4323) +++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-Rules.xml 2006-05-19 09:16:42 UTC (rev 4324) @@ -0,0 +1,311 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section> + <title>Rules</title> + + <section> + <title>Production Rules</title> + + <para>A <indexterm> + <primary>Production Rule</primary> + </indexterm>Production Rule, or Rule, in Drools is a two part structure + with a Left Hand Side (LHS) and a Right Hand Side (RHS) additionally a + Rule may have the following attributes:</para> + + <itemizedlist> + <listitem> + <para>salience</para> + </listitem> + + <listitem> + <para>activation-group</para> + </listitem> + + <listitem> + <para>no-loop</para> + </listitem> + + <listitem> + <para>auto-focus</para> + </listitem> + + <listitem> + <para>duration</para> + </listitem> + </itemizedlist> + + <programlisting>rule “<name>” + <attribute> <value> + when + <LHS> + then + <RHS> +end +</programlisting> + + <para>The LHS of a Rule consists of <indexterm> + <primary>Conditional Element</primary> + </indexterm>Conditional Elements (CE) and Columns; to facilate the + encoding of propositional and first order logic. The term <indexterm> + <primary>Column</primary> + </indexterm>Column is used to indicate <indexterm> + <primary>Field Constraint</primary> + </indexterm>Field Constraints on a Fact.</para> + + <para>Drools currently supports the follows CEs:</para> + + <itemizedlist> + <listitem> + <para>'and'</para> + </listitem> + + <listitem> + <para>'or',</para> + </listitem> + + <listitem> + <para>'not',</para> + </listitem> + + <listitem> + <para>'exists'</para> + </listitem> + </itemizedlist> + + <para>'forall' and 'accumulate' will be added shortley. The following + Field Constraints are allowed:</para> + + <itemizedlist> + <listitem> + <para>Literal Constraint</para> + </listitem> + + <listitem> + <para>Bound Variable Constraint</para> + </listitem> + + <listitem> + <para>Return Value</para> + </listitem> + + <listitem> + <para>Predicate</para> + </listitem> + </itemizedlist> + + <para>The Language Guide chapter provides more indepth information for + each of these.</para> + + <para>As facts are asserted and modified in the Working Memory it matches + the facts against the LHS conditions, when all the conditions are met and + true the Rule plus those match facts are activated. When a Rule is + activated it is placed onto the Agenda for potential execution, where the + actions of RHS, called t he <indexterm> + <primary>Consequence</primary> + </indexterm>Consequence, are executed. The LHS and the RHS is analogous + to:</para> + + <programlisting>if ( <LHS> ) { + <RHS> +}</programlisting> + + <para>However 'if' is considered procedural in that it is one part of a + possible execution flow - if this.... else if.... else ..... Rules use + 'when' to more semantically recognise that the rule will activate when, + and only when, its LHS is matched.</para> + + <para>Rules are associated with a namespace via the + <literal>package</literal> keyword; other Rule Engines may call this a + <indexterm> + <primary>Rule Set</primary> + </indexterm>Rule Set. A Package declares imports, global variables, + functions and rules.</para> + + <programlisting>package com.sample + +import java.util.List +import com.sample.Cheese + +global List cheeses + +function void exampleFunction(Cheese cheese) { + System.out.println( cheese ); +} + +rule “A Cheesey Rule” + when + cheese : Cheese( type == "stilton" ) + then + exampleFunction( cheese ); + cheeses.add( cheese ); +end</programlisting> + + <para> The following example shows a LHS with a single Column that has a + single <indexterm> + <primary>Literal Field Constraint</primary> + </indexterm>Literal Field Constraint used with a Cheese Fact:</para> + + <programlisting>rule "Cheddar Cheese" + when + Cheese( type == "cheddar" ) + then + System.out.println( "cheddar" ); +end</programlisting> + + <para>The example above is analogous to :</para> + + <programlisting>public void cheddarCheese(Cheese cheese) { + if ( cheese.getType().equals("cheddar") { + System.out.println( "cheddar" ); + } +}</programlisting> + + <para>Rule engines are a complete de-coupling of data from the logic. + Rules cannot be called directly as they are not methods or functions + instead Rules fire in response to changes in Working Memory's data.</para> + </section> + + <section> + <title>First Order Logic</title> + + <para>Rules are written using First Order Logic, or predicate logic, which + extends Propositional Logic. <ulink + url="http://en.wikipedia.org/wiki/Emil_Leon_Post">Emil Leon Post</ulink> + was the first to develop an inference based system using symbols to + express logic - as a consequence of this he was able to prove that any + logical system (including mathematics) could be expressed with such a + system.</para> + + <para>A proposition is a statement that can be classified as true or + false. If the truth can be determined from statement alone it is said to + be a "closed statement". In programming terms this is an expression that + does not reference any variables:</para> + + <para>10 = = 2 * 5</para> + + <para>Expressions that evaluate against one or more variables, facts, are + "open statements", in that we cannot determine whether the statement is + true until we have a variable instance to evaluate against:</para> + + <para>Person.sex == "male"</para> + + <para>With SQL if we look at the conclusion's action as simply returning + the matched fact to the user:</para> + + <para>select * from People where People.sex == "male"</para> + + <para>For any rows, which represent our facts, that are returned we have + inferred that those facts are male people. The following diagram shows how + the above SQL statement and People table can be represented in terms of an + Inference Engine.</para> + + <figure> + <title>SQL as a simplistic Inference Engine</title> + + <mediaobject> + <imageobject> + <imagedata align="center" fileref="Male_People.svg" format="SVG" /> + </imageobject> + + <imageobject> + <imagedata align="center" fileref="Male_People.png" format="PNG" /> + </imageobject> + </mediaobject> + </figure> + + <para>So in java we can say that a simple proposition is of the form + 'variable' 'operator' 'value' - where we often refer to 'value' as being a + literal value - a proposition can be thought as a field constraint. + Further to this propositions can be combined with conjuntive and + disjuntive connectives, which is the logic theorists way of saying + '&&' and '||'. The following shows two open propositional + statements connected together with a single disjunctive connective.</para> + + <programlisting>person.getEyeColor().equals("blue") || person.getEyeColor().equals("green") </programlisting> + + <para>This can be expressed using a disjunctive Conditional Element + connective - which actually results in the generation of two rules, to + represent the two possible logic outcomes.</para> + + <programlisting>Person( eyeColour == "blue" ) || Person( eyeColor == "green" )</programlisting> + + <para>Disjunctive field constraints connectives could also be used - + although they are not currently supported in Drools 3.0 - and would not + result in multiple rule generation.</para> + + <programlisting>Person( eyeColour == "blue"||"green" )</programlisting> + + <para>However Propositional Logic is not Turing complete in that you are + limited to the problems you can define because it cannot express criteria + for the structure of data. First Order Logic (FOL), or Predicate Logic, + extends Propositional Logic with two new quantifier concepts to allow + expressions defining structure - specifically universal and existential + quantifiers. Universal quantifiers allow you to check that something is + true for everything; normally supported by the 'forall' conditional + element, but not yet implemented in Drools 3.0. Existential quantifiers + check for the existence of something, in that it occurs at least once - + this is supported with 'not' and 'exists' conditional elements.</para> + + <para>Imagine we have two classes - Student and Module. Module represents + each of the courses the Student attended for that semester, referenced by + the List collection. At the end of the semester each Module has a score. + If the Student has a Module score below 40 then they will fail that + semester - the existential quantifier can be used used with the "less than + 40" open proposition to check for the existence of a Module that is true + for the specified criteria.</para> + + <programlisting>public class Student { + private String name; + private List modules; + + ... +}</programlisting> + + <programlisting>public Class Module { + private String name; + private String studentName; + private int score;</programlisting> + + <para>Java is Turing complete in that you can write code, among other + things, to iterate data structures to check for existence. The following + should return a List of students who have failed the semester.</para> + + <programlisting>List failedStudents = new ArrayList(); + +for ( Iterator studentIter = students.iterator(); studentIter.hasNext() { + Student student = ( Student ) studentIter.next(); + for ( Iterator it = student.getModules.iterator(); it.hasNext(); ) { + Module module = ( Module ) it.next(); + if ( module.getScore() < 40 ) { + failedStudents.add( student ) ; + break; + } + } +}</programlisting> + + <para>Early SQL implementations where not Turing complete as they did not + provide quantifiers to asses the structure of data. However modern SQL + engines allow nesting of SQL which can be combined with keywords like + 'exists' and 'in': The following query would return a set of Students who + have failed the semester.</para> + + <programlisting>select + * +from + Students s +where exists ( + select + * + from + Modules m + where + m.student_name = s.name and + m.score < 40 +)</programlisting> + + <programlisting>rule + when + exists( $student : Student() && Module( student == $student, score < 40 ) )</programlisting> + + <para></para> + </section> +</section> \ No newline at end of file Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-What_is_a_Rule_Engine.xml =================================================================== --- labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-What_is_a_Rule_Engine.xml 2006-05-19 01:11:06 UTC (rev 4323) +++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Engine/Section-What_is_a_Rule_Engine.xml 2006-05-19 09:16:42 UTC (rev 4324) @@ -3,119 +3,64 @@ <title>What is a Rule Engine</title> <section> - <title>Background</title> + <title>Introduction and Background</title> - <para>A rule engine like Drools is centred around the concept of - production rules (IF conditions THEN actions). Emil Leon Post - (http://en.wikipedia.org/wiki/Emil_Leon_Post) was the first to use - production systems in logic - as a consequence of this he was able to - prove that any logical system (including mathematics) could be written - with production rules. Quite an amazing proof, this essentially means that - you can represent any system/problem with production rules (back in the - real world there are constraints of processing power and efficiency of - course !).</para> + <para>Artificial Intelligence (A.I.) is a very broad research area that + focuses on "Making computers think like people" and includes disciplines + like Neural Networks, Genetic Algorithms, Decision Trees, Frame Systems + and Expert Systems. Knowledge representation is the area of A.I. concerned + with how knowledge is represented and manipulated. Expert Systems use + Knowledge representation to facilitate the codification of knowledge into + a knowledge base which can be used for reasoning - i.e. we can process + data with this knowledge base to infer conclusions. Expert Systems are + also known as Knowledge-based Systems and Knowledge-based Expert System + and are considered 'applied artificial intelligence'; the process of + developing with an Expert System is Knowledge Engineering. EMYCIN was one + of the first "shells" for an Expert System, which was created from the + MYCIN medical diagnosis Expert System. Where early Expert Systems had + their logic hard coded "shells" separated the logic from the system, + providing an easy to use environment for user input. Drools is a Rule + Engine that uses the Rule Based approached to implement an Expert System + and is more correctly classified as a Production Rules System.</para> - <para>You may also have heard of "Expert Systems" in the context of rule - engines. You can think of expert systems as a rule engine + the - codification of knowledge for a specific problem domain (+ a user - interface !). In that sense, Drools is a platform for expert systems. - Historically, rule engines popularity grew out of expert systems success - (for example, EMYCIN was one of the first "shells" for an expert system, - which was created from the MYCIN medical diagnosis expert system).</para> - </section> + <para>Business Rule Management Systems build value on top of an Rule + Engine providing systems for rule management, deployment, collaboration, + analysis and end user tools for business users. Further to this the + "Business Rules Approach" is a fast evolving and popular methodology + helping to formalise the role of Rule Engines in the enterprise.</para> - <section> - <title>Rules</title> + <para>The term Rule Engine is quite ambiguous in that it can be any system + that uses rules, in any form, that can be applied to data to produce + outcomes; which includes simple systems like form validation; "How to + Build a Business Rules Engine (2004)" by Malcolm Chisholm exemplifies this + ambiguity. The book is actually about how to build and alter a database + schema to hold validation rules which it then shows how to generate VB + code from those validation rules to validate data entry - while a very + valid and usefil topic for some some, it caused quite a suprise to this + author, unaware at the time in the subtleties of Rules Engines + differences, who was hoping to find some hidden secrets to help improve + the Drools engine. While a Production Rule System is a kinda of Rule + Engine and also Expert System, the validation Rule Engine mention + previously obviously isn't an Expert System.</para> - <para>A <indexterm> - <primary>Rule</primary> - </indexterm>Rule is the codification of business knowledge. A Rule has - attributes, a Left Hand Side (LHS) and a Right Hand Side (RHS). Drools - allows the following attributes:</para> + <para>The brain of a Production Rule System is an Inference Engine which + matches facts, the data, against Production Rules, also called + Productions, to infer conclusions which result in actions. A Production + Rule is a two-part structure using First Order Logic for knowledge + representation.</para> - <itemizedlist> - <listitem> - <para>salience</para> - </listitem> + <programlisting>when + <conditions> +then + <actions></programlisting> - <listitem> - <para>agenda-group</para> - </listitem> - - <listitem> - <para>no-loop</para> - </listitem> - - <listitem> - <para>auto-focus</para> - </listitem> - - <listitem> - <para>duration</para> - </listitem> - </itemizedlist> - - <programlisting>rule “<name>” - <attribute> <value> - when - <LHS> - then - <RHS> -end -</programlisting> - - <para>The LHS of the Rule consists of one or more Conditions. As the Rule - Engine is made aware of new data or changes to existing data it matches - the data against the Conditions, when all the Conditions are met and true - the RHS, and its actions, are executed; the RHS, called the <indexterm> - <primary>Consequence</primary> - </indexterm>Consequence. The LHS and the RHS is analogous to:</para> - - <programlisting>if ( <LHS> ) { - <RHS> -}</programlisting> - - <para>Rules are associated with a namespace via the - <literal>package</literal> keyword; other Rule Engines may call this a - <indexterm> - <primary>Rule Set</primary> - </indexterm>Rule Set. A Package declares imports, global variables, - functions and rules.</para> - - <programlisting>package com.sample - -import java.util.List -import com.sample.Cheese - -global List cheeses - -function void exampleFunction(Cheese cheese) { - System.out.println( cheese ); -} - -rule “A Cheesy Rule” - when - cheese : Cheese( type == "stilton" ) - then - exampleFunction( cheese ); - cheeses.add( cheese ); -end</programlisting> - - <para>The process of matching the new or existing modified data against - rules is called <indexterm> + <para>The process of matching the new or existing facts against Production + Rules is called <indexterm> <primary>Pattern Matching</primary> - </indexterm> Pattern Matching, the engine which does this matching is - the <indexterm> + </indexterm> Pattern Matching, which is performed by the <indexterm> <primary>Inference Engine</primary> - </indexterm>Inference Engine. The Rule's are referred to as the - <indexterm> - <primary>Production Memory</primary> - </indexterm>Production Memory and the data that the Inference Engine - matches against is the <indexterm> - <primary>WorkingMemory</primary> - </indexterm>Working Memory. the Agenda manages the execution of the - matched Rules. There are a number of algorithms used for Pattern Matching - by Inference Engines including:</para> + </indexterm>Inference Engine. There are a number of algorithms used for + Pattern Matching by Inference Engines including:</para> <itemizedlist> <listitem> @@ -135,14 +80,34 @@ </listitem> </itemizedlist> - <para>Drools has implementations for both Rete and Leaps; Leaps is still - considered experiment. The Drools <indexterm> + <para>Drools has implementations for both <indexterm> <primary>Rete</primary> - </indexterm>Rete implementation is called ReteOO signifying that this - Drools has an enhanced and optimised implementation of the Rete algorithm. - Other Rete based engines also have marketting terms for their prioprietary - enhancements to Rete, like RetePlus and Rete III,</para> + </indexterm>Rete and <indexterm> + <primary>Leaps</primary> + </indexterm>Leaps; Leaps is still considered experiment. The Drools + <indexterm> + <primary>Rete</primary> + </indexterm>Rete implementation is called ReteOO signifying that Drools + has an enhanced and optimised implementation of the Rete algorithm. Other + Rete based engines also have marketing terms for their proprietary + enhancements to Rete, like RetePlus and Rete III. It is important to + understand that names like Rete III are purely marketing where, unlike the + original published Rete Algorithm, no details of implementation are + published; thus asking a question like "Does Drools implement Rete III" is + nonsensical.</para> + <para>The Production Rules are referred to as the <indexterm> + <primary>Production Memory</primary> + </indexterm>Production Memory and the facts that the Inference Engine + matches against the <indexterm> + <primary>WorkingMemory</primary> + </indexterm>Working Memory. Facts are asserted into the Working Memory + where they may then be modiied or retracted. A system with a large number + of rules and facts may result in many rules being true for the same fact + assertion, these rules are said to be in conflict. The Agenda manages the + execution order of these conflicuting rules using a Conflict Resolution + stategy. </para> + <figure> <title>A Basic Rete network</title> @@ -157,145 +122,39 @@ </mediaobject> </figure> - <para>The LHS of a rule is made up of <indexterm> - <primary>Conditional Element</primary> - </indexterm>iConditional Elements and <indexterm> - <primary>Field Constraint</primary> - </indexterm>iField Constraints. The following example shows a <indexterm> - <primary>Literal Field Constraint</primary> - </indexterm>iLiteral Field Constraint used with a Cheese Fact; the - combination of Field Constraints on a Fact is known as a <indexterm> - <primary>Column</primary> - </indexterm>Column.</para> + <para>A Production Rule System's Inference Engine is stateful and able to + enforce truthfulness - called Truth Maintence. A logical relationship can + be declared by actions which means the action's state depends on the + inference remaining true; when it is no longer true the logical dependant + action is undone. The "Honest Politician" is an example of Truth + Maintenance, which always ensures that hope can only exist for a + decomcracy while we have honest politicians.</para> - <programlisting>rule "Cheddar Cheese" - when - Cheese( type == "cheddar" ) - then - System.out.println( "cheddar" ); -end</programlisting> + <programlisting>when + an honest Politician exists +then + logically assert Hope - <para>The example above is similar to :</para> +when + Hope exists +then + print "Hurrah!!! Democracy Lives" - <programlisting>public void cheddarCheese(Cheese cheese) { - if ( cheese.getType().equals("cheddar") { - System.out.println( "cheddar" ); - } -}</programlisting> +when + Hope does not exist +then + print "Democracy is Doomed" +</programlisting> - <para>Rule engines are a complete de-coupling of data from the logic. - Rules cannot be called directly as they are not methods or functions - instead Rules fire in response to changes in Working Memory's data, It may - help to think of this de-coupling as a specialised event sytem. The - Consequence is the Listener to the full matching of the LHS events.</para> - - <para>Rule Engines are much like a database where Rule's LHS define the - queries on the Working Memory. The previous rule can be expressed in - <indexterm> - <primary>SQL</primary> - </indexterm>SQL as:</para> - - <programlisting> select * from Cheese where type == "cheddar"</programlisting> - - <para>A <indexterm> - <primary>DataBase</primary> - </indexterm>Database executes SQL, on request, where as a Rule Engine - will process data against its rules, its Production Memory, as it's - asserted; this process is known as <indexterm> - <primary>Pattern Matching</primary> - </indexterm>Pattern Matching. When added to the Production Memory, - Rule's are decomposed into a graph using the <indexterm> - <primary>Rete</primary> - </indexterm>Rete algorithm. Rete is one of the standard Rule Engine - algorithms developed by <indexterm> - <primary>Charles Forgey</primary> - </indexterm>Charles Forgey in 1979 which is covered in greater detail in - a Rete Algorithm chapter.</para> - - <figure> - <title>A Basic Rete network</title> - - <mediaobject> - <imageobject> - <imagedata align="center" fileref="A_Basic_Rete_Network.svg" - format="SVG" /> - </imageobject> - - <imageobject> - <imagedata align="center" fileref="A_Basic_Rete_Network.png" - format="PNG" /> - </imageobject> - </mediaobject> - </figure> - - <para>Each Fact type in our Working Memory, such as <code>Cheese</code>, - is represented by an <indexterm> - <primary>Object Type</primary> - </indexterm>Object Type class, shown as the root node in our graph. When - Facts are asserted into the Working Memory the Rule Engine finds the - matching Object Type node and propagates the asserted Fact onto the next - node. The Object Type node maintains a memory of all matched Facts. in our - example the next node in the graph is a <indexterm> - <primary>Field Constraint</primary> - </indexterm>Field Constraint, <code>type == "cheddar", </code>its job is - to filter Facts using the given constraint; if the type of - <code>Cheese</code> is not "cheddar" the Fact progresses no further in the - network, if it is "cheddar" it is rememebered in the <indexterm> - <primary>Alpha Node</primary> - </indexterm>Alpha Node's memory and propagated onto the next node in the - network.. Alpha Node is classic Rete terminology for single input/single - output nodes, in that it receives a single Fact of a specified Object Type - and propates a single Fact of specified Object Type.</para> - - <para>At this point we have what is known as a <indexterm> - <primary>Partial Match</primary> - </indexterm>Partial Match, in that we have matched facts against some, - but not all, of the Rule's nodes. <indexterm> - <primary>Left Input Adapter Node</primary> - </indexterm>s will be explained later, suffice to say it always - propagetes onto the next node, in this case a <indexterm> - <primary>Terminal Node</primary> - </indexterm>Terminal Node. The Terminal Node is our end node, now we say - the Rule is Fully Matched and ready to fire.</para> - - <para>Earlier we mentioned that a Rule Engine is much like a Database, we - can prove this by using a <indexterm> - <primary>Query</primary> - </indexterm>Query construct. A Query is Rule with a special Terminal - node; instead of executing a Consequence the Terminal node stores matching - Facts in a list, which is returned as the result. Lets prove this</para> - - <programlisting>query "Find cheeses with a cost of 5" - Cheese( price == 5 ) -end</programlisting> - - <programlisting>// First create the facts -Cheese stilton = new Cheese("stilton", 8); // type, price -Cheese cheddar = new Cheese("cheddar", 5); // type, price -Cheese mozarella = new Cheese("mozarella", 5); // type, price - -// Now assert them into the Working Memory -workingMemory.assertObject( stilton ); -workingMemory.assertObject( cheddar ); -workingMemory.assertObject( mozarella ); - -List results = workingMemory.getQueryResults( "Find cheeses with a cost of 5" );</programlisting> - - <para>When we get the Query Results the List has a size of two and - references "cheddar" and "mozarella", as expected. If we had used a Rule - construct instead of a Query the Terminal Node's Consequence would have - attempted to fire twice, once for "cheddar" and once for - "mozarella".</para> - - <para>When a Rule is Fully Matched it does not fire immediately (in Rete, - but in Leaps it does !). Instead the Rule plus the matched Facts are - <indexterm> - <primary>Activated</primary> - </indexterm>Activated placed onto the <indexterm> - <primary>Agenda</primary> - </indexterm>Agenda; which is responsible for the scheduling and firing - <indexterm> - <primary>Activation</primary> - </indexterm>Activations.</para> + <para>There are two general approaches to Rule Engines implementation - + forward chaing and backward chaining. Forward chaing is 'data-driven' and + thus reactionary - facts are asserted into the working memory which + results in rules firing - we start with a fact, it propagates and we end + in a conclusion. Drools is a forward chaining engine. Backward chaining is + 'goal-driven', we start with a conclusion which the engine tries to + satisfy. If it can't it searches for conclusions, 'sub goals', that helps + satisfy an unknown part fo the current goal - it continues this process + untill either the initial conclusion is proven or there are no more sub + goals.</para> </section> </section> \ No newline at end of file Modified: labs/jbossrules/trunk/documentation/manual/en/master.xml =================================================================== --- labs/jbossrules/trunk/documentation/manual/en/master.xml 2006-05-19 01:11:06 UTC (rev 4323) +++ labs/jbossrules/trunk/documentation/manual/en/master.xml 2006-05-19 09:16:42 UTC (rev 4324) @@ -58,6 +58,8 @@ <xi:include href="Chapter-Rule_Engine/Section-Why_use_a_Rule_Engine.xml" /> + <xi:include href="Chapter-Rule_Engine/Section-Rules.xml" /> + <xi:include href="Chapter-Rule_Engine/Section-Rete_Algorithm.xml" /> <xi:include href="Chapter-Rule_Engine/Section-Leaps_Algorithm.xml" /> |