[jboss-svn-commits] JBL Code SVN: r13715 - in labs/jbossrules/trunk/documentation/manual/en: Chapter-Rule_Language and 1 other directory.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Sun Jul 22 18:15:44 EDT 2007
Author: tirelli
Date: 2007-07-22 18:15:43 -0400 (Sun, 22 Jul 2007)
New Revision: 13715
Removed:
labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Language/Section-Advanced-CEs.xml
Modified:
labs/jbossrules/trunk/documentation/manual/en/master.xml
Log:
Removing section that was merged into the ce section
Deleted: labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Language/Section-Advanced-CEs.xml
===================================================================
--- labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Language/Section-Advanced-CEs.xml 2007-07-22 22:10:00 UTC (rev 13714)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Rule_Language/Section-Advanced-CEs.xml 2007-07-22 22:15:43 UTC (rev 13715)
@@ -1,588 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<section>
- <title>Advanced Conditional Elements</title>
-
- <note>
- <para><replaceable>(updated to Drools 4.0)</replaceable></para>
- </note>
-
- <para>Drools 4.0 introduces a whole new set of conditional elements in order
- to support full First Order Logic expressiveness, as well as some facilities
- for handling collections of facts. This section will detail the following
- new Conditional Elements:</para>
-
- <itemizedlist>
- <listitem>
- <para>from</para>
- </listitem>
-
- <listitem>
- <para>collect</para>
- </listitem>
-
- <listitem>
- <para>accumulate</para>
- </listitem>
-
- <listitem>
- <para>forall</para>
- </listitem>
- </itemizedlist>
-
- <section>
- <title>From</title>
-
- <figure>
- <title>from</title>
-
- <mediaobject>
- <imageobject>
- <imagedata align="center" fileref="from.svg" format="SVG" />
- </imageobject>
-
- <imageobject>
- <imagedata align="center" fileref="from.png" format="PNG" />
- </imageobject>
- </mediaobject>
- </figure>
-
- <para>The <emphasis role="bold">from</emphasis> Conditional Element allows
- users to specify a source for patterns to reason over. This allows the
- engine to reason over data not in the Working Memory. This could be a
- sub-field on a bound variable or the results of a method call. It is a
- powerful construction that allows out of the box integration with other
- application components and frameworks. One common example is the
- integration with data retrieved on-demand from databases using hibernate
- named queries.</para>
-
- <para>The expression used to define the object source is any expression
- that follows regular MVEL syntax. I.e., it allows you to easily use object
- property navigation, execute method calls and access maps and collections
- elements.</para>
-
- <para>Here is a simple example of reasoning and binding on another pattern
- sub-field:</para>
-
- <para><programlisting>rule "validate zipcode"
-when
- Person( $personAddress : address )
- Address( zipcode == "23920W") from $personAddress
-then
- # zip code is ok
-end
-</programlisting></para>
-
- <para>With all the flexibility from the new expressiveness in the Drools
- engine you can slice and dice this problem many ways. This is the same but
- shows how you can use a graph notation with the 'from':</para>
-
- <para><programlisting>rule "validate zipcode"
-when
- $p : Person( )
- $a : Address( zipcode == "23920W") from $p.address
-then
- # zip code is ok
-end
-</programlisting></para>
-
- <para>Previous examples were reasoning over a single pattern. The
- <emphasis role="bold">from</emphasis> CE also support object sources that
- return a collection of objects. In that case, <emphasis
- role="bold">from</emphasis> will iterate over all objects in the
- collection and try to match each of them individually. For instance, if we
- want a rule that applies 10% discount to each item in an order, we could
- do:</para>
-
- <programlisting>rule "apply 10% discount to all items over US$ 100,00 in an order"
-when
- $order : Order()
- $item : OrderItem( value > 100 ) from $order.items
-then
- # apply discount to $item
-end
-</programlisting>
-
- <para>The above example will cause the rule to fire once for each item
- whose value is greater than 100 for each given order.</para>
-
- <para>The next example shows how we can reason over the results of a
- hibernate query. The Restaurant pattern will reason over and bind with
- each result in turn:</para>
- </section>
-
- <section>
- <title>Collect</title>
-
- <figure>
- <title>collect</title>
-
- <mediaobject>
- <imageobject>
- <imagedata align="center" fileref="collect.svg" format="SVG" />
- </imageobject>
-
- <imageobject>
- <imagedata align="center" fileref="collect.png" format="PNG" />
- </imageobject>
- </mediaobject>
- </figure>
-
- <para>The <emphasis role="bold">collect</emphasis> Conditional Element
- allows rules to reason over collection of objects collected from the given
- source or from the working memory. A simple example:</para>
-
- <programlisting>import java.util.ArrayList
-
-rule "Raise priority if system has more than 3 pending alarms"
-when
- $system : System()
- $alarms : ArrayList( size >= 3 )
- from collect( Alarm( system == $system, status == 'pending' ) )
-then
- # Raise priority, because system $system has
- # 3 or more alarms pending. The pending alarms
- # are $alarms.
-end
-</programlisting>
-
- <para>In the above example, the rule will look for all pending alarms in
- the working memory for each given system and group them in ArrayLists. If
- 3 or more alarms are found for a given system, the rule will fire.</para>
-
- <para>The <emphasis role="bold">collect</emphasis> CE result pattern can
- be any concrete class that implements tha java.util.Collection interface
- and provides a default no-arg public constructor. I.e., you can use
- default java collections like ArrayList, LinkedList, HashSet, etc, or your
- own class, as long as it implements the java.util.Collection interface and
- provide a default no-arg public constructor.</para>
-
- <para>Both source and result patterns can be constrained as any other
- pattern.</para>
-
- <para>Variables bound before the <emphasis role="bold">collect</emphasis>
- CE are in the scope of both source and result patterns and as so, you can
- use them to constrain both your source and result patterns. Although, the
- <emphasis>collect( ... )</emphasis> is a scope delimiter for bindings,
- meaning that any binding made inside of it, is not available for use
- outside of it.</para>
-
- <para>Collect accepts nested <emphasis role="bold">from</emphasis>
- elements, so the following example is a valid use of <emphasis
- role="bold">collect</emphasis>:</para>
-
- <programlisting>import java.util.LinkedList;
-
-rule "Send a message to all mothers"
-when
- $town : Town( name == 'Paris' )
- $mothers : LinkedList()
- from collect( Person( gender == 'F', children > 0 )
- from $town.getPeople()
- )
-then
- # send a message to all mothers
-end
-</programlisting>
- </section>
-
- <section>
- <title>Accumulate</title>
-
- <figure>
- <title>accumulate</title>
-
- <mediaobject>
- <imageobject>
- <imagedata align="center" fileref="accumulate.svg" format="SVG" />
- </imageobject>
-
- <imageobject>
- <imagedata align="center" fileref="accumulate.png" format="PNG" />
- </imageobject>
- </mediaobject>
- </figure>
-
- <para>The <emphasis role="bold">accumulate</emphasis> Conditional Element
- is a more flexible and powerful form of <emphasis
- role="bold">collect</emphasis> Conditional Element, in the sense that it
- can be used to do what <emphasis role="bold">collect</emphasis> CE does
- and also do things that <emphasis role="bold">collect</emphasis> CE is not
- capable to do. Basically what it does is it allows a rule to iterate over
- a collection of objects, executing custom actions for each of the
- elements, and at the end return a result object.</para>
-
- <para>The general syntax of the <emphasis
- role="bold">accumulate</emphasis> CE is:</para>
-
- <programlisting><replaceable><result pattern></replaceable> from accumulate( <replaceable><source pattern></replaceable>,
- init( <replaceable><init code></replaceable> ),
- action( <replaceable><action code></replaceable> ),
- reverse( <replaceable><reverse code></replaceable> ),
- result( <replaceable><result expression></replaceable> ) )
-</programlisting>
-
- <para>The meaning of each of the elements is the following:</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis role="bold"><source pattern></emphasis>: the
- source pattern is a regular pattern that the engine will try to match
- against each of the source objects.</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold"><init code></emphasis>: this is a
- semantic block of code in the selected dialect that will be executed
- once for each tuple, before iterating over the source objects.</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold"><action code></emphasis>: this is a
- semantic block of code in the selected dialect that will be executed
- for each of the source objects.</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold"><reverse code></emphasis>: this is
- an optional semantic block of code in the selected dialect that if
- present will be executed for each source object that no longer matches
- the source pattern. The objective of this code block is to "undo" any
- calculation done in the <action code> block, so that the engine
- can do decremental calculation when a source object is modified or
- retracted, hugely improving performance of these operations.</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold"><result expression></emphasis>: this
- is a semantic expression in the selected dialect that is executed
- after all source objects are iterated.</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold"><result pattern></emphasis>: this is
- a regular pattern that the engine tries to match against the object
- returned from the <result expression>. If it matches, the
- <emphasis role="bold">accumulate</emphasis> conditional element
- evaluates to <emphasis role="bold">true</emphasis> and the engine
- proceeds with the evaluation of the next CE in the rule. If it does
- not matches, the <emphasis role="bold">accumulate</emphasis> CE
- evaluates to <emphasis role="bold">false</emphasis> and the engine
- stops evaluating CEs for that rule.</para>
- </listitem>
- </itemizedlist>
-
- <para>It is easier to understand if we look at an example:</para>
-
- <programlisting>rule "Apply 10% discount to orders over US$ 100,00"
-when
- $order : Order()
- $total : Number( doubleValue > 100 )
- from accumulate( OrderItem( order == $order, $value : value ),
- init( double total = 0; ),
- action( total += $value; ),
- reverse( total -= $value; ),
- result( total ) )
-then
- # apply discount to $order
-end
-</programlisting>
-
- <para>In the above example, for each Order() in the working memory, the
- engine will execute the <emphasis role="bold">init code</emphasis>
- initializing the total variable to zero. Then it will iterate over all
- OrderItem() objects for that order, executing the <emphasis
- role="bold">action</emphasis> for each one (in the example, it will sum
- the value of all items into the total variable). After iterating over all
- OrderItem, it will return the value corresponding to the <emphasis
- role="bold">result expression</emphasis> (in the above example, the value
- of the total variable). Finally, the engine will try to match the result
- with the Number() pattern and if the double value is greater than 100, the
- rule will fire.</para>
-
- <para>The example used java as the semantic dialect, and as such, note
- that the usage of ';' is mandatory in the init, action and reverse code
- blocks. The result is an expression and as such, it does not admit ';'. If
- the user uses any other dialect, he must comply to that dialect specific
- syntax.</para>
-
- <para>As mentioned before, the <emphasis role="bold">reverse
- code</emphasis> is optional, but it is strongly recommended that the user
- writes it in order to benefit from the <emphasis>improved performance on
- update and retracts</emphasis>.</para>
-
- <para>The <emphasis role="bold">accumulate</emphasis> CE can be used to
- execute any action on source objects. The following example instantiates
- and populates a custom object:</para>
-
- <programlisting>rule "Accumulate using custom objects"
-when
- $person : Person( $likes : likes )
- $cheesery : Cheesery( totalAmount > 100 )
- from accumulate( $cheese : Cheese( type == $likes ),
- init( Cheesery cheesery = new Cheesery(); ),
- action( cheesery.addCheese( $cheese ); ),
- reverse( cheesery.removeCheese( $cheese ); ),
- result( cheesery ) );
-then
- // do something
-end</programlisting>
-
- <section>
- <title>Accumulate Functions</title>
-
- <para>The accumulate CE is a very powerful CE, but it gets real
- declarative and easy to use when using predefined functions that are
- known as Accumulate Functions. They work exactly like accumulate, but
- instead of explicitly writing custom code in every accumulate CE, the
- user can use predefined code for common operations.</para>
-
- <para>For instance, the rule to apply discount on orders written in the
- previous section, could be written in the following way, using
- Accumulate Functions:</para>
-
- <programlisting>rule "Apply 10% discount to orders over US$ 100,00"
-when
- $order : Order()
- $total : Number( doubleValue > 100 )
- from accumulate( OrderItem( order == $order, $value : value ),
- sum( $value ) )
-then
- # apply discount to $order
-end
-</programlisting>
-
- <para>In the above example, sum is an AccumulateFunction and will sum
- the $value of all OrderItems and return the result.</para>
-
- <para>Drools 4.0 ships with the following built in accumulate
- functions:</para>
-
- <itemizedlist>
- <listitem>
- <para>average</para>
- </listitem>
-
- <listitem>
- <para>min</para>
- </listitem>
-
- <listitem>
- <para>max</para>
- </listitem>
-
- <listitem>
- <para>count</para>
- </listitem>
-
- <listitem>
- <para>sum</para>
- </listitem>
- </itemizedlist>
-
- <para>These common functions accept any expression as input. For
- instance, if someone wants to calculate the average profit on all items
- of an order, a rule could be written using the average function:</para>
-
- <programlisting>rule "Average profit"
-when
- $order : Order()
- $profit : Number()
- from accumulate( OrderItem( order == $order, $cost : cost, $price : price )
- average( 1 - $cost / $price ) )
-then
- # average profit for $order is $profit
-end
-</programlisting>
-
- <para>Accumulate Functions are all pluggable. That means that if needed,
- custom, domain specific functions can easily be added to the engine and
- rules can start to use them without any restrictions. To implement a new
- Accumulate Functions all one needs to do is to create a java class that
- implements the org.drools.base.acumulators.AccumulateFunction interface
- and add a line to the configuration file or set a system property to let
- the engine know about the new function. As an example of an Accumulate
- Function implementation, the following is the implementation of the
- "average" function:</para>
-
- <programlisting>/*
- * Copyright 2007 JBoss Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Created on Jun 21, 2007
- */
-package org.drools.base.accumulators;
-
-
-/**
- * An implementation of an accumulator capable of calculating average values
- *
- * @author etirelli
- *
- */
-public class AverageAccumulateFunction implements AccumulateFunction {
-
- protected static class AverageData {
- public int count = 0;
- public double total = 0;
- }
-
- /* (non-Javadoc)
- * @see org.drools.base.accumulators.AccumulateFunction#createContext()
- */
- public Object createContext() {
- return new AverageData();
- }
-
- /* (non-Javadoc)
- * @see org.drools.base.accumulators.AccumulateFunction#init(java.lang.Object)
- */
- public void init(Object context) throws Exception {
- AverageData data = (AverageData) context;
- data.count = 0;
- data.total = 0;
- }
-
- /* (non-Javadoc)
- * @see org.drools.base.accumulators.AccumulateFunction#accumulate(java.lang.Object, java.lang.Object)
- */
- public void accumulate(Object context,
- Object value) {
- AverageData data = (AverageData) context;
- data.count++;
- data.total += ((Number) value).doubleValue();
- }
-
- /* (non-Javadoc)
- * @see org.drools.base.accumulators.AccumulateFunction#reverse(java.lang.Object, java.lang.Object)
- */
- public void reverse(Object context,
- Object value) throws Exception {
- AverageData data = (AverageData) context;
- data.count--;
- data.total -= ((Number) value).doubleValue();
- }
-
- /* (non-Javadoc)
- * @see org.drools.base.accumulators.AccumulateFunction#getResult(java.lang.Object)
- */
- public Object getResult(Object context) throws Exception {
- AverageData data = (AverageData) context;
- return new Double( data.count == 0 ? 0 : data.total / data.count );
- }
-
- /* (non-Javadoc)
- * @see org.drools.base.accumulators.AccumulateFunction#supportsReverse()
- */
- public boolean supportsReverse() {
- return true;
- }
-
-}
-</programlisting>
-
- <para>The code for the function is very simple, as we could expect, as
- all the "dirty" integration work is done by the engine. Finally, to plug
- the function into the engine, we added it to the configuration
- file:</para>
-
- <programlisting>drools.accumulate.function.average = org.drools.base.accumulators.AverageAccumulateFunction
-</programlisting>
-
- <para>Where "drools.accumulate.function." is a prefix that must always
- be used, "average" is how the function will be used in the rule file,
- and "org.drools.base.accumulators.AverageAccumulateFunction" is the
- fully qualified name of the class that implements the function
- behavior.</para>
- </section>
- </section>
-
- <section>
- <title>Forall</title>
-
- <figure>
- <title>forall</title>
-
- <mediaobject>
- <imageobject>
- <imagedata align="center" fileref="forall.svg" format="SVG" />
- </imageobject>
-
- <imageobject>
- <imagedata align="center" fileref="forall.png" format="PNG" />
- </imageobject>
- </mediaobject>
- </figure>
-
- <para><emphasis role="bold">Forall</emphasis> is the Conditional Element
- that completes the First Order Logic support in Drools. The syntax is very
- simple:</para>
-
- <programlisting>forall( <replaceable><select pattern></replaceable> <replaceable><constraint patterns></replaceable> )</programlisting>
-
- <para>The <emphasis role="bold">forall</emphasis> Conditional Element will
- evaluate to true when all facts that match the <replaceable><select
- pattern></replaceable> match all the <replaceable><constraint
- patterns></replaceable>. Example:</para>
-
- <programlisting>rule "All english buses are red"
-when
- forall( $bus : Bus( type == 'english')
- Bus( this == $bus, color = 'red' ) )
-then
- # all english buses are red
-end
-</programlisting>
-
- <para>In the above rule, we "select" all Bus object whose type is
- "english". Then, for each fact that matchs this pattern we evaluate the
- following patterns and if they match, the forall CE will evaluate to true.
- Another example:</para>
-
- <programlisting>rule "all employees have health and dental care programs"
-when
- forall( $emp : Employee()
- HealthCare( employee == $emp )
- DentalCare( employee == $emp )
- )
-then
- # all employees have health and dental care
-end
-</programlisting>
-
- <para>Forall can be nested inside other CEs for complete expressiveness.
- For instance, <emphasis role="bold">forall</emphasis> can be used inside a
- <emphasis role="bold">not</emphasis> CE:</para>
-
- <programlisting>rule "not all employees have health and dental care"
-when
- not forall( $emp : Employee()
- HealthCare( employee == $emp )
- DentalCare( employee == $emp )
- )
-then
- # not all employees have health and dental care
-end
-</programlisting>
-
- <para>As a side note, forall Conditional Element is equivalent to
- writing:</para>
-
- <programlisting>not( <replaceable><select pattern></replaceable> and not ( and <replaceable><constraint patterns></replaceable> ) )</programlisting>
-
- <para>Also, it is important to note that <emphasis role="bold">forall is a
- scope delimiter</emphasis>, so it can use any previously bound variable,
- but no variable bound inside it will be available to use outside of
- it.</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 2007-07-22 22:10:00 UTC (rev 13714)
+++ labs/jbossrules/trunk/documentation/manual/en/master.xml 2007-07-22 22:15:43 UTC (rev 13715)
@@ -113,8 +113,6 @@
<xi:include href="Chapter-Rule_Language/Section-Rule.xml" />
- <xi:include href="Chapter-Rule_Language/Section-Advanced-CEs.xml" />
-
<xi:include href="Chapter-Rule_Language/Section-Query.xml" />
<xi:include href="Chapter-Rule_Language/Section-DSL.xml" />
More information about the jboss-svn-commits
mailing list