[rules-users] Avoid unnecessary rule activation when object is retracted

lsilva lesilvav at gmail.com
Fri May 8 13:58:02 EDT 2009


After hours loking for a solutions I finally found it. I had to avoid using
"from" in this case, according to recomendation that I found in this
http://www.nabble.com/Rules-with-from-always-loops-(Drools-4.0.7)-td21930651.html#a21997926
Message 

So, I retired from my rules sentences like:

usageItem: EstimatedElectricUsage() from
account.getElectricUsageEstimation(1,6);

And I had to insert each EstimatedElectricUsage object directly in the
working memory.


lsilva wrote:
> 
> Hi, I'll appreciate any help in this issue
> 
> I'm going to explain my problem, using the next rules as example:
> 
> ####################BEGIN RULE FILE
> (pricing.drl)##########################
> #created on: 04/05/2009
> package com.mycompany.pricing
> 
> import com.company.FeatureQuoteRequest;
> import com.company.Account;
> import com.company.EstimatedElectricUsage;
> import com.company.AuxDecimal
>  
> global AuxDecimal auxDecimal1;
> 
> #first rule group to calculate the Capacity Factor
> rule "Start capacity factor calculation"
> 	salience 20
> when
> 	featureQuoteRequest: FeatureQuoteRequest(feature == 'CAPACITY_FACTOR',
> priceAmount == null);
> 	account: Account();
> 	usageItem: EstimatedElectricUsage() from
> account.getElectricUsageEstimation(1,6);
> then
> 	insert (usageItem);
> 	drools.setFocus("monthly_capacity_factor"); 
> end
> 
> 
> rule "Get monthly Capacity factor"
> 	agenda-group 'monthly_capacity_factor'
> when
> 	featureQuoteRequest: FeatureQuoteRequest(feature == 'CAPACITY_FACTOR',
> priceAmount == null);
> 	account: Account();
> 	usage: EstimatedElectricUsage();
> then
> 	auxDecimal1.add(usage.getValue() * 2 + 1);
> 	retract(usage);
> end
>  
> rule "Get total Capacity factor"
> 	salience 10
> when
> 	featureQuoteRequest: FeatureQuoteRequest(feature == 'CAPACITY_FACTOR',
> priceAmount == null);
> 	account: Account();
> 	totalEstimatedElectricUsage: Double() from
> accumulate(EstimatedElectricUsage (value: value) from
> account.getElectricUsageEstimation(1,6), sum(value));
> then
> 
> featureQuoteRequest.setPriceAmount(auxDecimal1.getValue()/totalEstimatedElectricUsage);
> end
> 
> 
> #second rule group to calculate the Transmision Factor
> rule "Start transmision factor calculation"
> 	salience 20
> when
> 	featureQuoteRequest: FeatureQuoteRequest(feature == 'TRANSMISION_FACTOR',
> priceAmount == null);
> 	account: Account();
> 	usageItem: EstimatedElectricUsage() from
> account.getElectricUsageEstimation(1,6);
> then
> 	insert (usageItem);
> 	drools.setFocus("monthly_transmision_factor"); 
> end
> 
> rule "Get monthly Transmision factor"
> 	agenda-group 'monthly_transmision_factor'
> when
> 	featureQuoteRequest: FeatureQuoteRequest(feature == 'TRANSMISION_FACTOR',
> priceAmount == null);
> 	account: Account();
> 	usage: EstimatedElectricUsage();
> then
> 	auxDecimal1.add(usage.getValue() * 2 + 1);
> 	retract(usage);
> end
>  
> rule "Get total Transmision factor"
> 	salience 10
> when
> 	featureQuoteRequest: FeatureQuoteRequest(feature == 'TRANSMISION_FACTOR',
> priceAmount == null);
> 	account: Account();
> 	totalEstimatedElectricUsage: Double() from
> accumulate(EstimatedElectricUsage (value: value) from
> account.getElectricUsageEstimation(1,6), sum(value));
> then
> 
> featureQuoteRequest.setPriceAmount(auxDecimal1.getValue()/totalEstimatedElectricUsage);
> end
> 
> ####################END RULE FILE (pricing.drl)##########################
> 
> 
> 
> 
> And I have the nex class to process the rules:
> 
> ####################BEGIN JAVA CLASS FILE ##########################
> 1. package com.company;
> 2. 
> 3. import java.io.InputStreamReader;
> 4. import java.io.Reader;
> 5. import java.util.ArrayList;
> 6. import java.util.List;
> 7. 
> 8. import org.drools.FactHandle;
> 9. import org.drools.RuleBase;
> 10. import org.drools.RuleBaseFactory;
> 11. import org.drools.WorkingMemory;
> 12. import org.drools.audit.WorkingMemoryFileLogger;
> 13. import org.drools.compiler.PackageBuilder;
> 14. import org.drools.rule.Package;
> 15. 
> 16. public class PricingCalc {
> 17. 
> 18. 		FactHandle handleQuoteRequest = null;
> 19.		FactHandle handleAccount = null;
> 20.	
> 21.		public PricingCalc() {
> 22.		}
> 23.
> 24.	 	public static final void main(String[] args) {
> 25.	        PricingCalc pricingCalc = new PricingCalc();
> 26.	        pricingCalc.runPricingCalc();
> 27.	    }
> 28.
> 29.	 	private void runPricingCalc(){
> 30.	 		try {
> 31.	        	
> 32.	        	//load up the rulebase
> 33.	            RuleBase ruleBase = readRule();
> 34.	            WorkingMemory workingMemory =
> ruleBase.newStatefulSession();
> 35.	            
> 36.	            WorkingMemoryFileLogger logger = new
> WorkingMemoryFileLogger(workingMemory);
> 37.	            logger.setFileName("log/event");
> 38.
> 39.	            workingMemory.setGlobal("auxDecimal1", new AuxDecimal(new
> Double(0)));
> 40.	            //go to calculate capacity Factor!
> 41.	            setWorkingMemoryCapacity(workingMemory);
> 42.	            
> 43.	            workingMemory.fireAllRules();   
> 44.	            
> 45.	            workingMemory.retract(handleQuoteRequest);
> 46.	            workingMemory.retract(handleAccount);
> 47.
> 48	            //go to calculate Transmision Factor!
> 49	            setWorkingMemoryTransmision(workingMemory);
> 50	            
> 51	            workingMemory.fireAllRules();   
> 52	            
> 53	            workingMemory.retract(handleQuoteRequest);
> 54	            workingMemory.retract(handleAccount);
> 55	            
> 56	            
> 57	            // stop logging
> 58	            logger.writeToDisk();
> 59	            
> 60	        } catch (Throwable t) {
> 61	            t.printStackTrace();
> 62	        }	 		
> 63	 	}
> 64	 
> 65		private static RuleBase readRule() throws Exception {
> 66			//read in the source
> 67			Reader source = new InputStreamReader(
> PricingCalc.class.getResourceAsStream( "/Pricing.drl" ) );
> 68			
> 69			PackageBuilder builder = new PackageBuilder();
> 70
> 71			//this wil parse and compile in one step
> 72			//NOTE: There are 2 methods here, the one argument one is for normal
> DRL.
> 73			builder.addPackageFromDrl( source );
> 74
> 75			//get the compiled package (which is serializable)
> 76			Package pkg = builder.getPackage();
> 77			
> 78			//add the package to a rulebase (deploy the rule package).
> 79			RuleBase ruleBase = RuleBaseFactory.newRuleBase();
> 80			ruleBase.addPackage( pkg );
> 81			return ruleBase;
> 82		}	
> 83		
> 84		
> 85		private void setWorkingMemoryCapacity(WorkingMemory workingMemory){
> 86			//Setting FeatureQuoteRequest
> 87			FeatureQuoteRequest featureQuoteRequest = new FeatureQuoteRequest();
> 88			featureQuoteRequest.setFeature("CAPACITY_FACTOR");
> 89			
> 90			//Setting Account Estimated Electric Usage
> 91			Account account = new Account();
> 92			List<EstimatedElectricUsage> electricUsageEstimation = new
> ArrayList<EstimatedElectricUsage>();
> 93			
> 94			EstimatedElectricUsage estimatedElectricUsage1 = new
> EstimatedElectricUsage();
> 95			estimatedElectricUsage1.setMes(1);
> 96			estimatedElectricUsage1.setValue(new Double(10));
> 97			electricUsageEstimation.add(estimatedElectricUsage1);
> 98
> 99			EstimatedElectricUsage estimatedElectricUsage2 = new
> EstimatedElectricUsage();
> 100			estimatedElectricUsage2.setMes(2);
> 101			estimatedElectricUsage2.setValue(new Double(20));
> 102			electricUsageEstimation.add(estimatedElectricUsage2);
> 103
> 104			EstimatedElectricUsage estimatedElectricUsage3 = new
> EstimatedElectricUsage();
> 105			estimatedElectricUsage3.setMes(3);
> 106			estimatedElectricUsage3.setValue(new Double(30));
> 107			electricUsageEstimation.add(estimatedElectricUsage3);
> 108
> 109			EstimatedElectricUsage estimatedElectricUsage4 = new
> EstimatedElectricUsage();
> 110			estimatedElectricUsage4.setMes(4);
> 111			estimatedElectricUsage4.setValue(new Double(40));
> 112			electricUsageEstimation.add(estimatedElectricUsage4);			
> 113
> 114			EstimatedElectricUsage estimatedElectricUsage5 = new
> EstimatedElectricUsage();
> 115			estimatedElectricUsage5.setMes(5);
> 116			estimatedElectricUsage5.setValue(new Double(50));
> 117			electricUsageEstimation.add(estimatedElectricUsage5);			
> 118
> 119			EstimatedElectricUsage estimatedElectricUsage6 = new
> EstimatedElectricUsage();
> 120			estimatedElectricUsage6.setMes(6);
> 121			estimatedElectricUsage6.setValue(new Double(60));
> 122			electricUsageEstimation.add(estimatedElectricUsage6);			
> 123
> 124			EstimatedElectricUsage estimatedElectricUsage7 = new
> EstimatedElectricUsage();
> 125			estimatedElectricUsage7.setMes(7);
> 126			estimatedElectricUsage7.setValue(new Double(70));
> 127			electricUsageEstimation.add(estimatedElectricUsage7);
> 128			
> 129			account.setElectricUsageEstimation(electricUsageEstimation);
> 130			
> 131			handleQuoteRequest = workingMemory.insert(featureQuoteRequest);
> 132			handleAccount = workingMemory.insert(account);
> 133		}
> 134
> 135		private void setWorkingMemoryTransmision(WorkingMemory
> workingMemory){
> 136			//Setting FeatureQuoteRequest
> 137			FeatureQuoteRequest featureQuoteRequest = new FeatureQuoteRequest();
> 138			featureQuoteRequest.setFeature("TRANSMISION_FACTOR");
> 139			
> 140			//Setting Account Estimated Electric Usage
> 141			Account account = new Account();
> 142			List<EstimatedElectricUsage> electricUsageEstimation = new
> ArrayList<EstimatedElectricUsage>();
> 143			
> 144			EstimatedElectricUsage estimatedElectricUsage1 = new
> EstimatedElectricUsage();
> 145			estimatedElectricUsage1.setMes(1);
> 146			estimatedElectricUsage1.setValue(new Double(110));
> 147			electricUsageEstimation.add(estimatedElectricUsage1);
> 148
> 149			EstimatedElectricUsage estimatedElectricUsage2 = new
> EstimatedElectricUsage();
> 150			estimatedElectricUsage2.setMes(2);
> 151			estimatedElectricUsage2.setValue(new Double(120));
> 152			electricUsageEstimation.add(estimatedElectricUsage2);
> 153
> 154			EstimatedElectricUsage estimatedElectricUsage3 = new
> EstimatedElectricUsage();
> 155			estimatedElectricUsage3.setMes(3);
> 156			estimatedElectricUsage3.setValue(new Double(130));
> 157			electricUsageEstimation.add(estimatedElectricUsage3);
> 158
> 159			EstimatedElectricUsage estimatedElectricUsage4 = new
> EstimatedElectricUsage();
> 160			estimatedElectricUsage4.setMes(4);
> 161			estimatedElectricUsage4.setValue(new Double(140));
> 162			electricUsageEstimation.add(estimatedElectricUsage4);			
> 163
> 164			EstimatedElectricUsage estimatedElectricUsage5 = new
> EstimatedElectricUsage();
> 165			estimatedElectricUsage5.setMes(5);
> 166			estimatedElectricUsage5.setValue(new Double(150));
> 167			electricUsageEstimation.add(estimatedElectricUsage5);			
> 168
> 169			EstimatedElectricUsage estimatedElectricUsage6 = new
> EstimatedElectricUsage();
> 170			estimatedElectricUsage6.setMes(6);
> 171			estimatedElectricUsage6.setValue(new Double(160));
> 172			electricUsageEstimation.add(estimatedElectricUsage6);			
> 173
> 174			EstimatedElectricUsage estimatedElectricUsage7 = new
> EstimatedElectricUsage();
> 175			estimatedElectricUsage7.setMes(7);
> 176			estimatedElectricUsage7.setValue(new Double(170));
> 177			electricUsageEstimation.add(estimatedElectricUsage7);
> 178			
> 179			account.setElectricUsageEstimation(electricUsageEstimation);
> 180			
> 181			handleQuoteRequest = workingMemory.insert(featureQuoteRequest);
> 182			handleAccount = workingMemory.insert(account);
> 183		}
> 184	
> 185  }
> ####################END JAVA CLASS FILE ##########################
> 
> I'm using Drools 4.0.7
> 
> The problem is, that many activations are create (one for every
> EstimatedElectricUsage) everytime I retract the first object from the
> working memory (lines 45 and 53) You can see the activations created, and
> immediately cancelled, in the file event.log attached to this post.
> http://www.nabble.com/file/p23381763/event.log event.log  (open this file
> in the Audit View of Eclipse Plugin for a better read)
> 
> If I put the "lock-on-active true" for rule "Get total Capacity factor"
> then activations are not created when corresponding objects are retracted
> (line 45, 46) but It doesn't work for rule "Get total Transmision factor".
> See event2.log file for detail. 
> http://www.nabble.com/file/p23381763/event2.log event2.log 
> 
> Adding "lock-on-active true" for rule "Get total Transmision factor"
> doesn't resolve the activations for lines 53 and 54.
> 
> When the objects are retracted none of the rules should get activate,
> becaouse the rules depend on the existance of the objects retracted.
> 
> finally, sorry if my English is not so good, Ask me, If you have any
> question to clarify mi problem.
> 
> This is my example project if you want to reproduce the case.
>  http://www.nabble.com/file/p23381763/drools.zip drools.zip 
> 
> Thanks,
> 
> 

-- 
View this message in context: http://www.nabble.com/Avoid-unnecessary-rule-activation-when-object-is-retracted-tp23381763p23450600.html
Sent from the drools - user mailing list archive at Nabble.com.




More information about the rules-users mailing list