<br>&nbsp;&nbsp; Alessandro,<br><br>&nbsp;&nbsp; I&#39;m not sure what the problem in your case is, but the syntax I showed you is the correct syntax for forall, since a forall is nothing more than not( A() and not( B() ... ) ).<br>&nbsp;&nbsp; I created a JUnit 3 test case (since people was asking for junit examples) to reproduce the scenario and it works just fine:<br>
<br>================<br>&nbsp;&nbsp;&nbsp; public void testExpenses() throws Exception {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Reader source = new InputStreamReader( getClass().getResourceAsStream( &quot;/expenses.drl&quot; ) );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PackageBuilder builder = new PackageBuilder();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; builder.addPackageFromDrl( source );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RuleBase ruleBase = RuleBaseFactory.newRuleBase();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ruleBase.addPackage( builder.getPackage() );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StatefulSession session = ruleBase.newStatefulSession();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ArrayList&lt;ExpenseReport&gt; results = new ArrayList&lt;ExpenseReport&gt;();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; session.setGlobal( &quot;results&quot;, results );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // CASE 1: empty expense report, should fire<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ExpenseReport report1 = new ExpenseReport(new ArrayList&lt;ExpenseDetail&gt;());<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; session.insert( report1 );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; session.fireAllRules();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assertEquals( 1, results.size() );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assertEquals( report1, results.get( 0 ));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // CASE 2: non-empty expense report, with mixed details, should NOT fire<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ExpenseDetail[] details2 = new ExpenseDetail[] { new ExpenseDetail(ExpenseType.TAX), new ExpenseDetail( ExpenseType.MEAL ) };<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ExpenseReport report2 = new ExpenseReport(Arrays.asList( details2 ));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; session.insert( report2 );<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; session.fireAllRules();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assertEquals( 1, results.size() );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // CASE 3: non-empty expense report, with TAX-only details, should fire<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ExpenseDetail[] details3 = new ExpenseDetail[] { new ExpenseDetail(ExpenseType.TAX), new ExpenseDetail( ExpenseType.TAX ) };<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ExpenseReport report3 = new ExpenseReport(Arrays.asList( details3 ));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; session.insert( report3 );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; session.fireAllRules();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assertEquals( 2, results.size() );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assertEquals( report3, results.get( 1 ));<br>
&nbsp;&nbsp;&nbsp; }<br><br>==========<br>package com.sample<br><br>global java.util.List results;<br><br>rule &quot;Check all expenses&quot;<br>when<br>&nbsp;&nbsp;&nbsp; $report: ExpenseReport($expenseDetails: expenseDetails)<br>&nbsp;&nbsp;&nbsp; not ( $ed : ExpenseDetail() from $expenseDetails and<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; not ( ExpenseDetail( this == $ed, type == ExpenseType.TAX ) from $expenseDetails )<br>&nbsp;&nbsp;&nbsp; )<br>then<br>&nbsp;&nbsp;&nbsp; results.add( $report );<br>end<br>===========<br><br>&nbsp;&nbsp;&nbsp; If you can make this test break showing your problem, I may be able to help you out.<br>
<br>&nbsp;&nbsp;&nbsp; Thanks for opening the JIRA.<br><br>&nbsp;&nbsp;&nbsp; []s<br>&nbsp;&nbsp;&nbsp; Edson<br><br><br><div class="gmail_quote">2008/5/19 Alessandro Di Bella &lt;<a href="mailto:aldibella@gmail.com">aldibella@gmail.com</a>&gt;:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hi,<br>
<br>
thanks for your help, I created the JIRA as requested (<a href="http://jira.jboss.org/jira/browse/JBRULES-1611" target="_blank">http://jira.jboss.org/jira/browse/JBRULES-1611</a>).<br>
<br>
The workaround you suggest works only partially, if any of the ExpenseDetails is of type ExpenseType.TAX it will fire the rule.<br>
<br>
What I would like to do is to fire the rule only if all ExpenseDetails in the same report are of type ExpenseType.TAX.<br>
<br>
Any help is more than welcome.<br>
<br>
Thanks<br>
<br>
Alessandro<br>
<br>
Edson Tirelli wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="Ih2E3d">
<br>
 &nbsp; Hmm, now that you mentioned, I see that our parser is limiting the forall() CE, not allowing nested &quot;from&quot; CEs. This is something we should fix, since the limitation is purely a parser limitation.<br>
<br>
 &nbsp; Anyway, for your case, the workaround is simply to use the &quot;raw&quot; forall-equivalence: not( A() and not( B() ) ). So try this:<br>
<br>
rule &quot;Do Not Process TAX&quot; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;when<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $report: ExpenseReport($expenseDetails: expenseDetails)<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; not ( $ed : ExpenseDetails() from $expenseDetails and<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; not ( ExpenseDetails( this == $ed, expenseType == ExpenseType.TAX ) from $expenseDetails )<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )<br>
&nbsp;then<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(&quot;################ It works ##################&quot;);<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; insertLogical(&quot;Bypass Process&quot;);<br>
end<br>
<br>
 &nbsp; This is just more verbose than the forall, but it is exactly the same. Once the parser is fixed, you will be able to simply write:<br>
<br>
rule &quot;Do Not Process TAX&quot; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;when<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $report: ExpenseReport($expenseDetails: expenseDetails)<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; forall ( ExpenseDetails( expenseType == ExpenseType.TAX ) from $expenseDetails )<br>
&nbsp;then<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(&quot;################ It works ##################&quot;);<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; insertLogical(&quot;Bypass Process&quot;);<br>
end<br>
<br>
 &nbsp; &nbsp;BTW, may I ask you please to open a JIRA so we don&#39;t forget to fix this for 5.0?<br>
<br>
 &nbsp; &nbsp;Thanks,<br>
 &nbsp; &nbsp; &nbsp; &nbsp; Edson<br>
<br>
<br>
<br></div>
2008/5/18 Alessandro Di Bella &lt;<a href="mailto:aldibella@gmail.com" target="_blank">aldibella@gmail.com</a> &lt;mailto:<a href="mailto:aldibella@gmail.com" target="_blank">aldibella@gmail.com</a>&gt;&gt;:<div class="Ih2E3d">
<br>
<br>
 &nbsp; &nbsp;Hi,<br>
<br>
 &nbsp; &nbsp;I have these two classes:<br>
<br>
 &nbsp; &nbsp;ExpenseReport{<br>
 &nbsp; &nbsp; Collection&lt;ExpenseDetails&gt; expenseDetails<br>
 &nbsp; &nbsp;}<br>
 &nbsp; &nbsp;ExpenseDetails{ &nbsp; &nbsp;ExpenseReport document<br>
 &nbsp; &nbsp; ExpenseType expenseType<br>
 &nbsp; &nbsp;}<br>
<br>
 &nbsp; &nbsp;I am trying to create a rule that fires when all the ExpenseDetails in a<br>
 &nbsp; &nbsp;ExpenseReport &nbsp;are of the same type:<br>
<br>
 &nbsp; &nbsp;rule &quot;Do Not Process TAX&quot; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;when<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $report: ExpenseReport($expenseDetails: expenseDetails)<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; forall ( &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; ExpenseDetails(document==$report, expenseType<br>
 &nbsp; &nbsp;== ExpenseType.TAX)<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;then<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(&quot;################ It works<br>
 &nbsp; &nbsp;##################&quot;);<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; insertLogical(&quot;Bypass Process&quot;);<br>
 &nbsp; &nbsp;end<br>
<br>
 &nbsp; &nbsp;For some reasons, it fires regardless that value of<br>
 &nbsp; &nbsp;ExpenseDetails.expenseType.<br>
<br>
 &nbsp; &nbsp;I just started with drools and any help i more than welcome.<br>
<br>
 &nbsp; &nbsp;Thanks<br>
<br>
 &nbsp; &nbsp;_______________________________________________<br>
 &nbsp; &nbsp;rules-users mailing list<br></div>
 &nbsp; &nbsp;<a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a> &lt;mailto:<a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a>&gt;<div class="Ih2E3d">
<br>
 &nbsp; &nbsp;<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
<br>
<br>
<br>
<br>
-- <br>
Edson Tirelli<br>
JBoss Drools Core Development<br>
Office: +55 11 3529-6000<br>
Mobile: +55 11 9287-5646<br></div>
JBoss, a division of Red Hat @ <a href="http://www.jboss.com" target="_blank">www.jboss.com</a> &lt;<a href="http://www.jboss.com" target="_blank">http://www.jboss.com</a>&gt;<br>
<br>
<br>
------------------------------------------------------------------------<div class="Ih2E3d"><br>
<br>
_______________________________________________<br>
rules-users mailing list<br>
<a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
</div></blockquote><div><div></div><div class="Wj3C7c">
<br>
_______________________________________________<br>
rules-users mailing list<br>
<a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br> Edson Tirelli<br> JBoss Drools Core Development<br> Office: +55 11 3529-6000<br> Mobile: +55 11 9287-5646<br> JBoss, a division of Red Hat @ <a href="http://www.jboss.com">www.jboss.com</a>