Yap, Wolfgang has the picture right. Just 2 clarifications: * A single pattern forall in Drools is a syntax sugar to a multi-pattern forall in the following way:
forall( Pattern( <constraints> ) ) => forall( $p : Pattern() Pattern( this == $p, <constraints> ) In other words, drools uses the fact type to define the domain and apply the constraints to all objects in that domain. * "not" is the quantifier CE that means "not exists". If you explicitly write "not( exists ( ) )", the "exists" is redundant, but not eliminated automatically by Drools yet. So, you are wasting quite a lot of performance, since that forces drools to create a subnetwork in Rete. For Drools 5.1 and forward I will automatically eliminate the exists during the logical transformation step, but up to 5.0.x, you need to do it manually. Edson 2009/11/7 Wolfgang Laun <wolfgang.l...@gmail.com> > Here's the explanation why Tom's version does not work. The first pattern > of a "forall" defines the domain, which is: all CreditReport facts; for each > object in this domain, the remaining patterns must match; since the FICO > pattern merely ascertains the existence of a single FICO chained to a parent > CreditReport with validScoreIndicator false, it fires as soon as there is > one for each of the existing CreditReports. > > Jared's solution has the CreditReport CE in front of the forall, unadorned > with any quantifier, and the innate behavior of Drools makes sure that the > hole thing will be tried, once, for any existing CreditReport anyway. Then, > the forall domain is now FICOs with that CR's id and valid == false - but > what is the CE? I guess that Drool's behavior is somewhat off the > definition, using just FICO() - i.e., all existing FICO objects - as the > domain. (However, I think that Edson changed this recently for 5.1.0.) Thus, > Jared's rule indeed fires only when all FICOs are linked to the CreditReport > are false, but it fails to do so as soon as there is at least one other FICO > with either a different parent, or valid. > > Therefore, to be on the safe side with multiple CreditReport facts and > assorted FICO's being in WM at the same time, I propose this rule: > > rule "somerule2" > > when > report: CreditReport( $parentCreditReport_1_Id : myId) > forall ( $f : FICO( parentId == $parentCreditReport_1_Id ) > FICO( this == $f, validScoreIndicator == false) ) > then > System.out.println("somerule2 fired on " + $parentCreditReport_1_Id ); > end > > Here, the domain is explicitly given as all FICOs of the current CR; and > for all of them valid must be false. > > Still, this solution is not perfect: It would also fire in the absence of > any FICO for some CR. To fix this, add a guard against there being no FICOs > for the current CR: > > > report: CreditReport( $parentCreditReport_1_Id : myId) > exists FICO( parentId == $parentCreditReport_1_Id ) > forall ( $f : FICO( parentId == $parentCreditReport_1_Id ) > FICO( this == $f, validScoreIndicator == false) ) > > To complete the picture, one might equally well use the negation of forall, > which would have to be propagated into the predicate (read '|' as "so > that"): > forall x in D | P(x) => not existst x in D | not P(x) > > Now the condition delimiting the domain and the negated predicate can be > merged again into one CE: > > rule "somerule3" > > when > report: CreditReport( $parentCreditReport_1_Id : myId) > exists FiCo( parentId == $parentCreditReport_1_Id ) > not ( exists FiCo( parentId == $parentCreditReport_1_Id, validScore == > true) ) > then > System.out.println("somerule3 fired on " + $parentCreditReport_1_Id ); > end > > -W > > > On Fri, Nov 6, 2009 at 9:45 PM, Jared Davis > <sun...@davisprogramming.com>wrote: > >> I think this usage may work for your case. >> >> rule "somerule" >> when >> report: CreditReport( $parentCreditReport_1_Id : myId) >> forall ( >> FICO( parentId == $parentCreditReport_1_Id, validScoreIndicator == >> false) >> ) >> then >> System.out.print("Fired on " + $parentCreditReport_1_Id ); >> end >> >> >> >> _______________________________________________ >> rules-users mailing list >> rules-users@lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/rules-users >> > > -- Edson Tirelli JBoss Drools Core Development JBoss by Red Hat @ www.jboss.com
_______________________________________________ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users