[jboss-svn-commits] JBL Code SVN: r16111 - in labs/jbossrules/trunk/drools-analytics/src: main/java/org/drools/analytics/components and 9 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Sat Oct 27 04:56:56 EDT 2007


Author: Rikkola
Date: 2007-10-27 04:56:56 -0400 (Sat, 27 Oct 2007)
New Revision: 16111

Added:
   labs/jbossrules/trunk/drools-analytics/src/main/resources/org/drools/analytics/optimisation/
   labs/jbossrules/trunk/drools-analytics/src/main/resources/org/drools/analytics/optimisation/RestrictionOrder.drl
   labs/jbossrules/trunk/drools-analytics/src/test/java/org/drools/analytics/optimisation/
   labs/jbossrules/trunk/drools-analytics/src/test/java/org/drools/analytics/optimisation/RestrictionOrderTest.java
   labs/jbossrules/trunk/drools-analytics/src/test/resources/org/drools/analytics/optimisation/
   labs/jbossrules/trunk/drools-analytics/src/test/resources/org/drools/analytics/optimisation/OptimisationRestrictionOrderTest.drl
Modified:
   labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/PackageDescrFlattener.java
   labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/RuleLoader.java
   labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/Solvers.java
   labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsComponent.java
   labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsEvalDescr.java
   labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsPredicateDescr.java
   labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsRule.java
   labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/Constraint.java
   labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/LiteralRestriction.java
   labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/OperatorDescr.java
   labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/Restriction.java
   labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsData.java
   labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsDataFactory.java
   labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsDataMaps.java
   labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/report/components/AnalyticsMessageBase.java
   labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/report/components/Cause.java
   labs/jbossrules/trunk/drools-analytics/src/main/resources/org/drools/analytics/rangeChecks/Integers.drl
   labs/jbossrules/trunk/drools-analytics/src/test/java/org/drools/analytics/AnalyticsTestStandalone.java
   labs/jbossrules/trunk/drools-analytics/src/test/java/org/drools/analytics/PatternSolverTest.java
   labs/jbossrules/trunk/drools-analytics/src/test/java/org/drools/analytics/SolversTest.java
Log:
Added optimilisation rules. Now informs that eval should be last and that the most declarative restriction should be first.

Modified: labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/PackageDescrFlattener.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/PackageDescrFlattener.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/PackageDescrFlattener.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -1,7 +1,6 @@
 package org.drools.analytics;
 
 import java.util.Collection;
-import java.util.Stack;
 
 import org.drools.analytics.components.AnalyticsAccessorDescr;
 import org.drools.analytics.components.AnalyticsAccumulateDescr;
@@ -67,8 +66,6 @@
 
 	private Solvers solvers = new Solvers();
 
-	private Stack<AnalyticsComponent> components = new Stack<AnalyticsComponent>();
-
 	private RulePackage currentPackage = null;
 	private AnalyticsRule currentRule = null;
 	private Pattern currentPattern = null;
@@ -83,107 +80,118 @@
 		formPossibilities();
 	}
 
