Alessandro,

   I'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() ... ) ).
   I created a JUnit 3 test case (since people was asking for junit examples) to reproduce the scenario and it works just fine:

================
    public void testExpenses() throws Exception {
        Reader source = new InputStreamReader( getClass().getResourceAsStream( "/expenses.drl" ) );
        PackageBuilder builder = new PackageBuilder();
        builder.addPackageFromDrl( source );
       
        RuleBase ruleBase = RuleBaseFactory.newRuleBase();
        ruleBase.addPackage( builder.getPackage() );
       
        StatefulSession session = ruleBase.newStatefulSession();
        ArrayList<ExpenseReport> results = new ArrayList<ExpenseReport>();
        session.setGlobal( "results", results );
       
        // CASE 1: empty expense report, should fire
        ExpenseReport report1 = new ExpenseReport(new ArrayList<ExpenseDetail>());
        session.insert( report1 );
        session.fireAllRules();
       
        assertEquals( 1, results.size() );
        assertEquals( report1, results.get( 0 ));
       
        // CASE 2: non-empty expense report, with mixed details, should NOT fire
        ExpenseDetail[] details2 = new ExpenseDetail[] { new ExpenseDetail(ExpenseType.TAX), new ExpenseDetail( ExpenseType.MEAL ) };
        ExpenseReport report2 = new ExpenseReport(Arrays.asList( details2 ));
        session.insert( report2 );
        session.fireAllRules();
       
        assertEquals( 1, results.size() );
       
        // CASE 3: non-empty expense report, with TAX-only details, should fire
        ExpenseDetail[] details3 = new ExpenseDetail[] { new ExpenseDetail(ExpenseType.TAX), new ExpenseDetail( ExpenseType.TAX ) };
        ExpenseReport report3 = new ExpenseReport(Arrays.asList( details3 ));
        session.insert( report3 );
        session.fireAllRules();
       
        assertEquals( 2, results.size() );
        assertEquals( report3, results.get( 1 ));
    }

==========
package com.sample

global java.util.List results;

rule "Check all expenses"
when
    $report: ExpenseReport($expenseDetails: expenseDetails)
    not ( $ed : ExpenseDetail() from $expenseDetails and
          not ( ExpenseDetail( this == $ed, type == ExpenseType.TAX ) from $expenseDetails )
    )
then
    results.add( $report );
end
===========

    If you can make this test break showing your problem, I may be able to help you out.

    Thanks for opening the JIRA.

    []s
    Edson


2008/5/19 Alessandro Di Bella <aldibella@gmail.com>:
Hi,

thanks for your help, I created the JIRA as requested (http://jira.jboss.org/jira/browse/JBRULES-1611).

The workaround you suggest works only partially, if any of the ExpenseDetails is of type ExpenseType.TAX it will fire the rule.

What I would like to do is to fire the rule only if all ExpenseDetails in the same report are of type ExpenseType.TAX.

Any help is more than welcome.

Thanks

Alessandro

Edson Tirelli wrote:

  Hmm, now that you mentioned, I see that our parser is limiting the forall() CE, not allowing nested "from" CEs. This is something we should fix, since the limitation is purely a parser limitation.

  Anyway, for your case, the workaround is simply to use the "raw" forall-equivalence: not( A() and not( B() ) ). So try this:

rule "Do Not Process TAX"                        when
              $report: ExpenseReport($expenseDetails: expenseDetails)
              not ( $ed : ExpenseDetails() from $expenseDetails and
                    not ( ExpenseDetails( this == $ed, expenseType == ExpenseType.TAX ) from $expenseDetails )
              )
 then
              System.out.println("################ It works ##################");
              insertLogical("Bypass Process");
end

  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:

rule "Do Not Process TAX"                        when
              $report: ExpenseReport($expenseDetails: expenseDetails)
              forall ( ExpenseDetails( expenseType == ExpenseType.TAX ) from $expenseDetails )
 then
              System.out.println("################ It works ##################");
              insertLogical("Bypass Process");
end

   BTW, may I ask you please to open a JIRA so we don't forget to fix this for 5.0?

   Thanks,
        Edson



2008/5/18 Alessandro Di Bella <aldibella@gmail.com <mailto:aldibella@gmail.com>>:


   Hi,

   I have these two classes:

   ExpenseReport{
    Collection<ExpenseDetails> expenseDetails
   }
   ExpenseDetails{    ExpenseReport document
    ExpenseType expenseType
   }

   I am trying to create a rule that fires when all the ExpenseDetails in a
   ExpenseReport  are of the same type:

   rule "Do Not Process TAX"                        when
                  $report: ExpenseReport($expenseDetails: expenseDetails)
                  forall (                                                   ExpenseDetails(document==$report, expenseType
   == ExpenseType.TAX)
                  )          then
                  System.out.println("################ It works
   ##################");
                  insertLogical("Bypass Process");
   end

   For some reasons, it fires regardless that value of
   ExpenseDetails.expenseType.

   I just started with drools and any help i more than welcome.

   Thanks

   _______________________________________________
   rules-users mailing list
   rules-users@lists.jboss.org <mailto:rules-users@lists.jboss.org>

   https://lists.jboss.org/mailman/listinfo/rules-users




--
Edson Tirelli
JBoss Drools Core Development
Office: +55 11 3529-6000
Mobile: +55 11 9287-5646
JBoss, a division of Red Hat @ www.jboss.com <http://www.jboss.com>


------------------------------------------------------------------------


_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users

_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users



--
Edson Tirelli
JBoss Drools Core Development
Office: +55 11 3529-6000
Mobile: +55 11 9287-5646
JBoss, a division of Red Hat @ www.jboss.com