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

lsilva lesilvav at gmail.com
Tue May 5 10:09:44 EDT 2009


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-tp23381763p23381763.html
Sent from the drools - user mailing list archive at Nabble.com.




More information about the rules-users mailing list