-	private void flatten(Collection<Object> descrs) {
+	private void flatten(Collection<Object> descrs, AnalyticsComponent parent) {
 
+		int orderNumber = 0;
+
 		for (Object o : descrs) {
 			BaseDescr descr = (BaseDescr) o;
 			if (descr instanceof PackageDescr) {
 				flatten((PackageDescr) descr);
 			} else if (descr instanceof RuleDescr) {
-				flatten((RuleDescr) descr);
+				flatten((RuleDescr) descr, parent);
 			} else if (descr instanceof PatternDescr) {
-				flatten((PatternDescr) descr);
+				flatten((PatternDescr) descr, parent, orderNumber);
 			} else if (descr instanceof VariableRestrictionDescr) {
-				flatten((VariableRestrictionDescr) descr);
+				flatten((VariableRestrictionDescr) descr, parent, orderNumber);
 			} else if (descr instanceof FieldBindingDescr) {
-				flatten((FieldBindingDescr) descr);
+				flatten((FieldBindingDescr) descr, parent, orderNumber);
 			} else if (descr instanceof FieldConstraintDescr) {
-				flatten((FieldConstraintDescr) descr);
+				flatten((FieldConstraintDescr) descr, parent, orderNumber);
 			} else if (descr instanceof RestrictionConnectiveDescr) {
-				flatten((RestrictionConnectiveDescr) descr);
+				flatten((RestrictionConnectiveDescr) descr, parent, orderNumber);
 			} else if (descr instanceof LiteralRestrictionDescr) {
-				flatten((LiteralRestrictionDescr) descr);
+				flatten((LiteralRestrictionDescr) descr, parent, orderNumber);
 			} else if (descr instanceof ReturnValueRestrictionDescr) {
-				flatten((ReturnValueRestrictionDescr) descr);
+				flatten((ReturnValueRestrictionDescr) descr, parent,
+						orderNumber);
 			} else if (descr instanceof QualifiedIdentifierRestrictionDescr) {
-				flatten((QualifiedIdentifierRestrictionDescr) descr);
+				flatten((QualifiedIdentifierRestrictionDescr) descr, parent,
+						orderNumber);
 			} else if (descr instanceof FunctionCallDescr) {
-				flatten((FunctionCallDescr) descr);
+				flatten((FunctionCallDescr) descr, parent, orderNumber);
 			} else if (descr instanceof PredicateDescr) {
-				flatten((PredicateDescr) descr);
+				flatten((PredicateDescr) descr, parent, orderNumber);
 			} else if (descr instanceof AccessorDescr) {
-				flatten((AccessorDescr) descr);
+				flatten((AccessorDescr) descr, parent, orderNumber);
 			} else if (descr instanceof MethodAccessDescr) {
-				flatten((MethodAccessDescr) descr);
+				flatten((MethodAccessDescr) descr, parent, orderNumber);
 			} else if (descr instanceof FieldAccessDescr) {
-				flatten((FieldAccessDescr) descr);
+				flatten((FieldAccessDescr) descr, parent, orderNumber);
 			} else if (descr instanceof PatternSourceDescr) {
-				flatten((PatternSourceDescr) descr);
+				flatten((PatternSourceDescr) descr, parent);
 			} else if (descr instanceof ConditionalElementDescr) {
-				flatten((ConditionalElementDescr) descr);
+				flatten((ConditionalElementDescr) descr, parent, orderNumber);
 			}
+
+			orderNumber++;
 		}
 	}
 
-	private AnalyticsComponent flatten(PatternSourceDescr descr) {
+	private AnalyticsComponent flatten(PatternSourceDescr descr,
+			AnalyticsComponent parent) {
 		if (descr instanceof AccumulateDescr) {
-			return flatten((AccumulateDescr) descr);
+			return flatten((AccumulateDescr) descr, parent);
 		} else if (descr instanceof CollectDescr) {
-			return flatten((CollectDescr) descr);
+			return flatten((CollectDescr) descr, parent);
 		} else if (descr instanceof FromDescr) {
-			return flatten((FromDescr) descr);
+			return flatten((FromDescr) descr, parent);
 		}
+
 		return null;
 	}
 
-	private AnalyticsComponent flatten(DeclarativeInvokerDescr descr) {
+	private AnalyticsComponent flatten(DeclarativeInvokerDescr descr,
+			AnalyticsComponent parent) {
 		if (descr instanceof AccessorDescr) {
-			return flatten((AccessorDescr) descr);
+			return flatten((AccessorDescr) descr, parent);
 		} else if (descr instanceof FieldAccessDescr) {
-			return flatten((FieldAccessDescr) descr);
+			return flatten((FieldAccessDescr) descr, parent);
 		} else if (descr instanceof FunctionCallDescr) {
-			return flatten((FunctionCallDescr) descr);
+			return flatten((FunctionCallDescr) descr, parent);
 		} else if (descr instanceof MethodAccessDescr) {
-			return flatten((MethodAccessDescr) descr);
+			return flatten((MethodAccessDescr) descr, parent);
 		}
+
 		return null;
 	}
 
-	private void flatten(ConditionalElementDescr descr) {
+	private void flatten(ConditionalElementDescr descr,
+			AnalyticsComponent parent, int orderNumber) {
 		if (descr instanceof AndDescr) {
-			flatten((AndDescr) descr);
+			flatten((AndDescr) descr, parent, orderNumber);
 		} else if (descr instanceof CollectDescr) {
-			flatten((CollectDescr) descr);
+			flatten((CollectDescr) descr, parent, orderNumber);
 		} else if (descr instanceof EvalDescr) {
-			flatten((EvalDescr) descr);
+			flatten((EvalDescr) descr, parent, orderNumber);
 		} else if (descr instanceof ExistsDescr) {
-			flatten((ExistsDescr) descr);
+			flatten((ExistsDescr) descr, parent);
 		} else if (descr instanceof ForallDescr) {
-			flatten((ForallDescr) descr);
+			flatten((ForallDescr) descr, parent);
 		} else if (descr instanceof FromDescr) {
-			flatten((FromDescr) descr);
+			flatten((FromDescr) descr, parent);
 		} else if (descr instanceof NotDescr) {
-			flatten((NotDescr) descr);
+			flatten((NotDescr) descr, parent);
 		} else if (descr instanceof OrDescr) {
-			flatten((OrDescr) descr);
+			flatten((OrDescr) descr, parent, orderNumber);
 		}
 	}
 
-	private void flatten(ForallDescr descr) {
+	private void flatten(ForallDescr descr, AnalyticsComponent parent) {
 		solvers.startForall();
-		flatten(descr.getDescrs());
+		flatten(descr.getDescrs(), parent);
 		solvers.endForall();
 	}
 
-	private void flatten(ExistsDescr descr) {
+	private void flatten(ExistsDescr descr, AnalyticsComponent parent) {
 		solvers.startExists();
-		flatten(descr.getDescrs());
+		flatten(descr.getDescrs(), parent);
 		solvers.endExists();
 	}
 
-	private void flatten(NotDescr descr) {
+	private void flatten(NotDescr descr, AnalyticsComponent parent) {
 		solvers.startNot();
-		flatten(descr.getDescrs());
+		flatten(descr.getDescrs(), parent);
 		solvers.endNot();
 	}
 
@@ -193,10 +201,13 @@
 	 * @param descr
 	 * @return
 	 */
-	private AnalyticsFunctionCallDescr flatten(FunctionCallDescr descr) {
+	private AnalyticsFunctionCallDescr flatten(FunctionCallDescr descr,
+			AnalyticsComponent parent, int orderNumber) {
 		AnalyticsFunctionCallDescr functionCall = new AnalyticsFunctionCallDescr();
 		functionCall.setName(descr.getName());
 		functionCall.setArguments(descr.getArguments());
+		functionCall.setOrderNumber(orderNumber);
+		functionCall.setParent(parent);
 
 		return functionCall;
 	}
@@ -207,11 +218,20 @@
 	 * @param descr
 	 * @return
 	 */
-	private AnalyticsPredicateDescr flatten(PredicateDescr descr) {
+	private AnalyticsPredicateDescr flatten(PredicateDescr descr,
+			AnalyticsComponent parent, int orderNumber) {
+		AnalyticsData data = AnalyticsDataFactory.getAnalyticsData();
+
 		AnalyticsPredicateDescr predicate = new AnalyticsPredicateDescr();
+		predicate.setRuleName(currentRule.getRuleName());
+		predicate.setRuleId(currentRule.getId());
 		predicate.setContent(descr.getContent().toString());
 		predicate.setClassMethodName(descr.getClassMethodName());
+		predicate.setOrderNumber(orderNumber);
+		predicate.setParent(parent);
 
+		data.save(predicate);
+
 		return predicate;
 	}
 
@@ -221,11 +241,18 @@
 	 * @param descr
 	 * @return
 	 */
-	private AnalyticsEvalDescr flatten(EvalDescr descr) {
+	private AnalyticsEvalDescr flatten(EvalDescr descr,
+			AnalyticsComponent parent, int orderNumber) {
+		AnalyticsData data = AnalyticsDataFactory.getAnalyticsData();
+
 		AnalyticsEvalDescr eval = new AnalyticsEvalDescr();
 		eval.setContent(descr.getContent().toString());
 		eval.setClassMethodName(descr.getClassMethodName());
+		eval.setOrderNumber(orderNumber);
+		eval.setParent(parent);
 
+		data.save(eval);
+
 		return eval;
 	}
 
@@ -235,20 +262,24 @@
 	 * @param descr
 	 * @return
 	 */
-	private AnalyticsFromDescr flatten(FromDescr descr) {
+	private AnalyticsFromDescr flatten(FromDescr descr,
+			AnalyticsComponent parent) {
 		AnalyticsFromDescr from = new AnalyticsFromDescr();
 
-		AnalyticsComponent ds = flatten(descr.getDataSource());
+		AnalyticsComponent ds = flatten(descr.getDataSource(), from);
 		from.setDataSourceId(ds.getId());
 		from.setDataSourceType(ds.getComponentType());
+		from.setParent(parent);
 
 		return from;
 	}
 
-	private AnalyticsAccumulateDescr flatten(AccumulateDescr descr) {
+	private AnalyticsAccumulateDescr flatten(AccumulateDescr descr,
+			AnalyticsComponent parent) {
 		AnalyticsAccumulateDescr accumulate = new AnalyticsAccumulateDescr();
 
-		accumulate.setInputPatternId(flatten(descr.getInputPattern()));
+		accumulate.setInputPatternId(flatten(descr.getInputPattern(),
+				accumulate, 0));
 		accumulate.setInitCode(descr.getInitCode());
 		accumulate.setActionCode(descr.getActionCode());
 		accumulate.setReverseCode(descr.getReverseCode());
@@ -261,20 +292,27 @@
 		accumulate.setExternalFunction(descr.isExternalFunction());
 		accumulate.setFunctionIdentifier(descr.getFunctionIdentifier());
 		accumulate.setExpression(descr.getExpression());
+		accumulate.setParent(parent);
 
 		return accumulate;
 	}
 
-	private AnalyticsCollectDescr flatten(CollectDescr descr) {
+	private AnalyticsCollectDescr flatten(CollectDescr descr,
+			AnalyticsComponent parent) {
 		AnalyticsCollectDescr collect = new AnalyticsCollectDescr();
 		collect.setClassMethodName(descr.getClassMethodName());
-		collect.setInsidePatternId(flatten(descr.getInputPattern()));
+		collect
+				.setInsidePatternId(flatten(descr.getInputPattern(), collect, 0));
+		collect.setParent(parent);
 
 		return collect;
 	}
 
-	private AnalyticsAccessorDescr flatten(AccessorDescr descr) {
+	private AnalyticsAccessorDescr flatten(AccessorDescr descr,
+			AnalyticsComponent parent, int orderNumber) {
 		AnalyticsAccessorDescr accessor = new AnalyticsAccessorDescr();
+		accessor.setOrderNumber(orderNumber);
+		accessor.setParent(parent);
 		// TODO: I wonder what this descr does.
 		return accessor;
 	}
@@ -284,10 +322,14 @@
 	 * 
 	 * @param descr
 	 */
-	private AnalyticsMethodAccessDescr flatten(MethodAccessDescr descr) {
+	private AnalyticsMethodAccessDescr flatten(MethodAccessDescr descr,
+			AnalyticsComponent parent, int orderNumber) {
 		AnalyticsMethodAccessDescr accessor = new AnalyticsMethodAccessDescr();
 		accessor.setMethodName(descr.getMethodName());
 		accessor.setArguments(descr.getArguments());
+		accessor.setOrderNumber(orderNumber);
+		accessor.setParent(parent);
+
 		return accessor;
 	}
 
@@ -296,10 +338,14 @@
 	 * 
 	 * @param descr
 	 */
-	private AnalyticsFieldAccessDescr flatten(FieldAccessDescr descr) {
+	private AnalyticsFieldAccessDescr flatten(FieldAccessDescr descr,
+			AnalyticsComponent parent, int orderNumber) {
 		AnalyticsFieldAccessDescr accessor = new AnalyticsFieldAccessDescr();
 		accessor.setFieldName(descr.getFieldName());
 		accessor.setArgument(descr.getArgument());
+		accessor.setOrderNumber(orderNumber);
+		accessor.setParent(parent);
+
 		return accessor;
 	}
 
@@ -316,12 +362,10 @@
 
 		currentPackage = rulePackage;
 
-		components.push(rulePackage);
-		flatten(descr.getRules());
-		components.pop();
+		flatten(descr.getRules(), rulePackage);
 	}
 
-	private void flatten(RuleDescr descr) {
+	private void flatten(RuleDescr descr, AnalyticsComponent parent) {
 		AnalyticsData data = AnalyticsDataFactory.getAnalyticsData();
 
 		AnalyticsRule rule = new AnalyticsRule();
@@ -330,6 +374,7 @@
 		rule.setConsequence(descr.getConsequence().toString());
 		rule.setLineNumber(descr.getLine());
 		rule.setPackageId(currentPackage.getId());
+		rule.setParent(parent);
 
 		data.save(rule);
 
@@ -337,27 +382,40 @@
 		currentRule = rule;
 
 		solvers.startRuleSolver(rule);
-		flatten(descr.getLhs());
+		flatten(descr.getLhs(), rule, 0);
 		solvers.endRuleSolver();
 	}
 
-	private void flatten(OrDescr descr) {
-		OperatorDescr operatorDescr = OperatorDescr
-				.valueOf(OperatorDescr.Type.OR);
+	private void flatten(OrDescr descr, AnalyticsComponent parent,
+			int orderNumber) {
+		AnalyticsData data = AnalyticsDataFactory.getAnalyticsData();
+		OperatorDescr operatorDescr = new OperatorDescr(OperatorDescr.Type.OR);
+		operatorDescr.setOrderNumber(orderNumber);
+		operatorDescr.setParent(parent);
+
+		data.save(operatorDescr);
+
 		solvers.startOperator(operatorDescr);
-		flatten(descr.getDescrs());
+		flatten(descr.getDescrs(), operatorDescr);
 		solvers.endOperator();
 	}
 
-	private void flatten(AndDescr descr) {
-		OperatorDescr operatorDescr = OperatorDescr
-				.valueOf(OperatorDescr.Type.AND);
+	private void flatten(AndDescr descr, AnalyticsComponent parent,
+			int orderNumber) {
+		AnalyticsData data = AnalyticsDataFactory.getAnalyticsData();
+		OperatorDescr operatorDescr = new OperatorDescr(OperatorDescr.Type.AND);
+		operatorDescr.setOrderNumber(orderNumber);
+		operatorDescr.setParent(parent);
+
+		data.save(operatorDescr);
+
 		solvers.startOperator(operatorDescr);
-		flatten(descr.getDescrs());
+		flatten(descr.getDescrs(), operatorDescr);
 		solvers.endOperator();
 	}
 
-	private int flatten(PatternDescr descr) {
+	private int flatten(PatternDescr descr, AnalyticsComponent parent,
+			int orderNumber) {
 		AnalyticsData data = AnalyticsDataFactory.getAnalyticsData();
 
 		AnalyticsClass clazz = data.getClassByPackageAndName(descr
@@ -376,6 +434,8 @@
 		pattern.setPatternNot(solvers.getRuleSolver().isChildNot());
 		pattern.setPatternExists(solvers.getRuleSolver().isExists());
 		pattern.setPatternForall(solvers.getRuleSolver().isForall());
+		pattern.setOrderNumber(orderNumber);
+		pattern.setParent(parent);
 
 		data.save(pattern);
 		currentPattern = pattern;
@@ -394,7 +454,7 @@
 
 		// flatten source.
 		if (descr.getSource() != null) {
-			AnalyticsComponent source = flatten(descr.getSource());
+			AnalyticsComponent source = flatten(descr.getSource(), pattern);
 			pattern.setSourceId(source.getId());
 			pattern.setSourceType(source.getComponentType());
 		} else {
@@ -402,13 +462,14 @@
 			pattern.setSourceType(AnalyticsComponentType.NOTHING);
 		}
 		solvers.startPatternSolver(pattern);
-		flatten(descr.getConstraint());
+		flatten(descr.getConstraint(), pattern, 0);
 		solvers.endPatternSolver();
 
 		return pattern.getId();
 	}
 
-	private void flatten(FieldConstraintDescr descr) {
+	private void flatten(FieldConstraintDescr descr, AnalyticsComponent parent,
+			int orderNumber) {
 		AnalyticsData data = AnalyticsDataFactory.getAnalyticsData();
 
 		Field field = data.getFieldByClassAndFieldName(currentClass.getName(),
@@ -424,20 +485,24 @@
 
 		constraint.setRuleId(currentRule.getId());
 		constraint.setFieldId(currentField.getId());
+		constraint.setFieldName(currentField.getName());
 		constraint.setPatternId(currentPattern.getId());
 		constraint.setPatternIsNot(currentPattern.isPatternNot());
 		constraint.setFieldId(field.getId());
+		constraint.setOrderNumber(orderNumber);
+		constraint.setParent(parent);
 
 		data.save(constraint);
 
 		currentConstraint = constraint;
 
-		flatten(descr.getRestriction());
+		flatten(descr.getRestriction(), constraint, 0);
 	}
 
-	private void flatten(RestrictionConnectiveDescr descr) {
+	private void flatten(RestrictionConnectiveDescr descr,
+			AnalyticsComponent parent, int orderNumber) {
 		// TODO: check.
-		flatten(descr.getRestrictions());
+		flatten(descr.getRestrictions(), parent);
 	}
 
 	/**
@@ -445,12 +510,15 @@
 	 * 
 	 * @param descr
 	 */
-	private void flatten(FieldBindingDescr descr) {
+	private void flatten(FieldBindingDescr descr, AnalyticsComponent parent,
+			int orderNumber) {
 		AnalyticsData data = AnalyticsDataFactory.getAnalyticsData();
 
 		Variable variable = new Variable();
 		variable.setRuleId(currentRule.getId());
 		variable.setName(descr.getIdentifier());
+		variable.setOrderNumber(orderNumber);
+		variable.setParent(parent);
 
 		variable.setObjectType(AnalyticsComponentType.FIELD);
 
@@ -465,7 +533,8 @@
 	 * 
 	 * @param descr
 	 */
-	private void flatten(VariableRestrictionDescr descr) {
+	private void flatten(VariableRestrictionDescr descr,
+			AnalyticsComponent parent, int orderNumber) {
 		AnalyticsData data = AnalyticsDataFactory.getAnalyticsData();
 
 		Variable variable = data.getVariableByRuleAndVariableName(currentRule
@@ -481,6 +550,8 @@
 		restriction.setEvaluator(descr.getEvaluator());
 		restriction.setVariableId(variable.getId());
 		restriction.setVariableName(descr.getIdentifier());
+		restriction.setOrderNumber(orderNumber);
+		restriction.setParent(parent);
 
 		// Set field value, if it is unset.
 		currentField.setFieldType(Field.FieldType.VARIABLE);
@@ -494,7 +565,8 @@
 	 * 
 	 * @param descr
 	 */
-	private void flatten(ReturnValueRestrictionDescr descr) {
+	private void flatten(ReturnValueRestrictionDescr descr,
+			AnalyticsComponent parent, int orderNumber) {
 		AnalyticsData data = AnalyticsDataFactory.getAnalyticsData();
 
 		ReturnValueRestriction restriction = new ReturnValueRestriction();
@@ -509,6 +581,8 @@
 		restriction.setClassMethodName(descr.getClassMethodName());
 		restriction.setContent(descr.getContent());
 		restriction.setDeclarations(descr.getDeclarations());
+		restriction.setOrderNumber(orderNumber);
+		restriction.setParent(parent);
 
 		data.save(restriction);
 		solvers.addRestriction(restriction);
@@ -520,7 +594,8 @@
 	 * 
 	 * @param descr
 	 */
-	private void flatten(LiteralRestrictionDescr descr) {
+	private void flatten(LiteralRestrictionDescr descr,
+			AnalyticsComponent parent, int orderNumber) {
 		AnalyticsData data = AnalyticsDataFactory.getAnalyticsData();
 
 		LiteralRestriction restriction = new LiteralRestriction();
@@ -534,6 +609,8 @@
 		restriction.setFieldId(currentConstraint.getFieldId());
 		restriction.setEvaluator(descr.getEvaluator());
 		restriction.setValue(descr.getText());
+		restriction.setOrderNumber(orderNumber);
+		restriction.setParent(parent);
 
 		// Set field value, if it is unset.
 		currentField.setFieldType(restriction.getValueType());
@@ -547,7 +624,8 @@
 	 * 
 	 * @param descr
 	 */
-	private void flatten(QualifiedIdentifierRestrictionDescr descr) {
+	private void flatten(QualifiedIdentifierRestrictionDescr descr,
+			AnalyticsComponent parent, int orderNumber) {
 		AnalyticsData data = AnalyticsDataFactory.getAnalyticsData();
 
 		String text = descr.getText();
@@ -565,6 +643,8 @@
 		restriction.setVariableId(variable.getId());
 		restriction.setVariableName(text.substring(0, text.indexOf(".")));
 		restriction.setVariablePath(text.substring(text.indexOf(".")));
+		restriction.setOrderNumber(orderNumber);
+		restriction.setParent(parent);
 
 		// Set field value, if it is unset.
 		currentField.setFieldType(Field.FieldType.VARIABLE);

Modified: labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/RuleLoader.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/RuleLoader.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/RuleLoader.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -57,6 +57,8 @@
 
 		list.add(new InputStreamReader(RuleLoader.class
 				.getResourceAsStream("Consequence.drl")));
+		list.add(new InputStreamReader(RuleLoader.class
+				.getResourceAsStream("optimisation/RestrictionOrder.drl")));
 
 		// list.add(new InputStreamReader(RuleLoader.class
 		// .getResourceAsStream("redundancy/Possibilities.drl")));

Modified: labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/Solvers.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/Solvers.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/Solvers.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -118,6 +118,7 @@
 
 			possibility.setRuleId(ruleSolver.getRule().getId());
 			possibility.setRuleName(ruleSolver.getRule().getRuleName());
+			possibility.setRuleId(ruleSolver.getRule().getId());
 			possibility.setPatternId(patternSolver.getPattern().getId());
 
 			for (AnalyticsComponent descr : list) {
@@ -135,6 +136,7 @@
 
 			possibility.setRuleId(ruleSolver.getRule().getId());
 			possibility.setRuleName(ruleSolver.getRule().getRuleName());
+			possibility.setRuleId(ruleSolver.getRule().getId());
 
 			for (AnalyticsComponent descr : list) {
 				PatternPossibility patternPossibility = (PatternPossibility) descr;

Modified: labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsComponent.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsComponent.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsComponent.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -8,11 +8,14 @@
 		Comparable<AnalyticsComponent> {
 
 	protected String ruleName;
+	protected int ruleId;
 	protected int id;
 
 	protected AnalyticsComponent parent;
-	protected int orderNumber; // Order number of this instance under parent.
+	protected int orderNumber = 0; // Order number of this instance under
 
+	// parent.
+
 	public abstract AnalyticsComponentType getComponentType();
 
 	public int compareTo(AnalyticsComponent o) {
@@ -54,4 +57,12 @@
 	public void setOrderNumber(int orderNumber) {
 		this.orderNumber = orderNumber;
 	}
+
+	public int getRuleId() {
+		return ruleId;
+	}
+
+	public void setRuleId(int ruleId) {
+		this.ruleId = ruleId;
+	}
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsEvalDescr.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsEvalDescr.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsEvalDescr.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -1,10 +1,12 @@
 package org.drools.analytics.components;
 
+import org.drools.analytics.report.components.Cause;
+
 /**
  * 
  * @author Toni Rikkola
  */
-public class AnalyticsEvalDescr extends AnalyticsComponent {
+public class AnalyticsEvalDescr extends AnalyticsComponent implements Cause {
 
 	private static int index = 0;
 
@@ -20,6 +22,10 @@
 		return AnalyticsComponentType.EVAL;
 	}
 
+	public CauseType getCauseType() {
+		return CauseType.EVAL;
+	}
+
 	public String getClassMethodName() {
 		return classMethodName;
 	}

Modified: labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsPredicateDescr.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsPredicateDescr.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsPredicateDescr.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -1,10 +1,13 @@
 package org.drools.analytics.components;
 
+import org.drools.analytics.report.components.Cause;
+
 /**
  * 
  * @author Toni Rikkola
  */
-public class AnalyticsPredicateDescr extends AnalyticsComponent {
+public class AnalyticsPredicateDescr extends AnalyticsComponent implements
+		Cause {
 
 	private static int index = 0;
 
@@ -20,6 +23,10 @@
 		return AnalyticsComponentType.PREDICATE;
 	}
 
+	public CauseType getCauseType() {
+		return CauseType.PREDICATE;
+	}
+
 	public String getClassMethodName() {
 		return classMethodName;
 	}
@@ -35,4 +42,9 @@
 	public void setContent(String content) {
 		this.content = content;
 	}
+
+	@Override
+	public String toString() {
+		return "Predicate id: " + id + " content: " + content;
+	}
 }

Modified: labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsRule.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsRule.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsRule.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -20,6 +20,7 @@
 
 	public AnalyticsRule() {
 		super(index++);
+		ruleId = index;
 	}
 
 	@Override
@@ -68,6 +69,7 @@
 		AnalyticsRule clone = new AnalyticsRule();
 
 		clone.setRuleName(ruleName);
+		clone.setRuleId(ruleId);
 		clone.setRuleSalience(ruleSalience);
 		clone.setRuleAgendaGroup(ruleAgendaGroup);
 		clone.setConsequence(consequence);

Modified: labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/Constraint.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/Constraint.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/Constraint.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -1,13 +1,12 @@
 package org.drools.analytics.components;
 
-import java.io.Serializable;
+import org.drools.analytics.report.components.Cause;
 
 /**
  * 
  * @author Toni Rikkola
  */
-public class Constraint extends AnalyticsComponent implements Serializable {
-	private static final long serialVersionUID = -1564096753608593465L;
+public class Constraint extends AnalyticsComponent implements Cause {
 
 	private static int index = 0;
 
@@ -15,6 +14,7 @@
 	private int patternId;
 	private boolean patternIsNot;
 	private int fieldId;
+	private String fieldName;
 	private int lineNumber;
 
 	public Constraint() {
@@ -26,6 +26,10 @@
 		return AnalyticsComponentType.CONSTRAINT;
 	}
 
+	public CauseType getCauseType() {
+		return CauseType.CONSTRAINT;
+	}
+
 	public int getFieldId() {
 		return fieldId;
 	}
@@ -65,4 +69,17 @@
 	public void setPatternIsNot(boolean patternIsNot) {
 		this.patternIsNot = patternIsNot;
 	}
+
+	public String getFieldName() {
+		return fieldName;
+	}
+
+	public void setFieldName(String fieldName) {
+		this.fieldName = fieldName;
+	}
+
+	@Override
+	public String toString() {
+		return "Constraint id: " + id + " field name: " + fieldName;
+	}
 }

Modified: labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/LiteralRestriction.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/LiteralRestriction.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/LiteralRestriction.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -119,6 +119,6 @@
 	@Override
 	public String toString() {
 		return "LiteralRestriction from rule '" + ruleName + "' value '"
-				+ stringValue + "'";
+				+ evaluator + " " + stringValue + "'";
 	}
 }

Modified: labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/OperatorDescr.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/OperatorDescr.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/OperatorDescr.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -11,28 +11,19 @@
 
 	private static int index = 0;
 
-	private static final OperatorDescr OR_OPERATOR = new OperatorDescr(Type.OR);
-	private static final OperatorDescr AND_OPERATOR = new OperatorDescr(Type.AND);
-
 	public static enum Type {
 		AND, OR
 	};
 
 	private Type type;
 
-	private OperatorDescr() {
+	public OperatorDescr() {
 		super(index++);
 	}
 
-	public static OperatorDescr valueOf(Type type) {
-		switch (type) {
-		case OR:
-			return OR_OPERATOR;
-		case AND:
-			return AND_OPERATOR;
-		default:
-			return null;
-		}
+	public OperatorDescr(Type operatorType) {
+		super(index++);
+		this.type = operatorType;
 	}
 
 	@Override
@@ -40,12 +31,11 @@
 		return AnalyticsComponentType.OPERATOR;
 	}
 
-	private OperatorDescr(Type operatorType) {
-		super(index++);
-		this.type = operatorType;
-	}
-
 	public Type getType() {
 		return type;
 	}
+
+	public void setType(Type type) {
+		this.type = type;
+	}
 }

Modified: labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/Restriction.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/Restriction.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/components/Restriction.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -13,14 +13,14 @@
 
 	private static int index = 0;
 
-	private int ruleId;
 	private int patternId;
 	private boolean patternIsNot;
 	private int constraintId;
-	// Id of the field that this restriction is compared to.
+
+	// Id of the field that this restriction is related to.
 	private int fieldId;
 
-	private String evaluator;
+	protected String evaluator;
 
 	public Restriction() {
 		super(index++);

Modified: labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsData.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsData.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsData.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -3,10 +3,13 @@
 import java.util.Collection;
 
 import org.drools.analytics.components.AnalyticsClass;
+import org.drools.analytics.components.AnalyticsEvalDescr;
+import org.drools.analytics.components.AnalyticsPredicateDescr;
 import org.drools.analytics.components.AnalyticsRule;
 import org.drools.analytics.components.Constraint;
 import org.drools.analytics.components.Field;
 import org.drools.analytics.components.FieldClassLink;
+import org.drools.analytics.components.OperatorDescr;
 import org.drools.analytics.components.Pattern;
 import org.drools.analytics.components.PatternPossibility;
 import org.drools.analytics.components.Restriction;
@@ -74,4 +77,10 @@
 	public RulePackage getRulePackageByName(String name);
 
 	public Collection<Restriction> getRestrictionsByFieldId(int id);
+
+	public void save(OperatorDescr operatorDescr);
+
+	public void save(AnalyticsEvalDescr eval);
+
+	public void save(AnalyticsPredicateDescr predicate);
 }

Modified: labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsDataFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsDataFactory.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsDataFactory.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -20,4 +20,12 @@
 
 		return result;
 	}
+
+	public static void clearAnalyticsResult() {
+		result = new AnalyticsResultNormal();
+	}
+
+	public static void clearAnalyticsData() {
+		data = new AnalyticsDataMaps();
+	}
 }

Modified: labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsDataMaps.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsDataMaps.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsDataMaps.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -9,10 +9,13 @@
 import java.util.TreeMap;
 
 import org.drools.analytics.components.AnalyticsClass;
+import org.drools.analytics.components.AnalyticsEvalDescr;
+import org.drools.analytics.components.AnalyticsPredicateDescr;
 import org.drools.analytics.components.AnalyticsRule;
 import org.drools.analytics.components.Constraint;
 import org.drools.analytics.components.Field;
 import org.drools.analytics.components.FieldClassLink;
+import org.drools.analytics.components.OperatorDescr;
 import org.drools.analytics.components.Pattern;
 import org.drools.analytics.components.PatternPossibility;
 import org.drools.analytics.components.Restriction;
@@ -43,6 +46,9 @@
 	private Map<Integer, Constraint> constraintsById = new TreeMap<Integer, Constraint>();
 	private Map<Integer, Restriction> restrictionsById = new TreeMap<Integer, Restriction>();
 	private DataTree<Integer, Restriction> restrictionsByFieldId = new DataTree<Integer, Restriction>();
+	private Map<Integer, OperatorDescr> operatorsById = new TreeMap<Integer, OperatorDescr>();
+	private Map<Integer, AnalyticsEvalDescr> evalsById = new TreeMap<Integer, AnalyticsEvalDescr>();
+	private Map<Integer, AnalyticsPredicateDescr> predicatesById = new TreeMap<Integer, AnalyticsPredicateDescr>();
 
 	private Map<String, Variable> variablesByRuleAndVariableName = new TreeMap<String, Variable>();
 
@@ -152,6 +158,9 @@
 		objects.addAll(patternsById.values());
 		objects.addAll(constraintsById.values());
 		objects.addAll(restrictionsById.values());
+		objects.addAll(operatorsById.values());
+		objects.addAll(evalsById.values());
+		objects.addAll(predicatesById.values());
 
 		objects.addAll(patternPossibilitiesById.values());
 		objects.addAll(rulePossibilitiesById.values());
@@ -212,4 +221,16 @@
 	public Collection<Restriction> getRestrictionsByFieldId(int id) {
 		return restrictionsByFieldId.getBranch(id);
 	}
+
+	public void save(OperatorDescr operatorDescr) {
+		operatorsById.put(operatorDescr.getId(), operatorDescr);
+	}
+
+	public void save(AnalyticsEvalDescr eval) {
+		evalsById.put(eval.getId(), eval);
+	}
+
+	public void save(AnalyticsPredicateDescr predicate) {
+		predicatesById.put(predicate.getId(), predicate);
+	}
 }

Modified: labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/report/components/AnalyticsMessageBase.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/report/components/AnalyticsMessageBase.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/report/components/AnalyticsMessageBase.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -39,7 +39,7 @@
 	}
 
 	public static enum MessageType {
-		NOT_SPECIFIED, RANGE_CHECK, REDUNDANCY, SUBSUMPTION, MISSING_COMPONENT
+		NOT_SPECIFIED, RANGE_CHECK, REDUNDANCY, SUBSUMPTION, MISSING_COMPONENT, OPTIMISATION
 	}
 
 	protected Severity severity;

Modified: labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/report/components/Cause.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/report/components/Cause.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/main/java/org/drools/analytics/report/components/Cause.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -13,7 +13,10 @@
 		RESTRICTION,
 		POSSIBILITY,
 		RANGE_CHECK_CAUSE, 
-		REDUNDANCY
+		REDUNDANCY, 
+		EVAL,
+		PREDICATE, 
+		CONSTRAINT
 	}
 	
 	public int getId();

Added: labs/jbossrules/trunk/drools-analytics/src/main/resources/org/drools/analytics/optimisation/RestrictionOrder.drl
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/resources/org/drools/analytics/optimisation/RestrictionOrder.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-analytics/src/main/resources/org/drools/analytics/optimisation/RestrictionOrder.drl	2007-10-27 08:56:56 UTC (rev 16111)
@@ -0,0 +1,222 @@
+#created on: 25.10.2007
+package org.drools.analytics.optimisation.drl
+
+#list any import classes here.
+import java.util.Collection;
+import java.util.ArrayList;
+
+import org.drools.analytics.components.Restriction;
+import org.drools.analytics.components.Pattern;
+import org.drools.analytics.components.AnalyticsRule;
+import org.drools.analytics.components.OperatorDescr;
+import org.drools.analytics.components.AnalyticsPredicateDescr;
+import org.drools.analytics.components.AnalyticsComponent;
+import org.drools.analytics.components.AnalyticsComponentType;
+import org.drools.analytics.report.components.AnalyticsMessage;
+import org.drools.analytics.dao.AnalyticsResult;
+
+
+#declare any global variables here
+global AnalyticsResult result;
+
+
+# Informs that rule would be more effective if the less expensive
+# component was on the left side.
+# 
+# Type: Note
+# Example: { a:bar } < { baz == 1 } < { baz > 1 || < 1 } < { baz != 1 }
+#
+rule "Optimise restrictions inside operator"
+	when
+		$operator :OperatorDescr()
+	
+		(
+				$r1 :Restriction(
+					parent.parent == $operator,
+					( evaluator == "==" || == "matches" )
+				)
+			and
+				# There is no reason to check if there is a less expensive constraint
+				# if this one has a restriction that is more expensive.
+				not Restriction(
+					parent == $r1.parent,
+					( evaluator == ">" || == "<" || == ">=" || == "<=" || == "not matches" || == "!=" ) 
+				)
+			and
+				$r2 :Restriction(
+					parent.parent == $operator,
+					parent.orderNumber < $r1.parent.orderNumber,
+					( evaluator == ">" || == "<" || == ">=" || == "<=" || == "not matches" || == "!=" ) 
+				)
+			and
+				# The other restriction should not have any less expensive restrictions. 
+				not Restriction(
+					parent == $r2.parent,
+					( evaluator == "==" || == "matches" )
+				)
+		) or (
+				$r1 :Restriction(
+					parent.parent == $operator,
+					( evaluator == ">" || == "<" )
+				)
+			and
+				# There is no reason to check if there is a less expensive constraint
+				# if this one has a restriction that is more expensive.
+				not Restriction(
+					parent == $r1.parent,
+					( evaluator == ">=" || == "<=" || == "not matches" || == "!=" ) 
+				)
+			and
+				$r2 :Restriction(
+					parent.parent == $operator,
+					parent.orderNumber < $r1.parent.orderNumber,
+					( evaluator == ">=" || == "<=" || == "not matches" || == "!=" ) 
+				)
+			and
+				# The other restriction should not have any less expensive restrictions. 
+				not Restriction(
+					parent == $r2.parent,
+					( evaluator == "==" || == "matches" || == ">" || == "<" )
+				)
+		) or (
+				$r1 :Restriction(
+					parent.parent == $operator,
+					( evaluator == ">=" || == "<=" )
+				)
+			and
+				# There is no reason to check if there is a less expensive constraint
+				# if this one has a restriction that is more expensive.
+				not Restriction(
+					parent == $r1.parent,
+					( evaluator == "not matches" || == "!=" ) 
+				)
+			and
+				$r2 :Restriction(
+					parent.parent == $operator,
+					parent.orderNumber < $r1.parent.orderNumber,
+					( evaluator == "not matches" || == "!=" ) 
+				)
+			and
+				# The other restriction should not have any less expensive restrictions. 
+				not Restriction(
+					parent == $r2.parent,
+					( evaluator == "==" || == "matches" || == ">" || == "<" || == ">" || == "<" || == ">=" || == "<=" )
+				)
+		)
+		
+		$pattern :Pattern( 
+			id == $r1.patternId 
+		)
+	then
+		Collection list = new ArrayList();
+		list.add( $r1 ); 
+		list.add( $r2 ); 
+		result.save( new AnalyticsMessage( 
+								AnalyticsMessage.Severity.NOTE, 
+								AnalyticsMessage.MessageType.OPTIMISATION, 
+								$pattern, 
+								"Rule \"" + $r1.getRuleName() + 
+								"\" would be more effective if the more restrictive component (" + 
+								$r2 +
+								") could be before (" + 
+								$r1 + ").", 
+								list ) );
+end
+
+# Informs that rule would be more effective if the less expensive
+# component was on the left side.
+# 
+# Type: Note
+# Example: { a:bar } < { baz == 1 } < { baz > 1 || < 1 } < { baz != 1 }
+#
+rule "Optimise restrictions inside constraint"
+	when
+		(
+				$r1 :Restriction(
+					( evaluator == "==" || == "matches" )
+				)
+			and
+				$r2 :Restriction(
+					parent == $r1.parent,
+					orderNumber < $r1.orderNumber,
+					( evaluator == ">" || == "<" || == ">=" || == "<=" || == "not matches" || == "!=" ) 
+				)
+		) or (
+				$r1 :Restriction(
+					( evaluator == ">" || == "<" )
+				)
+			and
+				$r2 :Restriction(
+					parent == $r1.parent,
+					orderNumber < $r1.orderNumber,
+					( evaluator == ">=" || == "<=" || == "not matches" || == "!=" ) 
+				)
+		) or (
+				$r1 :Restriction(
+					( evaluator == ">=" || == "<=" )
+				)
+			and
+				$r2 :Restriction(
+					parent == $r1.parent,
+					orderNumber < $r1.orderNumber,
+					( evaluator == "not matches" || == "!=" ) 
+				)
+		)
+		
+		$pattern :Pattern( 
+			id == $r1.patternId 
+		)
+	then
+		Collection list = new ArrayList();
+		list.add( $r1 ); 
+		list.add( $r2 ); 
+		result.save( new AnalyticsMessage( 
+								AnalyticsMessage.Severity.NOTE, 
+								AnalyticsMessage.MessageType.OPTIMISATION, 
+								$pattern, 
+								"Rule \"" + $r1.getRuleName() + 
+								"\" would be more effective if the more restrictive component (" + 
+								$r2 +
+								") could be before (" + 
+								$r1 + ").", 
+								list ) );
+end
+
+# AnalyticsPredicateDescr should be last.
+# 
+# Type: Note
+# Example: Foo( eval( bar == 1), bar == 1 ) 
+#
+rule "Optimise predicates inside operator"
+	when
+		$operator :OperatorDescr()
+		
+		$predicate :AnalyticsPredicateDescr( 
+			parent == $operator 
+		)
+		
+		# Any other AnalyticsComponent that is not predicate or operator 
+		$other :AnalyticsComponent(
+			parent == $operator,
+			orderNumber > $predicate.orderNumber,
+			( componentType != AnalyticsComponentType.OPERATOR && != AnalyticsComponentType.PREDICATE )
+		)
+
+		$rule :AnalyticsRule( 
+			id == $predicate.ruleId 
+		)
+	then
+		Collection list = new ArrayList();
+		list.add( $predicate );
+		list.add( $other );
+		result.save( new AnalyticsMessage(
+								AnalyticsMessage.Severity.NOTE, 
+								AnalyticsMessage.MessageType.OPTIMISATION, 
+								$rule, 
+								"Rule \"" + $predicate.getRuleName() + 
+								"\" would be more effective if the less expensive component, (" + 
+								$other +
+								"), could be before (" + 
+								$predicate + ").", 
+								list ) );
+end
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-analytics/src/main/resources/org/drools/analytics/rangeChecks/Integers.drl
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/main/resources/org/drools/analytics/rangeChecks/Integers.drl	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/main/resources/org/drools/analytics/rangeChecks/Integers.drl	2007-10-27 08:56:56 UTC (rev 16111)
@@ -3,7 +3,6 @@
 
 #list any import classes here.
 import org.drools.analytics.components.*;
-import org.drools.analytics.dao.AnalyticsResult;
 import org.drools.analytics.report.components.Gap;
 
 import org.drools.analytics.dao.AnalyticsResult;

Modified: labs/jbossrules/trunk/drools-analytics/src/test/java/org/drools/analytics/AnalyticsTestStandalone.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/test/java/org/drools/analytics/AnalyticsTestStandalone.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/test/java/org/drools/analytics/AnalyticsTestStandalone.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -35,6 +35,10 @@
 					Analyzer.class.getResourceAsStream("Misc3.drl")));
 			PackageDescr descr8 = new DrlParser().parse(new InputStreamReader(
 					Analyzer.class.getResourceAsStream("ConsequenceTest.drl")));
+			PackageDescr descr9 = new DrlParser()
+					.parse(new InputStreamReader(
+							Analyzer.class
+									.getResourceAsStream("optimisation/OptimisationRestrictionOrderTest.drl")));
 
 			Analyzer a = new Analyzer();
 			// a.addPackageDescr(descr);
@@ -45,6 +49,7 @@
 			a.addPackageDescr(descr6);
 			a.addPackageDescr(descr7);
 			a.addPackageDescr(descr8);
+			a.addPackageDescr(descr9);
 			a.fireAnalysis();
 			// System.out.print(a.getResultAsPlainText());
 			// System.out.print(a.getResultAsXML());

Modified: labs/jbossrules/trunk/drools-analytics/src/test/java/org/drools/analytics/PatternSolverTest.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/test/java/org/drools/analytics/PatternSolverTest.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/test/java/org/drools/analytics/PatternSolverTest.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -8,14 +8,12 @@
 import org.drools.analytics.components.OperatorDescr;
 import org.drools.analytics.components.Pattern;
 
-
-
 import junit.framework.TestCase;
 
 /**
  * 
  * @author Toni Rikkola
- *
+ * 
  */
 public class PatternSolverTest extends TestCase {
 
@@ -35,8 +33,7 @@
 		LiteralRestriction literalRestriction = new LiteralRestriction();
 		LiteralRestriction literalRestriction2 = new LiteralRestriction();
 
-		OperatorDescr operatorDescr = OperatorDescr
-				.valueOf(OperatorDescr.Type.AND);
+		OperatorDescr operatorDescr = new OperatorDescr(OperatorDescr.Type.AND);
 		PatternSolver solver = new PatternSolver(pattern);
 
 		solver.add(operatorDescr);
@@ -67,8 +64,7 @@
 		LiteralRestriction literalRestriction = new LiteralRestriction();
 		LiteralRestriction literalRestriction2 = new LiteralRestriction();
 
-		OperatorDescr operatorDescr = OperatorDescr
-				.valueOf(OperatorDescr.Type.OR);
+		OperatorDescr operatorDescr = new OperatorDescr(OperatorDescr.Type.OR);
 		PatternSolver solver = new PatternSolver(pattern);
 
 		solver.add(operatorDescr);
@@ -103,8 +99,8 @@
 		LiteralRestriction literalRestriction2 = new LiteralRestriction();
 		LiteralRestriction literalRestriction3 = new LiteralRestriction();
 
-		OperatorDescr orDescr = OperatorDescr.valueOf(OperatorDescr.Type.OR);
-		OperatorDescr andDescr = OperatorDescr.valueOf(OperatorDescr.Type.AND);
+		OperatorDescr orDescr = new OperatorDescr(OperatorDescr.Type.OR);
+		OperatorDescr andDescr = new OperatorDescr(OperatorDescr.Type.AND);
 		PatternSolver solver = new PatternSolver(pattern);
 
 		solver.add(orDescr);
@@ -147,8 +143,8 @@
 		LiteralRestriction literalRestriction2 = new LiteralRestriction();
 		LiteralRestriction literalRestriction3 = new LiteralRestriction();
 
-		OperatorDescr orDescr = OperatorDescr.valueOf(OperatorDescr.Type.AND);
-		OperatorDescr andDescr = OperatorDescr.valueOf(OperatorDescr.Type.OR);
+		OperatorDescr orDescr = new OperatorDescr(OperatorDescr.Type.AND);
+		OperatorDescr andDescr = new OperatorDescr(OperatorDescr.Type.OR);
 		PatternSolver solver = new PatternSolver(pattern);
 
 		solver.add(orDescr);
@@ -197,9 +193,9 @@
 		LiteralRestriction literalRestriction3 = new LiteralRestriction();
 		LiteralRestriction literalRestriction4 = new LiteralRestriction();
 
-		OperatorDescr andDescr = OperatorDescr.valueOf(OperatorDescr.Type.AND);
-		OperatorDescr orDescr = OperatorDescr.valueOf(OperatorDescr.Type.OR);
-		OperatorDescr orDescr2 = OperatorDescr.valueOf(OperatorDescr.Type.OR);
+		OperatorDescr andDescr = new OperatorDescr(OperatorDescr.Type.AND);
+		OperatorDescr orDescr = new OperatorDescr(OperatorDescr.Type.OR);
+		OperatorDescr orDescr2 = new OperatorDescr(OperatorDescr.Type.OR);
 		PatternSolver solver = new PatternSolver(pattern);
 
 		solver.add(andDescr);
@@ -255,9 +251,9 @@
 		LiteralRestriction literalRestriction3 = new LiteralRestriction();
 		LiteralRestriction literalRestriction4 = new LiteralRestriction();
 
-		OperatorDescr orDescr = OperatorDescr.valueOf(OperatorDescr.Type.OR);
-		OperatorDescr andDescr = OperatorDescr.valueOf(OperatorDescr.Type.AND);
-		OperatorDescr andDescr2 = OperatorDescr.valueOf(OperatorDescr.Type.AND);
+		OperatorDescr orDescr = new OperatorDescr(OperatorDescr.Type.OR);
+		OperatorDescr andDescr = new OperatorDescr(OperatorDescr.Type.AND);
+		OperatorDescr andDescr2 = new OperatorDescr(OperatorDescr.Type.AND);
 		PatternSolver solver = new PatternSolver(pattern);
 
 		solver.add(orDescr);
@@ -307,9 +303,9 @@
 		LiteralRestriction literalRestriction3 = new LiteralRestriction();
 		LiteralRestriction literalRestriction4 = new LiteralRestriction();
 
-		OperatorDescr orDescr = OperatorDescr.valueOf(OperatorDescr.Type.OR);
-		OperatorDescr andDescr = OperatorDescr.valueOf(OperatorDescr.Type.AND);
-		OperatorDescr orDescr2 = OperatorDescr.valueOf(OperatorDescr.Type.OR);
+		OperatorDescr orDescr = new OperatorDescr(OperatorDescr.Type.OR);
+		OperatorDescr andDescr = new OperatorDescr(OperatorDescr.Type.AND);
+		OperatorDescr orDescr2 = new OperatorDescr(OperatorDescr.Type.OR);
 		PatternSolver solver = new PatternSolver(pattern);
 
 		solver.add(orDescr);
@@ -360,9 +356,9 @@
 		LiteralRestriction literalRestriction4 = new LiteralRestriction();
 		LiteralRestriction literalRestriction5 = new LiteralRestriction();
 
-		OperatorDescr andDescr = OperatorDescr.valueOf(OperatorDescr.Type.AND);
-		OperatorDescr andDescr2 = OperatorDescr.valueOf(OperatorDescr.Type.AND);
-		OperatorDescr orDescr = OperatorDescr.valueOf(OperatorDescr.Type.OR);
+		OperatorDescr andDescr = new OperatorDescr(OperatorDescr.Type.AND);
+		OperatorDescr andDescr2 = new OperatorDescr(OperatorDescr.Type.AND);
+		OperatorDescr orDescr = new OperatorDescr(OperatorDescr.Type.OR);
 		PatternSolver solver = new PatternSolver(pattern);
 
 		solver.add(andDescr);

Modified: labs/jbossrules/trunk/drools-analytics/src/test/java/org/drools/analytics/SolversTest.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/test/java/org/drools/analytics/SolversTest.java	2007-10-27 07:55:48 UTC (rev 16110)
+++ labs/jbossrules/trunk/drools-analytics/src/test/java/org/drools/analytics/SolversTest.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -43,7 +43,7 @@
 		Restriction r3 = new LiteralRestriction();
 		Restriction r4 = new LiteralRestriction();
 
-		OperatorDescr andDescr = OperatorDescr.valueOf(OperatorDescr.Type.AND);
+		OperatorDescr andDescr = new OperatorDescr(OperatorDescr.Type.AND);
 		Solvers solvers = new Solvers();
 
 		solvers.startRuleSolver(rule);
@@ -113,7 +113,7 @@
 		Restriction r = new LiteralRestriction();
 		Restriction r2 = new LiteralRestriction();
 
-		OperatorDescr andDescr = OperatorDescr.valueOf(OperatorDescr.Type.AND);
+		OperatorDescr andDescr = new OperatorDescr(OperatorDescr.Type.AND);
 		Solvers solvers = new Solvers();
 
 		solvers.startRuleSolver(rule);

Added: labs/jbossrules/trunk/drools-analytics/src/test/java/org/drools/analytics/optimisation/RestrictionOrderTest.java
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/test/java/org/drools/analytics/optimisation/RestrictionOrderTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-analytics/src/test/java/org/drools/analytics/optimisation/RestrictionOrderTest.java	2007-10-27 08:56:56 UTC (rev 16111)
@@ -0,0 +1,210 @@
+package org.drools.analytics.optimisation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.drools.StatelessSession;
+import org.drools.analytics.TestBase;
+import org.drools.analytics.components.AnalyticsComponent;
+import org.drools.analytics.components.LiteralRestriction;
+import org.drools.analytics.components.OperatorDescr;
+import org.drools.analytics.components.Pattern;
+import org.drools.analytics.components.Restriction;
+import org.drools.analytics.dao.AnalyticsDataFactory;
+import org.drools.analytics.dao.AnalyticsResult;
+import org.drools.analytics.report.components.AnalyticsMessage;
+import org.drools.analytics.report.components.AnalyticsMessageBase;
+import org.drools.analytics.report.components.Cause;
+import org.drools.base.RuleNameMatchesAgendaFilter;
+
+public class RestrictionOrderTest extends TestBase {
+
+	public void testRestrictionOrderInsideOperator() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("RestrictionOrder.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Optimise restrictions inside operator"));
+
+		// Clear data so that test data doesn't mix.
+		AnalyticsDataFactory.clearAnalyticsData();
+		Collection<? extends Object> testData = getTestData(this.getClass()
+				.getResourceAsStream("OptimisationRestrictionOrderTest.drl"));
+
+		// Clear result so that test data doesn't mix.
+		AnalyticsDataFactory.clearAnalyticsResult();
+		AnalyticsResult result = AnalyticsDataFactory.getAnalyticsResult();
+		session.setGlobal("result", result);
+
+		session.executeWithResults(testData);
+
+		Iterator<AnalyticsMessageBase> iter = result.getBySeverity(
+				AnalyticsMessageBase.Severity.NOTE).iterator();
+
+		Collection<String> ruleNames = new ArrayList<String>();
+		while (iter.hasNext()) {
+			Object o = (Object) iter.next();
+			if (o instanceof AnalyticsMessage) {
+				String name = ((AnalyticsMessage) o).getCauses().toArray(
+						new Restriction[2])[0].getRuleName();
+
+				ruleNames.add(name);
+			}
+		}
+
+		assertTrue(ruleNames.remove("Wrong descr order 1"));
+
+		if (!ruleNames.isEmpty()) {
+			for (String string : ruleNames) {
+				fail("Rule " + string + " caused an error.");
+			}
+		}
+	}
+
+	public void testRestrictionOrderInsideConstraint() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("RestrictionOrder.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Optimise restrictions inside constraint"));
+
+		Collection<Object> testData = new ArrayList<Object>();
+
+		/*
+		 * Case 1
+		 */
+		Pattern pattern1 = new Pattern();
+		testData.add(pattern1);
+
+		OperatorDescr parent1 = new OperatorDescr(OperatorDescr.Type.AND);
+
+		LiteralRestriction r1 = new LiteralRestriction();
+		r1.setPatternId(pattern1.getId());
+		r1.setParent(parent1);
+		r1.setEvaluator(">");
+		r1.setOrderNumber(1);
+		testData.add(r1);
+
+		LiteralRestriction r2 = new LiteralRestriction();
+		r2.setPatternId(pattern1.getId());
+		r2.setParent(parent1);
+		r2.setEvaluator("==");
+		r2.setOrderNumber(2);
+		testData.add(r2);
+
+		LiteralRestriction r3 = new LiteralRestriction();
+		r3.setPatternId(pattern1.getId());
+		r3.setParent(parent1);
+		r3.setEvaluator("<");
+		r3.setOrderNumber(3);
+		testData.add(r3);
+
+		/*
+		 * Case 2
+		 */
+		Pattern pattern2 = new Pattern();
+		testData.add(pattern2);
+
+		OperatorDescr parent2 = new OperatorDescr(OperatorDescr.Type.OR);
+
+		LiteralRestriction r4 = new LiteralRestriction();
+		r4.setPatternId(pattern2.getId());
+		r4.setParent(parent2);
+		r4.setEvaluator("!=");
+		r4.setOrderNumber(1);
+		testData.add(r4);
+
+		LiteralRestriction r5 = new LiteralRestriction();
+		r5.setPatternId(pattern2.getId());
+		r5.setParent(parent2);
+		r5.setEvaluator("<=");
+		r5.setOrderNumber(2);
+		testData.add(r5);
+
+		LiteralRestriction r6 = new LiteralRestriction();
+		r6.setPatternId(pattern2.getId());
+		r6.setParent(parent2);
+		r6.setEvaluator("!=");
+		r6.setOrderNumber(3);
+		testData.add(r6);
+
+		// Clear result so that test data doesn't mix.
+		AnalyticsDataFactory.clearAnalyticsResult();
+		AnalyticsResult result = AnalyticsDataFactory.getAnalyticsResult();
+		session.setGlobal("result", result);
+
+		session.executeWithResults(testData);
+
+		Iterator<AnalyticsMessageBase> iter = result.getBySeverity(
+				AnalyticsMessageBase.Severity.NOTE).iterator();
+
+		Map<Cause, Cause> pairs = new HashMap<Cause, Cause>();
+		while (iter.hasNext()) {
+			Object o = (Object) iter.next();
+			if (o instanceof AnalyticsMessage) {
+				Cause left = ((AnalyticsMessage) o).getCauses().toArray(
+						new Cause[2])[0];
+				Cause right = ((AnalyticsMessage) o).getCauses().toArray(
+						new Cause[2])[1];
+
+				pairs.put(left, right);
+			}
+		}
+
+		// Check that case 1 is here.
+		assertTrue((pairs.containsKey(r1) && pairs.get(r1).equals(r2))
+				|| pairs.containsKey(r2) && pairs.get(r2).equals(r1));
+
+		// Check that case 2 is here.
+		assertTrue((pairs.containsKey(r4) && pairs.get(r4).equals(r5))
+				|| pairs.containsKey(r5) && pairs.get(r5).equals(r4));
+
+		// Check that there is only one pair.
+		assertEquals(2, pairs.size());
+	}
+
+	public void testEvalOrderInsideOperator() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("RestrictionOrder.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Optimise predicates inside operator"));
+
+		// Clear data so that test data doesn't mix.
+		AnalyticsDataFactory.clearAnalyticsData();
+		Collection<? extends Object> testData = getTestData(this.getClass()
+				.getResourceAsStream("OptimisationRestrictionOrderTest.drl"));
+
+		// Clear result so that test data doesn't mix.
+		AnalyticsDataFactory.clearAnalyticsResult();
+		AnalyticsResult result = AnalyticsDataFactory.getAnalyticsResult();
+		session.setGlobal("result", result);
+
+		session.executeWithResults(testData);
+
+		Iterator<AnalyticsMessageBase> iter = result.getBySeverity(
+				AnalyticsMessageBase.Severity.NOTE).iterator();
+
+		Collection<String> ruleNames = new ArrayList<String>();
+		while (iter.hasNext()) {
+			Object o = (Object) iter.next();
+			if (o instanceof AnalyticsMessage) {
+				String name = ((AnalyticsMessage) o).getCauses().toArray(
+						new AnalyticsComponent[2])[0].getRuleName();
+
+				ruleNames.add(name);
+			}
+		}
+
+		assertTrue(ruleNames.remove("Wrong eval order 1"));
+
+		if (!ruleNames.isEmpty()) {
+			for (String string : ruleNames) {
+				fail("Rule " + string + " caused an error.");
+			}
+		}
+	}
+}

Added: labs/jbossrules/trunk/drools-analytics/src/test/resources/org/drools/analytics/optimisation/OptimisationRestrictionOrderTest.drl
===================================================================
--- labs/jbossrules/trunk/drools-analytics/src/test/resources/org/drools/analytics/optimisation/OptimisationRestrictionOrderTest.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-analytics/src/test/resources/org/drools/analytics/optimisation/OptimisationRestrictionOrderTest.drl	2007-10-27 08:56:56 UTC (rev 16111)
@@ -0,0 +1,24 @@
+package com.misc.someData
+
+import com.sample.DroolsTest.Message;
+
+rule "Wrong descr order 1"
+	when
+		Foo( bar > 1, bar == 1)
+	then
+		// Something
+end
+
+rule "Wrong descr order 2"
+	when
+		Foo( bar > 1 || == 1)
+	then
+		// Something
+end
+
+rule "Wrong eval order 1"
+	when
+		Foo( eval( bar == 1 ), baz == 1)
+	then
+		// Something
+end
\ No newline at end of file




More information about the jboss-svn-commits mailing list