<br>&nbsp;&nbsp; Thanks a lot for the feedback! :)<br>&nbsp;&nbsp; I will try to improve the docs, but I&#39;m still not sure how to explain the &quot;tuple&quot; thing in the accumulate context. :( Maybe we need to explain it in a previous overall rule section and then link from the accumulate docs, digging deep on the details associated with accumulate.
<br><br>&nbsp;&nbsp; []s<br>&nbsp;&nbsp; Edson<br><br><div><span class="gmail_quote">2007/8/11, Geoffrey De Smet &lt;<a href="mailto:ge0ffrey.spam@gmail.com">ge0ffrey.spam@gmail.com</a>&gt;:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
As promised :) (be carefull what you wish for)<br><br>- &quot;&lt;init code&gt;: this is a semantic block of code in the selected dialect<br>that will be executed once for each tuple, before iterating over the<br>source objects.&quot;
<br><br>What is a &quot;tuple&quot;?<br>Do you mean &quot;once for each rule&quot; or &quot;once for each pattern match&quot;?<br>(I presume the first, after reading further.)<br><br>- &quot;Source objects&quot; are facts that follow the source pattern I presume?
<br>Or is there a difference?<br><br>- The method javadocs in the AverageAccumulateFunction example are a bit<br>too besides the point IMHO. I&#39;d leave them out.<br><br><br>Summary: nothing seriously wrong with that documentation, looks good :)
<br><br>With kind regards,<br>Geoffrey De Smet<br><br><br>Edson Tirelli wrote:<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; Geoffrey,<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; The &quot;sum&quot; function that is shipped with drools always uses double<br>&gt; internally, but all numeric accumulate functions must have return type
<br>&gt; Number to avoid class cast exceptions... I must write that in the<br>&gt; docs... so, recommendation is to do:<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Number( $total : intValue ) from accumulate(<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hop($distance : distance ), // distance is an int
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum($distance)<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; Now, having said that, the decision to use double is because we<br>&gt; needed a one size fits all to ship with drools. On the other hand I<br>&gt; tried to make as simple as possible to plug new or replace built-in
<br>&gt; functions.&nbsp;&nbsp;So, if you want a sum function that uses only integers, you<br>&gt; can easily develop and plug it your own. Since I just wrote the docs on<br>&gt; how to do it, may I ask you please to read them and provide a feedback
<br>&gt; if they are good, need more info, shall I write them in another way, etc?<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; BTW, when I say it is really simple to create another sum function,<br>&gt; I mean, you can do it in about 20 minutes. Really!
<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; Find attached the HTML doc page I&#39;m talking about.<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; []s<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; Edson<br>&gt;<br>&gt;<br>&gt; 2007/7/22, Geoffrey De Smet &lt; <a href="mailto:ge0ffrey.spam@gmail.com">ge0ffrey.spam@gmail.com
</a><br>&gt; &lt;mailto:<a href="mailto:ge0ffrey.spam@gmail.com">ge0ffrey.spam@gmail.com</a>&gt;&gt;:<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; Hi guys,<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; I finally got around to experimenting with the accumulate support in<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; LocalSearchSolver. Thanks for implementing it :)<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; I use nothing but int&#39;s in my calculations,<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; but I get a ClassCastExceptions, as sum() always returns a Double and<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; setSoftConstraintsBroken(int) failes.
<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; In a previous benchmarks I &#39;ve proven that summing integers in double&#39;s<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; instead of int&#39;s hurts performance for 10% or more (which is rather<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; big).<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; Is there a sumInteger() available (or do I need to write it)? Or can it
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; be overloaded over sum() in a much cleaner way?<br>&gt;<br>&gt;<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; rule &quot;ScoreCalculator&quot;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$scoreFact : ScoreFact(); // singleton<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$total : Integer() from accumulate(
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hop($distance : distance ), // distance is an int<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum($distance)<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;then<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$scoreFact.setSoftConstraintsBroken($total);<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; end
<br>&gt;<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; svn is still here, till it&#39;s ready for drools:<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; <a href="https://taseree.svn.sourceforge.net/svnroot/taseree/trunk">https://taseree.svn.sourceforge.net/svnroot/taseree/trunk</a>
<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; --<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; With kind regards,<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; Geoffrey De Smet<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; _______________________________________________<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; rules-dev mailing list<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; <a href="mailto:rules-dev@lists.jboss.org">
rules-dev@lists.jboss.org</a> &lt;mailto:<a href="mailto:rules-dev@lists.jboss.org">rules-dev@lists.jboss.org</a>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; <a href="https://lists.jboss.org/mailman/listinfo/rules-dev">https://lists.jboss.org/mailman/listinfo/rules-dev
</a><br>&gt;<br>&gt;<br>&gt;<br>&gt;<br>&gt; --<br>&gt;&nbsp;&nbsp; Edson Tirelli<br>&gt;&nbsp;&nbsp; Software Engineer - JBoss Rules Core Developer<br>&gt;&nbsp;&nbsp; Office: +55 11 3529-6000<br>&gt;&nbsp;&nbsp; Mobile: +55 11 9287-5646<br>&gt;&nbsp;&nbsp; JBoss, a division of Red Hat @ 
<a href="http://www.jboss.com">www.jboss.com</a> &lt;<a href="http://www.jboss.com">http://www.jboss.com</a>&gt;<br>&gt; ------------------------------------------------------------------------<br>&gt;<br>&gt; 3.6. Advanced Conditional Elements
<br>&gt; Prev &lt;ch03s05.html&gt;&nbsp;&nbsp; Chapter 3. The Rule Language&nbsp;&nbsp;&nbsp;&nbsp; Next &lt;ch03s07.html&gt;<br>&gt;<br>&gt; ------------------------------------------------------------------------<br>&gt;<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; 3.6. Advanced Conditional Elements
<br>&gt;<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Note<br>&gt;<br>&gt; /|(updated to Drools 4.0)|/<br>&gt;<br>&gt; Drools 4.0 introduces a whole new set of conditional elements in order<br>&gt; to support full First Order Logic expressiveness, as well as some
<br>&gt; facilities for handling collections of facts. This section will detail<br>&gt; the following new Conditional Elements:<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; *<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; *<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; collect
<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; *<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; accumulate<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; *<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; forall<br>&gt;<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.6.1. From<br>&gt;<br>&gt; The *from* Conditional Element allows users to specify a source for
<br>&gt; patterns to reason over. This allows the engine to reason over data not<br>&gt; in the Working Memory. This could be a sub-field on a bound variable or<br>&gt; the results of a method call. It is a powerful construction that allows
<br>&gt; out of the box integration with other application components and<br>&gt; frameworks. One common example is the integration with data retrieved<br>&gt; on-demand from databases using hibernate named queries.<br>&gt;
<br>&gt; The expression used to define the object source is any expression that<br>&gt; follows regular MVEL syntax. I.e., it allows you to easily use object<br>&gt; property navigation, execute method calls and access maps and
<br>&gt; collections elements.<br>&gt;<br>&gt; Here is a simple example of reasoning and binding on another pattern<br>&gt; sub-field:<br>&gt;<br>&gt; rule &quot;validate zipcode&quot;<br>&gt; when<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; Person( $personAddress : address )
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; Address( zipcode == &quot;23920W&quot;) from $personAddress<br>&gt; then<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; # zip code is ok<br>&gt; end<br>&gt;<br>&gt; With all the flexibility from the new expressiveness in the Drools<br>&gt; engine you can slice and dice this problem many ways. This is the same
<br>&gt; but shows how you can use a graph notation with the &#39;from&#39;:<br>&gt;<br>&gt; rule &quot;validate zipcode&quot;<br>&gt; when<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; $p : Person( )<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; $a : Address( zipcode == &quot;23920W&quot;) from $p.address
<br>&gt; then<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; # zip code is ok<br>&gt; end<br>&gt;<br>&gt; Previous examples were reasoning over a single pattern. The *from* CE<br>&gt; also support object sources that return a collection of objects. In that
<br>&gt; case, *from* will iterate over all objects in the collection and try to<br>&gt; match each of them individually. For instance, if we want a rule that<br>&gt; applies 10% discount to each item in an order, we could do:
<br>&gt;<br>&gt; rule &quot;apply 10% discount to all items over US$ 100,00 in an order&quot;<br>&gt; when<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; $order : Order()<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; $item&nbsp;&nbsp;: OrderItem( value &gt; 100 ) from $order.items<br>&gt; then<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; # apply discount to $item
<br>&gt; end<br>&gt;<br>&gt; The above example will cause the rule to fire once for each item whose<br>&gt; value is greater than 100 for each given order.<br>&gt;<br>&gt; The next example shows how we can reason over the results of a hibernate
<br>&gt; query. The Restaurant pattern will reason over and bind with each result<br>&gt; in turn:<br>&gt;<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.6.2. Collect<br>&gt;<br>&gt; The *collect* Conditional Element allows rules to reason over collection
<br>&gt; of objects collected from the given source or from the working memory. A<br>&gt; simple example:<br>&gt;<br>&gt; import java.util.ArrayList<br>&gt;<br>&gt; rule &quot;Raise priority if system has more than 3 pending alarms&quot;
<br>&gt; when<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; $system : System()<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; $alarms : ArrayList( size &gt;= 3 )<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from collect( Alarm( system == $system, status == &#39;pending&#39; ) )<br>&gt; then<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; # Raise priority, because system $system has
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; # 3 or more alarms pending. The pending alarms<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; # are $alarms.<br>&gt; end<br>&gt;<br>&gt; In the above example, the rule will look for all pending alarms in the<br>&gt; working memory for each given system and group them in ArrayLists. If 3
<br>&gt; or more alarms are found for a given system, the rule will fire.<br>&gt;<br>&gt; The *collect* CE result pattern can be any concrete class that<br>&gt; implements tha java.util.Collection interface and provides a default
<br>&gt; no-arg public constructor. I.e., you can use default java collections<br>&gt; like ArrayList, LinkedList, HashSet, etc, or your own class, as long as<br>&gt; it implements the java.util.Collection interface and provide a default
<br>&gt; no-arg public constructor.<br>&gt;<br>&gt; Both source and result patterns can be constrained as any other pattern.<br>&gt;<br>&gt; Variables bound before the *collect* CE are in the scope of both source<br>&gt; and result patterns and as so, you can use them to constrain both your
<br>&gt; source and result patterns. Although, the /collect( ... )/ is a scope<br>&gt; delimiter for bindings, meaning that any binding made inside of it, is<br>&gt; not available for use outside of it.<br>&gt;<br>&gt; Collect accepts nested *from* elements, so the following example is a
<br>&gt; valid use of *collect*:<br>&gt;<br>&gt; import java.util.LinkedList;<br>&gt;<br>&gt; rule &quot;Send a message to all mothers&quot;<br>&gt; when<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; $town : Town( name == &#39;Paris&#39; )<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; $mothers : LinkedList()
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from collect( Person( gender == &#39;F&#39;, children &gt; 0 )<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from $town.getPeople()<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)<br>&gt; then<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; # send a message to all mothers
<br>&gt; end<br>&gt;<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.6.3. Accumulate<br>&gt;<br>&gt; The *accumulate* Conditional Element is a more flexible and powerful<br>&gt; form of *collect* Conditional Element, in the sense that it can be used
<br>&gt; to do what *collect* CE does and also do things that *collect* CE is not<br>&gt; capable to do. Basically what it does is it allows a rule to iterate<br>&gt; over a collection of objects, executing custom actions for each of the
<br>&gt; elements, and at the end return a result object.<br>&gt;<br>&gt; The general syntax of the *accumulate* CE is:<br>&gt;<br>&gt; /|&lt;result pattern&gt;|/ from accumulate( /|&lt;source pattern&gt;|/,<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; init( /|&lt;init code&gt;|/ ),
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; action( /|&lt;action code&gt;|/ ),<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reverse( /|&lt;reverse code&gt;|/ ),<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result( /|&lt;result expression&gt;|/ ) )
<br>&gt;<br>&gt; The meaning of each of the elements is the following:<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; *<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&lt;source pattern&gt;*: the source pattern is a regular pattern that<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the engine will try to match against each of the source objects.
<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; *<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&lt;init code&gt;*: this is a semantic block of code in the selected<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dialect that will be executed once for each tuple, before<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iterating over the source objects.
<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; *<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&lt;action code&gt;*: this is a semantic block of code in the selected<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dialect that will be executed for each of the source objects.<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; *<br>&gt;
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&lt;reverse code&gt;*: this is an optional semantic block of code in<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the selected dialect that if present will be executed for each<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; source object that no longer matches the source pattern. The
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; objective of this code block is to &quot;undo&quot; any calculation done in<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the &lt;action code&gt; block, so that the engine can do decremental<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; calculation when a source object is modified or retracted, hugely
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; improving performance of these operations.<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; *<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&lt;result expression&gt;*: this is a semantic expression in the<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; selected dialect that is executed after all source objects are
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iterated.<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; *<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&lt;result pattern&gt;*: this is a regular pattern that the engine<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tries to match against the object returned from the &lt;result<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; expression&gt;. If it matches, the *accumulate* conditional element
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; evaluates to *true* and the engine proceeds with the evaluation of<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the next CE in the rule. If it does not matches, the *accumulate*<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CE evaluates to *false* and the engine stops evaluating CEs for
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; that rule.<br>&gt;<br>&gt; It is easier to understand if we look at an example:<br>&gt;<br>&gt; rule &quot;Apply 10% discount to orders over US$ 100,00&quot;<br>&gt; when<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; $order : Order()<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; $total : Number( doubleValue &gt; 100 )
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from accumulate( OrderItem( order == $order, $value : value ),<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; init( double total = 0; ),<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; action( total += $value; ),<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reverse( total -= $value; ),
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result( total ) )<br>&gt; then<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; # apply discount to $order<br>&gt; end<br>&gt;<br>&gt; In the above example, for each Order() in the working memory, the engine<br>&gt; will execute the *init code* initializing the total variable to zero.
<br>&gt; Then it will iterate over all OrderItem() objects for that order,<br>&gt; executing the *action* for each one (in the example, it will sum the<br>&gt; value of all items into the total variable). After iterating over all
<br>&gt; OrderItem, it will return the value corresponding to the *result<br>&gt; expression* (in the above example, the value of the total variable).<br>&gt; Finally, the engine will try to match the result with the Number()
<br>&gt; pattern and if the double value is greater than 100, the rule will fire.<br>&gt;<br>&gt; The example used java as the semantic dialect, and as such, note that<br>&gt; the usage of &#39;;&#39; is mandatory in the init, action and reverse code
<br>&gt; blocks. The result is an expression and as such, it does not admit &#39;;&#39;.<br>&gt; If the user uses any other dialect, he must comply to that dialect<br>&gt; specific syntax.<br>&gt;<br>&gt; As mentioned before, the *reverse code* is optional, but it is strongly
<br>&gt; recommended that the user writes it in order to benefit from the<br>&gt; /improved performance on update and retracts/.<br>&gt;<br>&gt; The *accumulate* CE can be used to execute any action on source objects.<br>
&gt; The following example instantiates and populates a custom object:<br>&gt;<br>&gt; rule &quot;Accumulate using custom objects&quot;<br>&gt; when<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; $person&nbsp;&nbsp; : Person( $likes : likes )<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; $cheesery : Cheesery( totalAmount &gt; 100 )
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from accumulate( $cheese : Cheese( type == $likes ),<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init( Cheesery cheesery = new Cheesery(); ),<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action( cheesery.addCheese
( $cheese ); ),<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reverse( cheesery.removeCheese( $cheese ); ),<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result( cheesery ) );<br>&gt; then<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; // do something<br>&gt; end<br>
&gt;<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://3.6.3.1">3.6.3.1</a>. Accumulate Functions<br>&gt;<br>&gt; The accumulate CE is a very powerful CE, but it gets real declarative<br>&gt; and easy to use when using predefined functions that are known as
<br>&gt; Accumulate Functions. They work exactly like accumulate, but instead of<br>&gt; explicitly writing custom code in every accumulate CE, the user can use<br>&gt; predefined code for common operations.<br>&gt;<br>&gt; For instance, the rule to apply discount on orders written in the
<br>&gt; previous section, could be written in the following way, using<br>&gt; Accumulate Functions:<br>&gt;<br>&gt; rule &quot;Apply 10% discount to orders over US$ 100,00&quot;<br>&gt; when<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; $order : Order()
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; $total : Number( doubleValue &gt; 100 )<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from accumulate( OrderItem( order == $order, $value : value ),<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum( $value ) )<br>&gt; then<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; # apply discount to $order
<br>&gt; end<br>&gt;<br>&gt; In the above example, sum is an AccumulateFunction and will sum the<br>&gt; $value of all OrderItems and return the result.<br>&gt;<br>&gt; Drools 4.0 ships with the following built in accumulate functions:
<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; *<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; average<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; *<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; min<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; *<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; max<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; *<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum<br>&gt;<br>&gt; These common functions accept any expression as input. For instance, if<br>&gt; someone wants to calculate the average profit on all items of an order,<br>&gt; a rule could be written using the average function:
<br>&gt;<br>&gt; rule &quot;Average profit&quot;<br>&gt; when<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; $order : Order()<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; $profit : Number()<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from accumulate( OrderItem( order == $order, $cost : cost, $price : price )<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;average( 1 - $cost / $price ) )<br>&gt; then<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; # average profit for $order is $profit<br>&gt; end<br>&gt;<br>&gt; Accumulate Functions are all pluggable. That means that if needed,
<br>&gt; custom, domain specific functions can easily be added to the engine and<br>&gt; rules can start to use them without any restrictions. To implement a new<br>&gt; Accumulate Functions all one needs to do is to create a java class that
<br>&gt; implements the org.drools.base.acumulators.AccumulateFunction interface<br>&gt; and add a line to the configuration file or set a system property to let<br>&gt; the engine know about the new function. As an example of an Accumulate
<br>&gt; Function implementation, the following is the implementation of the<br>&gt; &quot;average&quot; function:<br>&gt;<br>&gt; /*<br>&gt;&nbsp;&nbsp;* Copyright 2007 JBoss Inc<br>&gt;&nbsp;&nbsp;*<br>&gt;&nbsp;&nbsp;* Licensed under the Apache License, Version 
2.0 (the &quot;License&quot;);<br>&gt;&nbsp;&nbsp;* you may not use this file except in compliance with the License.<br>&gt;&nbsp;&nbsp;* You may obtain a copy of the License at<br>&gt;&nbsp;&nbsp;*<br>&gt;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.apache.org/licenses/LICENSE-2.0">
http://www.apache.org/licenses/LICENSE-2.0</a><br>&gt;&nbsp;&nbsp;*<br>&gt;&nbsp;&nbsp;* Unless required by applicable law or agreed to in writing, software<br>&gt;&nbsp;&nbsp;* distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
<br>&gt;&nbsp;&nbsp;* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<br>&gt;&nbsp;&nbsp;* See the License for the specific language governing permissions and<br>&gt;&nbsp;&nbsp;* limitations under the License.<br>&gt;&nbsp;&nbsp;*<br>&gt;&nbsp;&nbsp;* Created on Jun 21, 2007
<br>&gt;&nbsp;&nbsp;*/<br>&gt; package org.drools.base.accumulators;<br>&gt;<br>&gt;<br>&gt; /**<br>&gt;&nbsp;&nbsp;* An implementation of an accumulator capable of calculating average values<br>&gt;&nbsp;&nbsp;*<br>&gt;&nbsp;&nbsp;* @author etirelli<br>&gt;&nbsp;&nbsp;*
<br>&gt;&nbsp;&nbsp;*/<br>&gt; public class AverageAccumulateFunction implements AccumulateFunction {<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; protected static class AverageData {<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int&nbsp;&nbsp;&nbsp;&nbsp;count = 0;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public double total = 0;
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; /* (non-Javadoc)<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @see org.drools.base.accumulators.AccumulateFunction#createContext()<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; public Object createContext() {<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new AverageData();
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; /* (non-Javadoc)<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @see org.drools.base.accumulators.AccumulateFunction#init(java.lang.Object)<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; public void init(Object context) throws Exception {
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AverageData data = (AverageData) context;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data.count = 0;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data.total = 0;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; /* (non-Javadoc)<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @see org.drools.base.accumulators.AccumulateFunction#accumulate
(java.lang.Object, java.lang.Object)<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; public void accumulate(Object context,<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object value) {<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AverageData data = (AverageData) context;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
data.count++;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data.total += ((Number) value).doubleValue();<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; /* (non-Javadoc)<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @see org.drools.base.accumulators.AccumulateFunction#reverse(java.lang.Object, 
java.lang.Object)<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; public void reverse(Object context,<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object value) throws Exception {<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AverageData data = (AverageData) context;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
data.count--;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data.total -= ((Number) value).doubleValue();<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; /* (non-Javadoc)<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @see org.drools.base.accumulators.AccumulateFunction#getResult(java.lang.Object
)<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; public Object getResult(Object context) throws Exception {<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AverageData data = (AverageData) context;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new Double( data.count == 0 ? 0 : data.total / data.count
 );<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; /* (non-Javadoc)<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @see org.drools.base.accumulators.AccumulateFunction#supportsReverse()<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; public boolean supportsReverse() {<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt;<br>&gt; }<br>&gt;<br>&gt; The code for the function is very simple, as we could expect, as all the<br>&gt; &quot;dirty&quot; integration work is done by the engine. Finally, to plug the<br>&gt; function into the engine, we added it to the configuration file:
<br>&gt;<br>&gt; drools.accumulate.function.average = org.drools.base.accumulators.AverageAccumulateFunction<br>&gt;<br>&gt; Where &quot;drools.accumulate.function.&quot; is a prefix that must always be<br>&gt; used, &quot;average&quot; is how the function will be used in the rule file, and
<br>&gt; &quot;org.drools.base.accumulators.AverageAccumulateFunction&quot; is the fully<br>&gt; qualified name of the class that implements the function behavior.<br>&gt;<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.6.4. Forall<br>&gt;<br>&gt; *Forall* is the Conditional Element that completes the First Order Logic
<br>&gt; support in Drools. The syntax is very simple:<br>&gt;<br>&gt; forall( /|&lt;select pattern&gt;|/ /|&lt;constraint patterns&gt;|/ )<br>&gt;<br>&gt; The *forall* Conditional Element will evaluate to true when all facts
<br>&gt; that match the /|&lt;select pattern&gt;|/ match all the /|&lt;constraint<br>&gt; patterns&gt;|/. Example:<br>&gt;<br>&gt; rule &quot;All english buses are red&quot;<br>&gt; when<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; forall( $bus : Bus( type == &#39;english&#39;)
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Bus( this == $bus, color = &#39;red&#39; ) )<br>&gt; then<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; # all english buses are red<br>&gt; end<br>&gt;<br>&gt; In the above rule, we &quot;select&quot; all Bus object whose type is &quot;english&quot;.
<br>&gt; Then, for each fact that matchs this pattern we evaluate the following<br>&gt; patterns and if they match, the forall CE will evaluate to true. Another<br>&gt; example:<br>&gt;<br>&gt; rule &quot;all employees have health and dental care programs&quot;
<br>&gt; when<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; forall( $emp : Employee()<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HealthCare( employee == $emp )<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DentalCare( employee == $emp )<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br>&gt; then<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; # all employees have health and dental care
<br>&gt; end<br>&gt;<br>&gt; Forall can be nested inside other CEs for complete expressiveness. For<br>&gt; instance, *forall* can be used inside a *not* CE:<br>&gt;<br>&gt; rule &quot;not all employees have health and dental care&quot;
<br>&gt; when<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; not forall( $emp : Employee()<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HealthCare( employee == $emp )<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DentalCare( employee == $emp )<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br>&gt; then<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; # not all employees have health and dental care
<br>&gt; end<br>&gt;<br>&gt; As a side note, forall Conditional Element is equivalent to writing:<br>&gt;<br>&gt; not( /|&lt;select pattern&gt;|/ and not ( and /|&lt;constraint patterns&gt;|/ ) )<br>&gt;<br>&gt; Also, it is important to note that *forall is a scope delimiter*, so it
<br>&gt; can use any previously bound variable, but no variable bound inside it<br>&gt; will be available to use outside of it.<br>&gt;<br>&gt; ------------------------------------------------------------------------<br>&gt; Prev &lt;
ch03s05.html&gt;&nbsp;&nbsp; Up &lt;ch03.html&gt;&nbsp;&nbsp; Next &lt;ch03s07.html&gt;<br>&gt; 3.5. Rule&nbsp;&nbsp;&nbsp;&nbsp; Home &lt;title.html&gt; | ToC &lt;bk01-toc.html&gt;&nbsp;&nbsp;3.7. Query<br>&gt;<br>&gt;<br>&gt; ------------------------------------------------------------------------
<br>&gt;<br>&gt; _______________________________________________<br>&gt; rules-dev mailing list<br>&gt; <a href="mailto:rules-dev@lists.jboss.org">rules-dev@lists.jboss.org</a><br>&gt; <a href="https://lists.jboss.org/mailman/listinfo/rules-dev">
https://lists.jboss.org/mailman/listinfo/rules-dev</a><br><br>_______________________________________________<br>rules-dev mailing list<br><a href="mailto:rules-dev@lists.jboss.org">rules-dev@lists.jboss.org</a><br><a href="https://lists.jboss.org/mailman/listinfo/rules-dev">
https://lists.jboss.org/mailman/listinfo/rules-dev</a><br></blockquote></div><br><br clear="all"><br>-- <br>&nbsp;&nbsp;Edson Tirelli<br>&nbsp;&nbsp;Software Engineer - JBoss Rules Core Developer<br>&nbsp;&nbsp;Office: +55 11 3529-6000<br>&nbsp;&nbsp;Mobile: +55 11 9287-5646
<br>&nbsp;&nbsp;JBoss, a division of Red Hat @ <a href="http://www.jboss.com">www.jboss.com</a>