Re: [rules-users] drools arithmetics without eval()
Hi, These rules are all auto-generated every day, and I don't control what is going into them, so this kind of optimizations won't work for me. The basic problem here, is that I have tons of rules that count facts (PortfolioProducts) and use the result as rule conditions. Some conditions could look like this: count(PortfolioProduct(A)) + count(PortfolioProduct(B)) = ( count(PortfolioProduct(C)) - count(PortfolioProduct(D)) ) - count(PortfolioProduct(E)) and so on... All rules look like the rule I've posted: I first calculate all relevant fact counts to be used by the rule (accumulates), and then perform the logic/arithmetic evaluation using evals(). Some rules end up having 15 accumulates and 2 evals as conditions... My question is if using accumulate and eval() is the only choice I have to write these kind of rules. Regards, Tiago Lopes -- View this message in context: http://drools.46999.n3.nabble.com/drools-arithmetics-without-eval-tp3823232p3824958.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] drools arithmetics without eval()
And what if you perform the count in some java methods (a session listener on inserted objects which updates a big map?) and then only use resulting counters in rules ? If you have to use rules to compute the counters (for instance because it is not always as simple, or if you want to keep the ability to add arbitrary businness logic), you nay consider using objects for counters, and then have : - a first set of rules updating counters (using accumulate or not). The idea there is to share common accumulates instead of repeating them in many many rules. You can also use queries instead of accumulates. - a second set of rules checking counters to take a decision. - Mail original - De: fx242 dro...@fx242.com À: rules-users@lists.jboss.org Envoyé: Mercredi 14 Mars 2012 11:49:19 Objet: Re: [rules-users] drools arithmetics without eval() Hi, These rules are all auto-generated every day, and I don't control what is going into them, so this kind of optimizations won't work for me. The basic problem here, is that I have tons of rules that count facts (PortfolioProducts) and use the result as rule conditions. Some conditions could look like this: count(PortfolioProduct(A)) + count(PortfolioProduct(B)) = ( count(PortfolioProduct(C)) - count(PortfolioProduct(D)) ) - count(PortfolioProduct(E)) and so on... All rules look like the rule I've posted: I first calculate all relevant fact counts to be used by the rule (accumulates), and then perform the logic/arithmetic evaluation using evals(). Some rules end up having 15 accumulates and 2 evals as conditions... My question is if using accumulate and eval() is the only choice I have to write these kind of rules. Regards, Tiago Lopes -- View this message in context: http://drools.46999.n3.nabble.com/drools-arithmetics-without-eval-tp3823232p3824958.html Sent from the Drools: User forum mailing list archive at Nabble.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
Re: [rules-users] drools arithmetics without eval()
accumulate is not the way to go. If you need accumlated counts for certain facts, by type or, within some type, by attribute value, then you should set up secondary facts and maintain these during the element insertion process or by separate (static) rules. class ProductCounter { String id; int count; } rule count when $pp: PortfolioProduct($pid: productId, prodCounted == false ) $pc: ProductCounter( id == $pid ) then modify( $pc ){ setCount( $pc.getCount() + 1 ) } end And now you can generate the rules accessing the completed counts. -W On 14/03/2012, fx242 dro...@fx242.com wrote: Hi, These rules are all auto-generated every day, and I don't control what is going into them, so this kind of optimizations won't work for me. The basic problem here, is that I have tons of rules that count facts (PortfolioProducts) and use the result as rule conditions. Some conditions could look like this: count(PortfolioProduct(A)) + count(PortfolioProduct(B)) = ( count(PortfolioProduct(C)) - count(PortfolioProduct(D)) ) - count(PortfolioProduct(E)) and so on... All rules look like the rule I've posted: I first calculate all relevant fact counts to be used by the rule (accumulates), and then perform the logic/arithmetic evaluation using evals(). Some rules end up having 15 accumulates and 2 evals as conditions... My question is if using accumulate and eval() is the only choice I have to write these kind of rules. Regards, Tiago Lopes -- View this message in context: http://drools.46999.n3.nabble.com/drools-arithmetics-without-eval-tp3823232p3824958.html Sent from the Drools: User forum mailing list archive at Nabble.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
Re: [rules-users] drools arithmetics without eval()
Wolfgang Laun wrote: accumulate is not the way to go. If you need accumlated counts for certain facts, by type or, within some type, by attribute value, then you should set up secondary facts and maintain these during the element insertion process or by separate (static) rules. class ProductCounter { String id; int count; } rule count when $pp: PortfolioProduct($pid: productId, prodCounted == false ) $pc: ProductCounter( id == $pid ) then modify( $pc ){ setCount( $pc.getCount() + 1 ) } end Shouldn't then be then modify( $pc ){ setCount( $pc.getCount() + 1 ) } modify ($pp ){ setProdCounted( true ) } end I'm only asking to validate my understanding of the situation. -Stathis And now you can generate the rules accessing the completed counts. -W On 14/03/2012, fx242 dro...@fx242.com wrote: Hi, These rules are all auto-generated every day, and I don't control what is going into them, so this kind of optimizations won't work for me. The basic problem here, is that I have tons of rules that count facts (PortfolioProducts) and use the result as rule conditions. Some conditions could look like this: count(PortfolioProduct(A)) + count(PortfolioProduct(B)) = ( count(PortfolioProduct(C)) - count(PortfolioProduct(D)) ) - count(PortfolioProduct(E)) and so on... All rules look like the rule I've posted: I first calculate all relevant fact counts to be used by the rule (accumulates), and then perform the logic/arithmetic evaluation using evals(). Some rules end up having 15 accumulates and 2 evals as conditions... My question is if using accumulate and eval() is the only choice I have to write these kind of rules. Regards, Tiago Lopes -- View this message in context: http://drools.46999.n3.nabble.com/drools-arithmetics-without-eval-tp3823232p3824958.html Sent from the Drools: User forum mailing list archive at Nabble.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 ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] drools arithmetics without eval()
Oh yes, indeed. -W On 14/03/2012, rou...@mm.di.uoa.gr rou...@mm.di.uoa.gr wrote: Wolfgang Laun wrote: accumulate is not the way to go. If you need accumlated counts for certain facts, by type or, within some type, by attribute value, then you should set up secondary facts and maintain these during the element insertion process or by separate (static) rules. class ProductCounter { String id; int count; } rule count when $pp: PortfolioProduct($pid: productId, prodCounted == false ) $pc: ProductCounter( id == $pid ) then modify( $pc ){ setCount( $pc.getCount() + 1 ) } end Shouldn't then be then modify( $pc ){ setCount( $pc.getCount() + 1 ) } modify ($pp ){ setProdCounted( true ) } end I'm only asking to validate my understanding of the situation. -Stathis And now you can generate the rules accessing the completed counts. -W On 14/03/2012, fx242 dro...@fx242.com wrote: Hi, These rules are all auto-generated every day, and I don't control what is going into them, so this kind of optimizations won't work for me. The basic problem here, is that I have tons of rules that count facts (PortfolioProducts) and use the result as rule conditions. Some conditions could look like this: count(PortfolioProduct(A)) + count(PortfolioProduct(B)) = ( count(PortfolioProduct(C)) - count(PortfolioProduct(D)) ) - count(PortfolioProduct(E)) and so on... All rules look like the rule I've posted: I first calculate all relevant fact counts to be used by the rule (accumulates), and then perform the logic/arithmetic evaluation using evals(). Some rules end up having 15 accumulates and 2 evals as conditions... My question is if using accumulate and eval() is the only choice I have to write these kind of rules. Regards, Tiago Lopes -- View this message in context: http://drools.46999.n3.nabble.com/drools-arithmetics-without-eval-tp3823232p3824958.html Sent from the Drools: User forum mailing list archive at Nabble.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 ___ 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
Re: [rules-users] drools arithmetics without eval()
Yes, it should But this kind of rule implies that a PortfolioProduct has a unique contribution in a unique counter (when prodCounted becomes true, the PortfolioProduct won't be counted anymore). And I am not sure whether this kind of rule is more efficient than an accumulate or a query (it implies a lot of updates, and to me this is equivalent to an accumulate). My way of doing such things is to count in a counter object (like the ProductCounter here), but don't call modify (or update) to avoid loop and to avoid adding some too technical stuff in rules. Once all counting rules fired, I exec another rule (in a separate ruleflow-group or agenda-group) that updates the counters. Then I give the focus to decision rules ... - Mail original - De: rou...@mm.di.uoa.gr À: rules-users@lists.jboss.org Envoyé: Mercredi 14 Mars 2012 13:25:51 Objet: Re: [rules-users] drools arithmetics without eval() Wolfgang Laun wrote: accumulate is not the way to go. If you need accumlated counts for certain facts, by type or, within some type, by attribute value, then you should set up secondary facts and maintain these during the element insertion process or by separate (static) rules. class ProductCounter { String id; int count; } rule count when $pp: PortfolioProduct($pid: productId, prodCounted == false ) $pc: ProductCounter( id == $pid ) then modify( $pc ){ setCount( $pc.getCount() + 1 ) } end Shouldn't then be then modify( $pc ){ setCount( $pc.getCount() + 1 ) } modify ($pp ){ setProdCounted( true ) } end I'm only asking to validate my understanding of the situation. -Stathis And now you can generate the rules accessing the completed counts. -W On 14/03/2012, fx242 dro...@fx242.com wrote: Hi, These rules are all auto-generated every day, and I don't control what is going into them, so this kind of optimizations won't work for me. The basic problem here, is that I have tons of rules that count facts (PortfolioProducts) and use the result as rule conditions. Some conditions could look like this: count(PortfolioProduct(A)) + count(PortfolioProduct(B)) = ( count(PortfolioProduct(C)) - count(PortfolioProduct(D)) ) - count(PortfolioProduct(E)) and so on... All rules look like the rule I've posted: I first calculate all relevant fact counts to be used by the rule (accumulates), and then perform the logic/arithmetic evaluation using evals(). Some rules end up having 15 accumulates and 2 evals as conditions... My question is if using accumulate and eval() is the only choice I have to write these kind of rules. Regards, Tiago Lopes -- View this message in context: http://drools.46999.n3.nabble.com/drools-arithmetics-without-eval-tp3823232p3824958.html Sent from the Drools: User forum mailing list archive at Nabble.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 ___ 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
[rules-users] drools arithmetics without eval()
I have a question regarding eval() use. My rulebase is around ~3k rules, most of them are auto-generated by templates, and they end up looking like this: rule CONFIG_114 salience 0 when client: Client() contextProd: PortfolioProduct(prodAdded == true, productId == PROFESSIONAL) Number(qty_1: intValue) from accumulate(pp: PortfolioProduct(productId in (BOX_001), prodAdded == true), count(pp)) Number(qty_2: intValue) from accumulate(pp: PortfolioProduct(productId in (BOX_002), prodAdded == true), count(pp)) Number(qty_3: intValue) from accumulate(pp: PortfolioProduct(productId in (BOX_003), prodAdded == true), count(pp)) Number(qty_4: intValue) from accumulate(pp: PortfolioProduct(productId in (BOX_004), prodAdded == true), count(pp)) Number(qty_5: intValue) from accumulate(pp: PortfolioProduct(productId in (BOX_005), prodAdded == true), count(pp)) eval(qty_1 == 1) not(eval(qty_2 = (qty_3 + qty_4 + qty_5))) then balance(kcontext, contextProd, qty_2, =, (qty_3 + qty_4 + qty_5)); end These rules have all one or two evals in the end, comparing product quantities that are present in the Working Memory. My question is: Is there any better way to write this kind of rules without resorting to eval()? I'm currently getting hit (in performance terms) by over-using these, so I wonder if there is a better way to do this. Thanks! Tiago Lopes -- View this message in context: http://drools.46999.n3.nabble.com/drools-arithmetics-without-eval-tp3823232p3823232.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] drools arithmetics without eval()
You can rewrite this rule like this (if I managed to juggle the inequality correctly): client: Client() contextProd: PortfolioProduct(prodAdded == true, productId ==PROFESSIONAL) Number(qty_1: intValue* == 1* ) from accumulate(pp: PortfolioProduct(productId in (BOX_001), prodAdded == true), count(pp)) Number(qty_2: intValue) from accumulate(pp: PortfolioProduct(productId in (BOX_002), prodAdded == true), count(pp)) Number(qty_3: intValue) from accumulate(pp: PortfolioProduct(productId in (BOX_003), prodAdded == true), count(pp)) Number(qty_4: intValue) from accumulate(pp: PortfolioProduct(productId in (BOX_004), prodAdded == true), count(pp)) Number(qty_5: intValue * qty_2 - qty_3 - qty_4* ) from accumulate(pp: PortfolioProduct(productId in (BOX_005), prodAdded == true), count(pp)) Especially the == 1in the first Number should block additional useless work. But the performance hit might also be due to the excessive use of accumulate. -W On 13 March 2012 20:12, fx242 dro...@fx242.com wrote: I have a question regarding eval() use. My rulebase is around ~3k rules, most of them are auto-generated by templates, and they end up looking like this: rule CONFIG_114 salience 0 when client: Client() contextProd: PortfolioProduct(prodAdded == true, productId == PROFESSIONAL) Number(qty_1: intValue) from accumulate(pp: PortfolioProduct(productId in (BOX_001), prodAdded == true), count(pp)) Number(qty_2: intValue) from accumulate(pp: PortfolioProduct(productId in (BOX_002), prodAdded == true), count(pp)) Number(qty_3: intValue) from accumulate(pp: PortfolioProduct(productId in (BOX_003), prodAdded == true), count(pp)) Number(qty_4: intValue) from accumulate(pp: PortfolioProduct(productId in (BOX_004), prodAdded == true), count(pp)) Number(qty_5: intValue) from accumulate(pp: PortfolioProduct(productId in (BOX_005), prodAdded == true), count(pp)) eval(qty_1 == 1) not(eval(qty_2 = (qty_3 + qty_4 + qty_5))) then balance(kcontext, contextProd, qty_2, =, (qty_3 + qty_4 + qty_5)); end These rules have all one or two evals in the end, comparing product quantities that are present in the Working Memory. My question is: Is there any better way to write this kind of rules without resorting to eval()? I'm currently getting hit (in performance terms) by over-using these, so I wonder if there is a better way to do this. Thanks! Tiago Lopes -- View this message in context: http://drools.46999.n3.nabble.com/drools-arithmetics-without-eval-tp3823232p3823232.html Sent from the Drools: User forum mailing list archive at Nabble.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