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

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Sep 6 10:21:14 EDT 2007


Author: Rikkola
Date: 2007-09-06 10:21:13 -0400 (Thu, 06 Sep 2007)
New Revision: 14912

Added:
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/PackageDescrFlattener.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/ReportWriter.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/reports/
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/reports/RangeCheckReports.drl
   labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/SubsumptantPossibilitiesRuleTest.java
Removed:
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/RuleFlattener.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Writer.java
Modified:
   labs/jbossrules/trunk/experimental/drools-analytics/pom.xml
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Analyzer.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/LiteralRestriction.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/PatternPossibility.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Possibility.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/QualifiedIdentifierRestriction.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Restriction.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/ReturnValueRestriction.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/RulePossibility.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/VariableRestriction.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsData.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsDataMaps.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisError.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisMessage.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisNote.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisResult.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisResultNormal.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisWarning.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Cause.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Gap.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Redundancy.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckDates.drl
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckDoubles.drl
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckIntegers.drl
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/Redundancy.drl
   labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RangeCheckDatesTest.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RangeCheckDoublesTest.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RangeCheckIntegersTest.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RedundancyTest.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/TestBase.java
Log:
Structure rewrites.
Redundancy improved.
Reporting added to Range checks.

Modified: labs/jbossrules/trunk/experimental/drools-analytics/pom.xml
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/pom.xml	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/pom.xml	2007-09-06 14:21:13 UTC (rev 14912)
@@ -12,31 +12,4 @@
   <packaging>jar</packaging>
   <name>Drools :: Analytics</name>
 
-  <build/>
-
-  <repositories>
-    <repository>
-      <id>basedir</id>
-      <url>file://${basedir}/../m2_repo</url>
-    </repository>
-  </repositories>
-
-  <dependencies>
-    <!-- Internal dependencies -->
-    <dependency>
-      <groupId>org.drools</groupId>
-      <artifactId>drools-core</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>org.drools</groupId>
-      <artifactId>drools-compiler</artifactId>
-    </dependency>
-     
-    <dependency>
-      <groupId>com.thoughtworks.xstream</groupId>
-      <artifactId>xstream</artifactId>
-      <optional>true</optional>
-    </dependency>
-  </dependencies>
 </project>
\ No newline at end of file


Property changes on: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics
___________________________________________________________________
Name: svn:ignore
   + Test.java
DroolsTest.java


Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Analyzer.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Analyzer.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Analyzer.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -1,20 +1,20 @@
 package org.drools.analytics;
 
 import java.io.InputStreamReader;
-import java.io.Reader;
-import java.util.Collection;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.drools.RuleBase;
 import org.drools.RuleBaseFactory;
 import org.drools.WorkingMemory;
+import org.drools.analytics.dao.AnalyticsData;
+import org.drools.analytics.dao.AnalyticsDataMaps;
 import org.drools.analytics.result.AnalysisResultNormal;
-import org.drools.analytics.result.Writer;
+import org.drools.analytics.result.ReportWriter;
 import org.drools.compiler.PackageBuilder;
 import org.drools.lang.descr.PackageDescr;
 import org.drools.rule.Package;
 
-
-
 /**
  * 
  * @author Toni Rikkola
@@ -23,9 +23,22 @@
 
 	private AnalysisResultNormal result = new AnalysisResultNormal();
 
-	public void solvePackageDescr(PackageDescr descr) {
+	public void addPackageDescr(PackageDescr descr) {
 		try {
 
+			PackageDescrFlattener ruleFlattener = new PackageDescrFlattener();
+
+			ruleFlattener.insert(descr);
+
+		} catch (Throwable t) {
+			t.printStackTrace();
+		}
+	}
+
+	public void fireAnalysis() {
+		try {
+			AnalyticsData data = AnalyticsDataMaps.getAnalyticsDataMaps();
+
 			System.setProperty("drools.accumulate.function.validatePattern",
 					"com.analytics.accumulateFunction.ValidatePattern");
 
@@ -34,18 +47,11 @@
 
 			WorkingMemory workingMemory = ruleBase.newStatefulSession();
 
-			RuleFlattener ruleFlattener = new RuleFlattener();
-
-			ruleFlattener.insert(descr);
-
-			// Rules with relations
-			Collection<Object > objects = ruleFlattener.getDataObjects();
-			for (Object o : objects) {
+			for (Object o : data.getAll()) {
 				workingMemory.insert(o);
 			}
 
 			// Object that returns the results.
-			AnalysisResultNormal result = new AnalysisResultNormal();
 			workingMemory.setGlobal("result", result);
 			workingMemory.fireAllRules();
 
@@ -54,20 +60,13 @@
 		}
 	}
 
-	private static RuleBase readRules() throws Exception {
-		// read in the source
-		Reader source = new InputStreamReader(Analyzer.class
-				.getResourceAsStream("RangeCheckIntegers.drl"));
-
-		PackageBuilder builder = new PackageBuilder();
-
-		builder.addPackageFromDrl(source);
-
-		Package pkg = builder.getPackage();
-
-		RuleBase ruleBase = RuleBaseFactory.newRuleBase();
-		ruleBase.addPackage(pkg);
-		return ruleBase;
+	/**
+	 * Returns the analysis results as plain text.
+	 * 
+	 * @return Analysis results as plain text.
+	 */
+	public String getResultAsPlainText() {
+		return ReportWriter.writePlainText(result);
 	}
 
 	/**
@@ -76,7 +75,7 @@
 	 * @return Analysis results as XML
 	 */
 	public String getResultAsXML() {
-		return Writer.write(result);
+		return ReportWriter.writeXML(result);
 	}
 
 	/**
@@ -87,4 +86,28 @@
 	public AnalysisResultNormal getResult() {
 		return result;
 	}
+
+	private static RuleBase readRules() throws Exception {
+		// read in the source
+		List<InputStreamReader> list = new ArrayList<InputStreamReader>();
+
+		list.add(new InputStreamReader(Analyzer.class
+				.getResourceAsStream("RangeCheckIntegers.drl")));
+		list.add(new InputStreamReader(Analyzer.class
+				.getResourceAsStream("reports/RangeCheckReports.drl")));
+
+		RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+
+		for (InputStreamReader reader : list) {
+
+			PackageBuilder builder = new PackageBuilder();
+
+			builder.addPackageFromDrl(reader);
+
+			Package pkg = builder.getPackage();
+			ruleBase.addPackage(pkg);
+		}
+
+		return ruleBase;
+	}
 }

Copied: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/PackageDescrFlattener.java (from rev 14749, labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/RuleFlattener.java)
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/PackageDescrFlattener.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/PackageDescrFlattener.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -0,0 +1,574 @@
+package org.drools.analytics;
+
+import java.util.List;
+
+import org.drools.analytics.components.AnalyticsAccessorDescr;
+import org.drools.analytics.components.AnalyticsAccumulateDescr;
+import org.drools.analytics.components.AnalyticsClass;
+import org.drools.analytics.components.AnalyticsCollectDescr;
+import org.drools.analytics.components.AnalyticsComponent;
+import org.drools.analytics.components.AnalyticsComponentType;
+import org.drools.analytics.components.AnalyticsEvalDescr;
+import org.drools.analytics.components.AnalyticsFieldAccessDescr;
+import org.drools.analytics.components.AnalyticsFromDescr;
+import org.drools.analytics.components.AnalyticsFunctionCallDescr;
+import org.drools.analytics.components.AnalyticsMethodAccessDescr;
+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.LiteralRestriction;
+import org.drools.analytics.components.OperatorDescr;
+import org.drools.analytics.components.Pattern;
+import org.drools.analytics.components.PatternPossibility;
+import org.drools.analytics.components.QualifiedIdentifierRestriction;
+import org.drools.analytics.components.ReturnValueRestriction;
+import org.drools.analytics.components.RulePossibility;
+import org.drools.analytics.components.Variable;
+import org.drools.analytics.components.VariableRestriction;
+import org.drools.analytics.dao.AnalyticsData;
+import org.drools.analytics.dao.AnalyticsDataMaps;
+import org.drools.lang.descr.AccessorDescr;
+import org.drools.lang.descr.AccumulateDescr;
+import org.drools.lang.descr.AndDescr;
+import org.drools.lang.descr.BaseDescr;
+import org.drools.lang.descr.CollectDescr;
+import org.drools.lang.descr.ConditionalElementDescr;
+import org.drools.lang.descr.DeclarativeInvokerDescr;
+import org.drools.lang.descr.EvalDescr;
+import org.drools.lang.descr.ExistsDescr;
+import org.drools.lang.descr.FieldAccessDescr;
+import org.drools.lang.descr.FieldBindingDescr;
+import org.drools.lang.descr.FieldConstraintDescr;
+import org.drools.lang.descr.ForallDescr;
+import org.drools.lang.descr.FromDescr;
+import org.drools.lang.descr.FunctionCallDescr;
+import org.drools.lang.descr.LiteralRestrictionDescr;
+import org.drools.lang.descr.MethodAccessDescr;
+import org.drools.lang.descr.NotDescr;
+import org.drools.lang.descr.OrDescr;
+import org.drools.lang.descr.PackageDescr;
+import org.drools.lang.descr.PatternDescr;
+import org.drools.lang.descr.PatternSourceDescr;
+import org.drools.lang.descr.PredicateDescr;
+import org.drools.lang.descr.QualifiedIdentifierRestrictionDescr;
+import org.drools.lang.descr.RestrictionConnectiveDescr;
+import org.drools.lang.descr.ReturnValueRestrictionDescr;
+import org.drools.lang.descr.RuleDescr;
+import org.drools.lang.descr.VariableRestrictionDescr;
+
+/**
+ * @author Toni Rikkola
+ * 
+ */
+public class PackageDescrFlattener {
+
+	private Solvers solvers = new Solvers();
+
+	private AnalyticsRule currentRule = null;
+	private Pattern currentPattern = null;
+	private Constraint currentConstraint = null;
+	private AnalyticsClass currentClass = null;
+	private Field currentField = null;
+
+	public void insert(PackageDescr packageDescr) {
+		flatten(packageDescr.getRules());
+		formPossibilities();
+	}
+
+	private void flatten(List descrs) {
+
+		for (Object o : descrs) {
+			BaseDescr descr = (BaseDescr) o;
+			if (descr instanceof PackageDescr) {
+				flatten((PackageDescr) descr);
+			} else if (descr instanceof RuleDescr) {
+				flatten((RuleDescr) descr);
+			} else if (descr instanceof PatternDescr) {
+				flatten((PatternDescr) descr);
+			} else if (descr instanceof VariableRestrictionDescr) {
+				flatten((VariableRestrictionDescr) descr);
+			} else if (descr instanceof FieldBindingDescr) {
+				flatten((FieldBindingDescr) descr);
+			} else if (descr instanceof FieldConstraintDescr) {
+				flatten((FieldConstraintDescr) descr);
+			} else if (descr instanceof RestrictionConnectiveDescr) {
+				flatten((RestrictionConnectiveDescr) descr);
+			} else if (descr instanceof LiteralRestrictionDescr) {
+				flatten((LiteralRestrictionDescr) descr);
+			} else if (descr instanceof ReturnValueRestrictionDescr) {
+				flatten((ReturnValueRestrictionDescr) descr);
+			} else if (descr instanceof QualifiedIdentifierRestrictionDescr) {
+				flatten((QualifiedIdentifierRestrictionDescr) descr);
+			} else if (descr instanceof FunctionCallDescr) {
+				flatten((FunctionCallDescr) descr);
+			} else if (descr instanceof PredicateDescr) {
+				flatten((PredicateDescr) descr);
+			} else if (descr instanceof AccessorDescr) {
+				flatten((AccessorDescr) descr);
+			} else if (descr instanceof MethodAccessDescr) {
+				flatten((MethodAccessDescr) descr);
+			} else if (descr instanceof FieldAccessDescr) {
+				flatten((FieldAccessDescr) descr);
+			} else if (descr instanceof PatternSourceDescr) {
+				flatten((PatternSourceDescr) descr);
+			} else if (descr instanceof ConditionalElementDescr) {
+				flatten((ConditionalElementDescr) descr);
+			}
+		}
+	}
+
+	private AnalyticsComponent flatten(PatternSourceDescr descr) {
+		if (descr instanceof AccumulateDescr) {
+			return flatten((AccumulateDescr) descr);
+		} else if (descr instanceof CollectDescr) {
+			return flatten((CollectDescr) descr);
+		} else if (descr instanceof FromDescr) {
+			return flatten((FromDescr) descr);
+		}
+		return null;
+	}
+
+	private AnalyticsComponent flatten(DeclarativeInvokerDescr descr) {
+		if (descr instanceof AccessorDescr) {
+			return flatten((AccessorDescr) descr);
+		} else if (descr instanceof FieldAccessDescr) {
+			return flatten((FieldAccessDescr) descr);
+		} else if (descr instanceof FunctionCallDescr) {
+			return flatten((FunctionCallDescr) descr);
+		} else if (descr instanceof MethodAccessDescr) {
+			return flatten((MethodAccessDescr) descr);
+		}
+		return null;
+	}
+
+	private void flatten(ConditionalElementDescr descr) {
+		if (descr instanceof AndDescr) {
+			flatten((AndDescr) descr);
+		} else if (descr instanceof CollectDescr) {
+			flatten((CollectDescr) descr);
+		} else if (descr instanceof EvalDescr) {
+			flatten((EvalDescr) descr);
+		} else if (descr instanceof ExistsDescr) {
+			flatten((ExistsDescr) descr);
+		} else if (descr instanceof ForallDescr) {
+			flatten((ForallDescr) descr);
+		} else if (descr instanceof FromDescr) {
+			flatten((FromDescr) descr);
+		} else if (descr instanceof NotDescr) {
+			flatten((NotDescr) descr);
+		} else if (descr instanceof OrDescr) {
+			flatten((OrDescr) descr);
+		}
+	}
+
+	private void flatten(ForallDescr descr) {
+		solvers.startForall();
+		flatten(descr.getDescrs());
+		solvers.endForall();
+	}
+
+	private void flatten(ExistsDescr descr) {
+		solvers.startExists();
+		flatten(descr.getDescrs());
+		solvers.endExists();
+	}
+
+	private void flatten(NotDescr descr) {
+		solvers.startNot();
+		flatten(descr.getDescrs());
+		solvers.endNot();
+	}
+
+	/**
+	 * End
+	 * 
+	 * @param descr
+	 * @return
+	 */
+	private AnalyticsFunctionCallDescr flatten(FunctionCallDescr descr) {
+		AnalyticsFunctionCallDescr functionCall = new AnalyticsFunctionCallDescr();
+		functionCall.setName(descr.getName());
+		functionCall.setArguments(descr.getArguments());
+
+		return functionCall;
+	}
+
+	/**
+	 * End
+	 * 
+	 * @param descr
+	 * @return
+	 */
+	private AnalyticsPredicateDescr flatten(PredicateDescr descr) {
+		AnalyticsPredicateDescr predicate = new AnalyticsPredicateDescr();
+		predicate.setContent(descr.getContent().toString());
+		predicate.setClassMethodName(descr.getClassMethodName());
+
+		return predicate;
+	}
+
+	/**
+	 * End
+	 * 
+	 * @param descr
+	 * @return
+	 */
+	private AnalyticsEvalDescr flatten(EvalDescr descr) {
+		AnalyticsEvalDescr eval = new AnalyticsEvalDescr();
+		eval.setContent(descr.getContent().toString());
+		eval.setClassMethodName(descr.getClassMethodName());
+
+		return eval;
+	}
+
+	/**
+	 * End
+	 * 
+	 * @param descr
+	 * @return
+	 */
+	private AnalyticsFromDescr flatten(FromDescr descr) {
+		AnalyticsFromDescr from = new AnalyticsFromDescr();
+
+		AnalyticsComponent ds = flatten(descr.getDataSource());
+		from.setDataSourceId(ds.getId());
+		from.setDataSourceType(ds.getComponentType());
+
+		return from;
+	}
+
+	private AnalyticsAccumulateDescr flatten(AccumulateDescr descr) {
+		AnalyticsAccumulateDescr accumulate = new AnalyticsAccumulateDescr();
+
+		accumulate.setInputPatternId(flatten(descr.getInputPattern()));
+		accumulate.setInitCode(descr.getInitCode());
+		accumulate.setActionCode(descr.getActionCode());
+		accumulate.setReverseCode(descr.getReverseCode());
+		accumulate.setResultCode(descr.getResultCode());
+
+		// XXX: Array seems to be always null.
+		// accumulate.setDeclarations(descr.getDeclarations());
+
+		accumulate.setClassName(descr.getClassName());
+		accumulate.setExternalFunction(descr.isExternalFunction());
+		accumulate.setFunctionIdentifier(descr.getFunctionIdentifier());
+		accumulate.setExpression(descr.getExpression());
+
+		return accumulate;
+	}
+
+	private AnalyticsCollectDescr flatten(CollectDescr descr) {
+		AnalyticsCollectDescr collect = new AnalyticsCollectDescr();
+		collect.setClassMethodName(descr.getClassMethodName());
+		collect.setInsidePatternId(flatten(descr.getInputPattern()));
+
+		return collect;
+	}
+
+	private AnalyticsAccessorDescr flatten(AccessorDescr descr) {
+		AnalyticsAccessorDescr accessor = new AnalyticsAccessorDescr();
+		// TODO: I wonder what this descr does.
+		return accessor;
+	}
+
+	/**
+	 * End
+	 * 
+	 * @param descr
+	 */
+	private AnalyticsMethodAccessDescr flatten(MethodAccessDescr descr) {
+		AnalyticsMethodAccessDescr accessor = new AnalyticsMethodAccessDescr();
+		accessor.setMethodName(descr.getMethodName());
+		accessor.setArguments(descr.getArguments());
+		return accessor;
+	}
+
+	/**
+	 * End
+	 * 
+	 * @param descr
+	 */
+	private AnalyticsFieldAccessDescr flatten(FieldAccessDescr descr) {
+		AnalyticsFieldAccessDescr accessor = new AnalyticsFieldAccessDescr();
+		accessor.setFieldName(descr.getFieldName());
+		accessor.setArgument(descr.getArgument());
+		return accessor;
+	}
+
+	private void flatten(PackageDescr descr) {
+		flatten(descr.getRules());
+	}
+
+	private void flatten(RuleDescr descr) {
+		AnalyticsData data = AnalyticsDataMaps.getAnalyticsDataMaps();
+
+		AnalyticsRule rule = new AnalyticsRule();
+		rule.setRuleName(descr.getName());
+		rule.setRuleSalience(descr.getSalience());
+		rule.setConsequence(descr.getConsequence().toString());
+		rule.setLineNumber(descr.getLine());
+		data.insert(rule);
+
+		currentRule = rule;
+
+		solvers.startRuleSolver(rule);
+		flatten(descr.getLhs());
+		solvers.endRuleSolver();
+	}
+
+	private void flatten(OrDescr descr) {
+		OperatorDescr operatorDescr = OperatorDescr
+				.valueOf(OperatorDescr.Type.OR);
+		solvers.startOperator(operatorDescr);
+		flatten(descr.getDescrs());
+		solvers.endOperator();
+	}
+
+	private void flatten(AndDescr descr) {
+		OperatorDescr operatorDescr = OperatorDescr
+				.valueOf(OperatorDescr.Type.AND);
+		solvers.startOperator(operatorDescr);
+		flatten(descr.getDescrs());
+		solvers.endOperator();
+	}
+
+	private int flatten(PatternDescr descr) {
+		AnalyticsData data = AnalyticsDataMaps.getAnalyticsDataMaps();
+
+		AnalyticsClass clazz = data.getClassByName(descr.getObjectType());
+		if (clazz == null) {
+			clazz = new AnalyticsClass();
+			clazz.setName(descr.getObjectType());
+			data.insert(clazz);
+		}
+		currentClass = clazz;
+
+		Pattern pattern = new Pattern();
+		pattern.setRuleId(currentRule.getId());
+		pattern.setRuleName(currentRule.getRuleName());
+		pattern.setClassId(clazz.getId());
+		pattern.setPatternNot(solvers.getRuleSolver().isChildNot());
+		pattern.setPatternExists(solvers.getRuleSolver().isExists());
+		pattern.setPatternForall(solvers.getRuleSolver().isForall());
+
+		data.insert(pattern);
+		currentPattern = pattern;
+
+		if (descr.getIdentifier() != null) {
+			Variable variable = new Variable();
+			variable.setRuleId(currentRule.getId());
+			variable.setName(descr.getIdentifier());
+
+			variable.setObjectType(AnalyticsComponentType.CLASS);
+			variable.setObjectId(clazz.getId());
+			variable.setObjectName(descr.getObjectType());
+
+			data.insert(variable);
+		}
+
+		// flatten source.
+		if (descr.getSource() != null) {
+			AnalyticsComponent source = flatten(descr.getSource());
+			pattern.setSourceId(source.getId());
+			pattern.setSourceType(source.getComponentType());
+		} else {
+			pattern.setSourceId(0);
+			pattern.setSourceType(AnalyticsComponentType.NOTHING);
+		}
+		solvers.startPatternSolver(pattern);
+		flatten(descr.getConstraint());
+		solvers.endPatternSolver();
+
+		return pattern.getId();
+	}
+
+	private void flatten(FieldConstraintDescr descr) {
+		AnalyticsData data = AnalyticsDataMaps.getAnalyticsDataMaps();
+
+		Field field = data.getFieldByClassAndFieldName(currentClass.getName(),
+				descr.getFieldName());
+		if (field == null) {
+			field = createField(descr.getFieldName(), descr.getLine(),
+					currentClass.getId(), currentClass.getName());
+			data.insert(field);
+		}
+		currentField = field;
+
+		Constraint constraint = new Constraint();
+
+		constraint.setRuleId(currentRule.getId());
+		constraint.setFieldId(currentField.getId());
+		constraint.setPatternId(currentPattern.getId());
+		constraint.setPatternIsNot(currentPattern.isPatternNot());
+		constraint.setFieldId(field.getId());
+
+		data.insert(constraint);
+
+		currentConstraint = constraint;
+
+		flatten(descr.getRestriction());
+	}
+
+	private void flatten(RestrictionConnectiveDescr descr) {
+		// TODO: check.
+		flatten(descr.getRestrictions());
+	}
+
+	/**
+	 * End
+	 * 
+	 * @param descr
+	 */
+	private void flatten(FieldBindingDescr descr) {
+		AnalyticsData data = AnalyticsDataMaps.getAnalyticsDataMaps();
+
+		Variable variable = new Variable();
+		variable.setRuleId(currentRule.getId());
+		variable.setName(descr.getIdentifier());
+
+		variable.setObjectType(AnalyticsComponentType.FIELD);
+
+		data.insert(variable);
+	}
+
+	/**
+	 * End
+	 * 
+	 * Foo( bar == $bar )<br>
+	 * $bar is a VariableRestrictionDescr
+	 * 
+	 * @param descr
+	 */
+	private void flatten(VariableRestrictionDescr descr) {
+		AnalyticsData data = AnalyticsDataMaps.getAnalyticsDataMaps();
+
+		Variable variable = data.getVariableByRuleAndVariableName(currentRule
+				.getRuleName(), descr.getIdentifier());
+		VariableRestriction restriction = new VariableRestriction();
+
+		restriction.setRuleId(currentRule.getId());
+		restriction.setRuleName(currentRule.getRuleName());
+		restriction.setPatternId(currentPattern.getId());
+		restriction.setPatternIsNot(currentPattern.isPatternNot());
+		restriction.setConstraintId(currentConstraint.getId());
+		restriction.setFieldId(currentConstraint.getFieldId());
+		restriction.setEvaluator(descr.getEvaluator());
+		restriction.setVariableId(variable.getId());
+		restriction.setVariableName(descr.getIdentifier());
+
+		// Set field value, if it is unset.
+		currentField.setFieldType(Field.FieldType.VARIABLE);
+
+		data.insert(restriction);
+		solvers.addRestriction(restriction);
+	}
+
+	/**
+	 * End
+	 * 
+	 * @param descr
+	 */
+	private void flatten(ReturnValueRestrictionDescr descr) {
+		AnalyticsData data = AnalyticsDataMaps.getAnalyticsDataMaps();
+
+		ReturnValueRestriction restriction = new ReturnValueRestriction();
+
+		restriction.setRuleId(currentRule.getId());
+		restriction.setRuleName(currentRule.getRuleName());
+		restriction.setPatternId(currentPattern.getId());
+		restriction.setPatternIsNot(currentPattern.isPatternNot());
+		restriction.setConstraintId(currentConstraint.getId());
+		restriction.setFieldId(currentConstraint.getFieldId());
+		restriction.setEvaluator(descr.getEvaluator());
+		restriction.setClassMethodName(descr.getClassMethodName());
+		restriction.setContent(descr.getContent());
+		restriction.setDeclarations(descr.getDeclarations());
+
+		data.insert(restriction);
+		solvers.addRestriction(restriction);
+
+	}
+
+	/**
+	 * End
+	 * 
+	 * @param descr
+	 */
+	private void flatten(LiteralRestrictionDescr descr) {
+		AnalyticsData data = AnalyticsDataMaps.getAnalyticsDataMaps();
+
+		LiteralRestriction restriction = new LiteralRestriction();
+
+		restriction.setRuleId(currentRule.getId());
+		restriction.setRuleName(currentRule.getRuleName());
+		restriction.setRuleId(currentRule.getId());
+		restriction.setPatternId(currentPattern.getId());
+		restriction.setPatternIsNot(currentPattern.isPatternNot());
+		restriction.setConstraintId(currentConstraint.getId());
+		restriction.setFieldId(currentConstraint.getFieldId());
+		restriction.setEvaluator(descr.getEvaluator());
+		restriction.setValue(descr.getText());
+
+		// Set field value, if it is unset.
+		currentField.setFieldType(restriction.getValueType());
+
+		data.insert(restriction);
+		solvers.addRestriction(restriction);
+	}
+
+	/**
+	 * End
+	 * 
+	 * @param descr
+	 */
+	private void flatten(QualifiedIdentifierRestrictionDescr descr) {
+		AnalyticsData data = AnalyticsDataMaps.getAnalyticsDataMaps();
+
+		String text = descr.getText();
+		Variable variable = data.getVariableByRuleAndVariableName(currentRule
+				.getRuleName(), text.substring(0, text.indexOf(".")));
+
+		QualifiedIdentifierRestriction restriction = new QualifiedIdentifierRestriction();
+
+		restriction.setRuleId(currentRule.getId());
+		restriction.setPatternId(currentPattern.getId());
+		restriction.setPatternIsNot(currentPattern.isPatternNot());
+		restriction.setConstraintId(currentConstraint.getId());
+		restriction.setFieldId(currentConstraint.getFieldId());
+		restriction.setEvaluator(descr.getEvaluator());
+		restriction.setVariableId(variable.getId());
+		restriction.setVariableName(text.substring(0, text.indexOf(".")));
+		restriction.setVariablePath(text.substring(text.indexOf(".")));
+
+		// Set field value, if it is unset.
+		currentField.setFieldType(Field.FieldType.VARIABLE);
+
+		variable.setObjectType(AnalyticsComponentType.FIELD);
+
+		data.insert(restriction);
+		solvers.addRestriction(restriction);
+	}
+
+	private Field createField(String fieldName, int line, int classId,
+			String className) {
+		Field field = new Field();
+		field.setClassId(classId);
+		field.setClassName(className);
+		field.setName(fieldName);
+		field.setLineNumber(line);
+
+		return field;
+	}
+
+	private void formPossibilities() {
+		AnalyticsData data = AnalyticsDataMaps.getAnalyticsDataMaps();
+
+		for (PatternPossibility possibility : solvers.getPatternPossibilities()) {
+			data.insert(possibility);
+		}
+		for (RulePossibility possibility : solvers.getRulePossibilities()) {
+			data.insert(possibility);
+		}
+	}
+}

Deleted: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/RuleFlattener.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/RuleFlattener.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/RuleFlattener.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -1,568 +0,0 @@
-package org.drools.analytics;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.drools.analytics.components.AnalyticsAccessorDescr;
-import org.drools.analytics.components.AnalyticsAccumulateDescr;
-import org.drools.analytics.components.AnalyticsClass;
-import org.drools.analytics.components.AnalyticsCollectDescr;
-import org.drools.analytics.components.AnalyticsComponent;
-import org.drools.analytics.components.AnalyticsComponentType;
-import org.drools.analytics.components.AnalyticsEvalDescr;
-import org.drools.analytics.components.AnalyticsFieldAccessDescr;
-import org.drools.analytics.components.AnalyticsFromDescr;
-import org.drools.analytics.components.AnalyticsFunctionCallDescr;
-import org.drools.analytics.components.AnalyticsMethodAccessDescr;
-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.LiteralRestriction;
-import org.drools.analytics.components.OperatorDescr;
-import org.drools.analytics.components.Pattern;
-import org.drools.analytics.components.PatternPossibility;
-import org.drools.analytics.components.QualifiedIdentifierRestriction;
-import org.drools.analytics.components.ReturnValueRestriction;
-import org.drools.analytics.components.RulePossibility;
-import org.drools.analytics.components.Variable;
-import org.drools.analytics.components.VariableRestriction;
-import org.drools.analytics.dao.AnalyticsData;
-import org.drools.analytics.dao.AnalyticsDataMaps;
-import org.drools.lang.descr.AccessorDescr;
-import org.drools.lang.descr.AccumulateDescr;
-import org.drools.lang.descr.AndDescr;
-import org.drools.lang.descr.BaseDescr;
-import org.drools.lang.descr.CollectDescr;
-import org.drools.lang.descr.ConditionalElementDescr;
-import org.drools.lang.descr.DeclarativeInvokerDescr;
-import org.drools.lang.descr.EvalDescr;
-import org.drools.lang.descr.ExistsDescr;
-import org.drools.lang.descr.FieldAccessDescr;
-import org.drools.lang.descr.FieldBindingDescr;
-import org.drools.lang.descr.FieldConstraintDescr;
-import org.drools.lang.descr.ForallDescr;
-import org.drools.lang.descr.FromDescr;
-import org.drools.lang.descr.FunctionCallDescr;
-import org.drools.lang.descr.LiteralRestrictionDescr;
-import org.drools.lang.descr.MethodAccessDescr;
-import org.drools.lang.descr.NotDescr;
-import org.drools.lang.descr.OrDescr;
-import org.drools.lang.descr.PackageDescr;
-import org.drools.lang.descr.PatternDescr;
-import org.drools.lang.descr.PatternSourceDescr;
-import org.drools.lang.descr.PredicateDescr;
-import org.drools.lang.descr.QualifiedIdentifierRestrictionDescr;
-import org.drools.lang.descr.RestrictionConnectiveDescr;
-import org.drools.lang.descr.ReturnValueRestrictionDescr;
-import org.drools.lang.descr.RuleDescr;
-import org.drools.lang.descr.VariableRestrictionDescr;
-
-/**
- * @author Toni Rikkola
- * 
- */
-public class RuleFlattener {
-
-	private Solvers solvers = new Solvers();
-
-	private AnalyticsData data = new AnalyticsDataMaps();
-
-	private AnalyticsRule currentRule = null;
-	private Pattern currentPattern = null;
-	private Constraint currentConstraint = null;
-	private AnalyticsClass currentClass = null;
-	private Field currentField = null;
-
-	public void insert(PackageDescr packageDescr) {
-		solve(packageDescr.getRules());
-	}
-
-	private void solve(List descrs) {
-
-		for (Object o : descrs) {
-			BaseDescr descr = (BaseDescr) o;
-			if (descr instanceof PackageDescr) {
-				solve((PackageDescr) descr);
-			} else if (descr instanceof RuleDescr) {
-				solve((RuleDescr) descr);
-			} else if (descr instanceof PatternDescr) {
-				solve((PatternDescr) descr);
-			} else if (descr instanceof VariableRestrictionDescr) {
-				solve((VariableRestrictionDescr) descr);
-			} else if (descr instanceof FieldBindingDescr) {
-				solve((FieldBindingDescr) descr);
-			} else if (descr instanceof FieldConstraintDescr) {
-				solve((FieldConstraintDescr) descr);
-			} else if (descr instanceof RestrictionConnectiveDescr) {
-				solve((RestrictionConnectiveDescr) descr);
-			} else if (descr instanceof LiteralRestrictionDescr) {
-				solve((LiteralRestrictionDescr) descr);
-			} else if (descr instanceof ReturnValueRestrictionDescr) {
-				solve((ReturnValueRestrictionDescr) descr);
-			} else if (descr instanceof QualifiedIdentifierRestrictionDescr) {
-				solve((QualifiedIdentifierRestrictionDescr) descr);
-			} else if (descr instanceof FunctionCallDescr) {
-				solve((FunctionCallDescr) descr);
-			} else if (descr instanceof PredicateDescr) {
-				solve((PredicateDescr) descr);
-			} else if (descr instanceof AccessorDescr) {
-				solve((AccessorDescr) descr);
-			} else if (descr instanceof MethodAccessDescr) {
-				solve((MethodAccessDescr) descr);
-			} else if (descr instanceof FieldAccessDescr) {
-				solve((FieldAccessDescr) descr);
-			} else if (descr instanceof PatternSourceDescr) {
-				solve((PatternSourceDescr) descr);
-			} else if (descr instanceof ConditionalElementDescr) {
-				solve((ConditionalElementDescr) descr);
-			}
-		}
-	}
-
-	private AnalyticsComponent solve(PatternSourceDescr descr) {
-		if (descr instanceof AccumulateDescr) {
-			return solve((AccumulateDescr) descr);
-		} else if (descr instanceof CollectDescr) {
-			return solve((CollectDescr) descr);
-		} else if (descr instanceof FromDescr) {
-			return solve((FromDescr) descr);
-		}
-		return null;
-	}
-
-	private AnalyticsComponent solve(DeclarativeInvokerDescr descr) {
-		if (descr instanceof AccessorDescr) {
-			return solve((AccessorDescr) descr);
-		} else if (descr instanceof FieldAccessDescr) {
-			return solve((FieldAccessDescr) descr);
-		} else if (descr instanceof FunctionCallDescr) {
-			return solve((FunctionCallDescr) descr);
-		} else if (descr instanceof MethodAccessDescr) {
-			return solve((MethodAccessDescr) descr);
-		}
-		return null;
-	}
-
-	private void solve(ConditionalElementDescr descr) {
-		if (descr instanceof AndDescr) {
-			solve((AndDescr) descr);
-		} else if (descr instanceof CollectDescr) {
-			solve((CollectDescr) descr);
-		} else if (descr instanceof EvalDescr) {
-			solve((EvalDescr) descr);
-		} else if (descr instanceof ExistsDescr) {
-			solve((ExistsDescr) descr);
-		} else if (descr instanceof ForallDescr) {
-			solve((ForallDescr) descr);
-		} else if (descr instanceof FromDescr) {
-			solve((FromDescr) descr);
-		} else if (descr instanceof NotDescr) {
-			solve((NotDescr) descr);
-		} else if (descr instanceof OrDescr) {
-			solve((OrDescr) descr);
-		}
-	}
-
-	private void solve(ForallDescr descr) {
-		solvers.startForall();
-		solve(descr.getDescrs());
-		solvers.endForall();
-	}
-
-	private void solve(ExistsDescr descr) {
-		solvers.startExists();
-		solve(descr.getDescrs());
-		solvers.endExists();
-	}
-
-	private void solve(NotDescr descr) {
-		solvers.startNot();
-		solve(descr.getDescrs());
-		solvers.endNot();
-	}
-
-	/**
-	 * End
-	 * 
-	 * @param descr
-	 * @return
-	 */
-	private AnalyticsFunctionCallDescr solve(FunctionCallDescr descr) {
-		AnalyticsFunctionCallDescr functionCall = new AnalyticsFunctionCallDescr();
-		functionCall.setName(descr.getName());
-		functionCall.setArguments(descr.getArguments());
-
-		return functionCall;
-	}
-
-	/**
-	 * End
-	 * 
-	 * @param descr
-	 * @return
-	 */
-	private AnalyticsPredicateDescr solve(PredicateDescr descr) {
-		AnalyticsPredicateDescr predicate = new AnalyticsPredicateDescr();
-		predicate.setContent(descr.getContent().toString());
-		predicate.setClassMethodName(descr.getClassMethodName());
-
-		return predicate;
-	}
-
-	/**
-	 * End
-	 * 
-	 * @param descr
-	 * @return
-	 */
-	private AnalyticsEvalDescr solve(EvalDescr descr) {
-		AnalyticsEvalDescr eval = new AnalyticsEvalDescr();
-		eval.setContent(descr.getContent().toString());
-		eval.setClassMethodName(descr.getClassMethodName());
-
-		return eval;
-	}
-
-	/**
-	 * End
-	 * 
-	 * @param descr
-	 * @return
-	 */
-	private AnalyticsFromDescr solve(FromDescr descr) {
-		AnalyticsFromDescr from = new AnalyticsFromDescr();
-
-		AnalyticsComponent ds = solve(descr.getDataSource());
-		from.setDataSourceId(ds.getId());
-		from.setDataSourceType(ds.getComponentType());
-
-		return from;
-	}
-
-	private AnalyticsAccumulateDescr solve(AccumulateDescr descr) {
-		AnalyticsAccumulateDescr accumulate = new AnalyticsAccumulateDescr();
-
-		accumulate.setInputPatternId(solve(descr.getInputPattern()));
-		accumulate.setInitCode(descr.getInitCode());
-		accumulate.setActionCode(descr.getActionCode());
-		accumulate.setReverseCode(descr.getReverseCode());
-		accumulate.setResultCode(descr.getResultCode());
-
-		// XXX: Array seems to be always null.
-		// accumulate.setDeclarations(descr.getDeclarations());
-
-		accumulate.setClassName(descr.getClassName());
-		accumulate.setExternalFunction(descr.isExternalFunction());
-		accumulate.setFunctionIdentifier(descr.getFunctionIdentifier());
-		accumulate.setExpression(descr.getExpression());
-
-		return accumulate;
-	}
-
-	private AnalyticsCollectDescr solve(CollectDescr descr) {
-		AnalyticsCollectDescr collect = new AnalyticsCollectDescr();
-		collect.setClassMethodName(descr.getClassMethodName());
-		collect.setInsidePatternId(solve(descr.getInputPattern()));
-
-		return collect;
-	}
-
-	private AnalyticsAccessorDescr solve(AccessorDescr descr) {
-		AnalyticsAccessorDescr accessor = new AnalyticsAccessorDescr();
-		// TODO: I wonder what this descr does.
-		return accessor;
-	}
-
-	/**
-	 * End
-	 * 
-	 * @param descr
-	 */
-	private AnalyticsMethodAccessDescr solve(MethodAccessDescr descr) {
-		AnalyticsMethodAccessDescr accessor = new AnalyticsMethodAccessDescr();
-		accessor.setMethodName(descr.getMethodName());
-		accessor.setArguments(descr.getArguments());
-		return accessor;
-	}
-
-	/**
-	 * End
-	 * 
-	 * @param descr
-	 */
-	private AnalyticsFieldAccessDescr solve(FieldAccessDescr descr) {
-		AnalyticsFieldAccessDescr accessor = new AnalyticsFieldAccessDescr();
-		accessor.setFieldName(descr.getFieldName());
-		accessor.setArgument(descr.getArgument());
-		return accessor;
-	}
-
-	private void solve(PackageDescr descr) {
-		solve(descr.getRules());
-	}
-
-	private void solve(RuleDescr descr) {
-
-		AnalyticsRule rule = new AnalyticsRule();
-		rule.setRuleName(descr.getName());
-		rule.setRuleSalience(descr.getSalience());
-		rule.setConsequence(descr.getConsequence().toString());
-		rule.setLineNumber(descr.getLine());
-		data.insert(rule);
-
-		currentRule = rule;
-
-		solvers.startRuleSolver(rule);
-		solve(descr.getLhs());
-		solvers.endRuleSolver();
-	}
-
-	private void solve(OrDescr descr) {
-		OperatorDescr operatorDescr = OperatorDescr
-				.valueOf(OperatorDescr.Type.OR);
-		solvers.startOperator(operatorDescr);
-		solve(descr.getDescrs());
-		solvers.endOperator();
-	}
-
-	private void solve(AndDescr descr) {
-		OperatorDescr operatorDescr = OperatorDescr
-				.valueOf(OperatorDescr.Type.AND);
-		solvers.startOperator(operatorDescr);
-		solve(descr.getDescrs());
-		solvers.endOperator();
-	}
-
-	private int solve(PatternDescr descr) {
-		AnalyticsClass clazz = data.getClassByName(descr.getObjectType());
-		if (clazz == null) {
-			clazz = new AnalyticsClass();
-			clazz.setName(descr.getObjectType());
-			data.insert(clazz);
-		}
-		currentClass = clazz;
-
-		Pattern pattern = new Pattern();
-		pattern.setRuleId(currentRule.getId());
-		pattern.setRuleName(currentRule.getRuleName());
-		pattern.setClassId(clazz.getId());
-		pattern.setPatternNot(solvers.getRuleSolver().isChildNot());
-		pattern.setPatternExists(solvers.getRuleSolver().isExists());
-		pattern.setPatternForall(solvers.getRuleSolver().isForall());
-
-		data.insert(pattern);
-		currentPattern = pattern;
-
-		if (descr.getIdentifier() != null) {
-			Variable variable = new Variable();
-			variable.setRuleId(currentRule.getId());
-			variable.setName(descr.getIdentifier());
-
-			variable.setObjectType(AnalyticsComponentType.CLASS);
-			variable.setObjectId(clazz.getId());
-			variable.setObjectName(descr.getObjectType());
-
-			data.insert(variable);
-		}
-
-		// Solve source.
-		if (descr.getSource() != null) {
-			AnalyticsComponent source = solve(descr.getSource());
-			pattern.setSourceId(source.getId());
-			pattern.setSourceType(source.getComponentType());
-		} else {
-			pattern.setSourceId(0);
-			pattern.setSourceType(AnalyticsComponentType.NOTHING);
-		}
-		solvers.startPatternSolver(pattern);
-		solve(descr.getConstraint());
-		solvers.endPatternSolver();
-
-		return pattern.getId();
-	}
-
-	private void solve(FieldConstraintDescr descr) {
-		Field field = data.getFieldByClassAndFieldName(currentClass.getName(),
-				descr.getFieldName());
-		if (field == null) {
-			field = createField(descr.getFieldName(), descr.getLine(),
-					currentClass.getId(), currentClass.getName());
-			data.insert(field);
-		}
-		currentField = field;
-
-		Constraint constraint = new Constraint();
-
-		constraint.setRuleId(currentRule.getId());
-		constraint.setFieldId(currentField.getId());
-		constraint.setPatternId(currentPattern.getId());
-		constraint.setPatternIsNot(currentPattern.isPatternNot());
-		constraint.setFieldId(field.getId());
-
-		data.insert(constraint);
-
-		currentConstraint = constraint;
-
-		solve(descr.getRestriction());
-	}
-
-	private void solve(RestrictionConnectiveDescr descr) {
-		// TODO: check.
-		solve(descr.getRestrictions());
-	}
-
-	/**
-	 * End
-	 * 
-	 * @param descr
-	 */
-	private void solve(FieldBindingDescr descr) {
-		Variable variable = new Variable();
-		variable.setRuleId(currentRule.getId());
-		variable.setName(descr.getIdentifier());
-
-		variable.setObjectType(AnalyticsComponentType.FIELD);
-
-		data.insert(variable);
-	}
-
-	/**
-	 * End
-	 * 
-	 * Foo( bar == $bar )<br>
-	 * $bar is a VariableRestrictionDescr
-	 * 
-	 * @param descr
-	 */
-	private void solve(VariableRestrictionDescr descr) {
-		Variable variable = data.getVariableByRuleAndVariableName(currentRule
-				.getRuleName(), descr.getIdentifier());
-		VariableRestriction restriction = new VariableRestriction();
-
-		restriction.setRuleId(currentRule.getId());
-		restriction.setRuleName(currentRule.getRuleName());
-		restriction.setPatternId(currentPattern.getId());
-		restriction.setPatternIsNot(currentPattern.isPatternNot());
-		restriction.setConstraintId(currentConstraint.getId());
-		restriction.setFieldId(currentConstraint.getFieldId());
-		restriction.setEvaluator(descr.getEvaluator());
-		restriction.setVariableId(variable.getId());
-		restriction.setVariableName(descr.getIdentifier());
-
-		// Set field value, if it is unset.
-		currentField.setFieldType(Field.FieldType.VARIABLE);
-
-		data.insert(restriction);
-		solvers.addRestriction(restriction);
-	}
-
-	/**
-	 * End
-	 * 
-	 * @param descr
-	 */
-	private void solve(ReturnValueRestrictionDescr descr) {
-		ReturnValueRestriction restriction = new ReturnValueRestriction();
-
-		restriction.setRuleId(currentRule.getId());
-		restriction.setRuleName(currentRule.getRuleName());
-		restriction.setPatternId(currentPattern.getId());
-		restriction.setPatternIsNot(currentPattern.isPatternNot());
-		restriction.setConstraintId(currentConstraint.getId());
-		restriction.setFieldId(currentConstraint.getFieldId());
-		restriction.setEvaluator(descr.getEvaluator());
-		restriction.setClassMethodName(descr.getClassMethodName());
-		restriction.setContent(descr.getContent());
-		restriction.setDeclarations(descr.getDeclarations());
-
-		data.insert(restriction);
-		solvers.addRestriction(restriction);
-
-	}
-
-	/**
-	 * End
-	 * 
-	 * @param descr
-	 */
-	private void solve(LiteralRestrictionDescr descr) {
-		LiteralRestriction restriction = new LiteralRestriction();
-
-		restriction.setRuleId(currentRule.getId());
-		restriction.setRuleName(currentRule.getRuleName());
-		restriction.setRuleId(currentRule.getId());
-		restriction.setPatternId(currentPattern.getId());
-		restriction.setPatternIsNot(currentPattern.isPatternNot());
-		restriction.setConstraintId(currentConstraint.getId());
-		restriction.setFieldId(currentConstraint.getFieldId());
-		restriction.setEvaluator(descr.getEvaluator());
-		restriction.setValue(descr.getText());
-
-		// Set field value, if it is unset.
-		currentField.setFieldType(restriction.getValueType());
-
-		data.insert(restriction);
-		solvers.addRestriction(restriction);
-	}
-
-	/**
-	 * End
-	 * 
-	 * @param descr
-	 */
-	private void solve(QualifiedIdentifierRestrictionDescr descr) {
-		String text = descr.getText();
-		Variable variable = data.getVariableByRuleAndVariableName(currentRule
-				.getRuleName(), text.substring(0, text.indexOf(".")));
-
-		QualifiedIdentifierRestriction restriction = new QualifiedIdentifierRestriction();
-
-		restriction.setRuleId(currentRule.getId());
-		restriction.setPatternId(currentPattern.getId());
-		restriction.setPatternIsNot(currentPattern.isPatternNot());
-		restriction.setConstraintId(currentConstraint.getId());
-		restriction.setFieldId(currentConstraint.getFieldId());
-		restriction.setEvaluator(descr.getEvaluator());
-		restriction.setVariableId(variable.getId());
-		restriction.setVariableName(text.substring(0, text.indexOf(".")));
-		restriction.setVariablePath(text.substring(text.indexOf(".")));
-
-		// Set field value, if it is unset.
-		currentField.setFieldType(Field.FieldType.VARIABLE);
-
-		variable.setObjectType(AnalyticsComponentType.FIELD);
-
-		data.insert(restriction);
-		solvers.addRestriction(restriction);
-	}
-
-	private Field createField(String fieldName, int line, int classId,
-			String className) {
-		Field field = new Field();
-		field.setClassId(classId);
-		field.setClassName(className);
-		field.setName(fieldName);
-		field.setLineNumber(line);
-
-		return field;
-	}
-
-	public List<PatternPossibility> getPatternPossibilities() {
-		return solvers.getPatternPossibilities();
-	}
-
-	public List<RulePossibility> getRulePossibilities() {
-		return solvers.getRulePossibilities();
-	}
-
-	public Collection<Object> getDataObjects() {
-		Collection<Object> objects = new ArrayList<Object>();
-		objects.addAll(data.getAll());
-		objects.addAll(solvers.getPatternPossibilities());
-		objects.addAll(solvers.getRulePossibilities());
-
-		return objects;
-	}
-}

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/LiteralRestriction.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/LiteralRestriction.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/LiteralRestriction.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -6,8 +6,6 @@
 
 import org.drools.analytics.result.Cause;
 
-
-
 /**
  * 
  * @author Toni Rikkola
@@ -26,6 +24,11 @@
 		return Restriction.RestrictionType.LITERAL;
 	}
 
+	@Override
+	public String getValueAsString() {
+		return stringValue;
+	}
+
 	public String getStringValue() {
 		return stringValue;
 	}

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/PatternPossibility.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/PatternPossibility.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/PatternPossibility.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -5,8 +5,6 @@
 
 import org.drools.analytics.result.Cause;
 
-
-
 /**
  * Instance of this class represents a possible combination of Constraints under
  * one Pattern. Each possibility returns true if all the Constraints in the
@@ -37,6 +35,10 @@
 		return items;
 	}
 
+	public int getAmountOfItems() {
+		return items.size();
+	}
+
 	public int getPatternId() {
 		return patternId;
 	}
@@ -56,4 +58,10 @@
 	public void add(Restriction restriction) {
 		items.add(restriction);
 	}
+
+	@Override
+	public String toString() {
+		return "PatternPossibility from rule: " + ruleName
+				+ ", amount of items:" + items.size();
+	}
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Possibility.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Possibility.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Possibility.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -10,7 +10,7 @@
  */
 public interface Possibility extends Cause {
 
-	public int getId();
-
 	public Set<Cause> getItems();
+	
+	public int getAmountOfItems();
 }

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/QualifiedIdentifierRestriction.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/QualifiedIdentifierRestriction.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/QualifiedIdentifierRestriction.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -15,6 +15,11 @@
 		return RestrictionType.QUALIFIED_IDENTIFIER;
 	}
 
+	@Override
+	public String getValueAsString() {
+		return variablePath + "." + variableName;
+	}
+
 	public int getVariableId() {
 		return variableId;
 	}

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Restriction.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Restriction.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Restriction.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -33,6 +33,8 @@
 
 	public abstract RestrictionType getRestrictionType();
 
+	public abstract String getValueAsString();
+
 	public String getEvaluator() {
 		return evaluator;
 	}

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/ReturnValueRestriction.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/ReturnValueRestriction.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/ReturnValueRestriction.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -13,6 +13,11 @@
 	private String classMethodName;
 
 	@Override
+	public String getValueAsString() {
+		return classMethodName;
+	}
+
+	@Override
 	public RestrictionType getRestrictionType() {
 		return RestrictionType.RETURN_VALUE_RESTRICTION;
 	}

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/RulePossibility.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/RulePossibility.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/RulePossibility.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -6,8 +6,6 @@
 
 import org.drools.analytics.result.Cause;
 
-
-
 /**
  * Instance of this class represents a possible combination of
  * PatternPosibilities under one Rule. Each possibility returns true if all the
@@ -37,6 +35,10 @@
 		return items;
 	}
 
+	public int getAmountOfItems() {
+		return items.size();
+	}
+
 	public int getRuleId() {
 		return ruleId;
 	}
@@ -48,4 +50,10 @@
 	public void add(PatternPossibility patternPossibility) {
 		items.add(patternPossibility);
 	}
+
+	@Override
+	public String toString() {
+		return "RulePossibility from rule: " + ruleName
+				+ ", amount of items:" + items.size();
+	}
 }

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/VariableRestriction.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/VariableRestriction.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/VariableRestriction.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -11,6 +11,11 @@
 	protected String variableName;
 	protected int variableId;
 
+	@Override
+	public String getValueAsString() {
+		return variableName;
+	}
+
 	public int getVariableId() {
 		return variableId;
 	}

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsData.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsData.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsData.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -8,11 +8,11 @@
 import org.drools.analytics.components.Field;
 import org.drools.analytics.components.FieldClassLink;
 import org.drools.analytics.components.Pattern;
+import org.drools.analytics.components.PatternPossibility;
 import org.drools.analytics.components.Restriction;
+import org.drools.analytics.components.RulePossibility;
 import org.drools.analytics.components.Variable;
 
-
-
 /**
  * 
  * @author Toni Rikkola
@@ -35,6 +35,10 @@
 
 	public void insert(FieldClassLink link);
 
+	public void insert(PatternPossibility possibility);
+
+	public void insert(RulePossibility possibility);
+
 	public AnalyticsClass getClassByName(String name);
 
 	public Field getFieldByClassAndFieldName(String className, String fieldName);

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsDataMaps.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsDataMaps.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsDataMaps.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -12,11 +12,11 @@
 import org.drools.analytics.components.Field;
 import org.drools.analytics.components.FieldClassLink;
 import org.drools.analytics.components.Pattern;
+import org.drools.analytics.components.PatternPossibility;
 import org.drools.analytics.components.Restriction;
+import org.drools.analytics.components.RulePossibility;
 import org.drools.analytics.components.Variable;
 
-
-
 /**
  * 
  * @author Toni Rikkola
@@ -35,6 +35,21 @@
 
 	private Map<String, Variable> variablesByRuleAndVariableName = new HashMap<String, Variable>();
 
+	private Map<Integer, PatternPossibility> patternPossibilitiesById = new HashMap<Integer, PatternPossibility>();
+	private Map<Integer, RulePossibility> rulePossibilitiesById = new HashMap<Integer, RulePossibility>();
+
+	private static AnalyticsDataMaps map;
+
+	private AnalyticsDataMaps() {
+	}
+
+	public static AnalyticsDataMaps getAnalyticsDataMaps() {
+		if (map == null) {
+			map = new AnalyticsDataMaps();
+		}
+		return map;
+	}
+
 	public void insert(AnalyticsClass clazz) {
 		classesById.put(Integer.valueOf(clazz.getId()), clazz);
 		classesByName.put(clazz.getName(), clazz);
@@ -93,6 +108,14 @@
 		return fieldClassLinkByIds.get(id + "." + id2);
 	}
 
+	public void insert(PatternPossibility possibility) {
+		patternPossibilitiesById.put(possibility.getId(), possibility);
+	}
+
+	public void insert(RulePossibility possibility) {
+		rulePossibilitiesById.put(possibility.getId(), possibility);
+	}
+
 	public Collection<? extends Object> getAll() {
 		List<Object> objects = new ArrayList<Object>();
 
@@ -101,6 +124,9 @@
 		objects.addAll(constraintsById.values());
 		objects.addAll(restrictionsById.values());
 
+		objects.addAll(patternPossibilitiesById.values());
+		objects.addAll(rulePossibilitiesById.values());
+
 		objects.addAll(classesByName.values());
 		objects.addAll(fieldsByClassAndFieldName.values());
 		objects.addAll(variablesByRuleAndVariableName.values());

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisError.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisError.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisError.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -1,6 +1,7 @@
 package org.drools.analytics.result;
 
 import java.io.Serializable;
+import java.util.List;
 
 /**
  * 
@@ -8,10 +9,11 @@
  */
 public class AnalysisError extends AnalysisMessage implements Serializable {
 	private static final long serialVersionUID = -7589664008092901491L;
-	
+
 	private static int errorIndex = 0;
 
-	public AnalysisError() {
+	public AnalysisError(String ruleName, String message, List<Cause> reasons) {
+		super(ruleName, message, reasons);
 		id = errorIndex++;
 	}
 }

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisMessage.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisMessage.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisMessage.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -1,6 +1,7 @@
 package org.drools.analytics.result;
 
 import java.io.Serializable;
+import java.util.List;
 
 /**
  * 
@@ -12,8 +13,14 @@
 
 	protected String ruleName;
 	protected String message;
-	protected int lineNumber;
+	protected List<Cause> causes;
 
+	public AnalysisMessage(String ruleName, String message, List<Cause> reasons) {
+		this.ruleName = ruleName;
+		this.message = message;
+		this.causes = reasons;
+	}
+
 	public int getId() {
 		return id;
 	}
@@ -22,14 +29,6 @@
 		this.id = id;
 	}
 
-	public int getLineNumber() {
-		return lineNumber;
-	}
-
-	public void setLineNumber(int lineNumber) {
-		this.lineNumber = lineNumber;
-	}
-
 	public String getMessage() {
 		return message;
 	}
@@ -46,7 +45,11 @@
 		this.ruleName = ruleName;
 	}
 
-	public String toString() {
-		return ruleName + ": " + message + " On line " + lineNumber;
+	public List<Cause> getCauses() {
+		return causes;
 	}
+
+	public void setCauses(List<Cause> reasons) {
+		this.causes = reasons;
+	}
 }

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisNote.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisNote.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisNote.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -1,6 +1,7 @@
 package org.drools.analytics.result;
 
 import java.io.Serializable;
+import java.util.List;
 
 /**
  * 
@@ -8,10 +9,11 @@
  */
 public class AnalysisNote extends AnalysisMessage implements Serializable {
 	private static final long serialVersionUID = 5853338910928403832L;
-	
+
 	private static int noteIndex = 0;
 
-	public AnalysisNote() {
+	public AnalysisNote(String ruleName, String message, List<Cause> reasons) {
+		super(ruleName, message, reasons);
 		id = noteIndex++;
 	}
 }

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisResult.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisResult.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisResult.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -1,14 +1,18 @@
 package org.drools.analytics.result;
 
+import java.util.List;
+
 /**
  * 
  * @author Toni Rikkola
  */
 public interface AnalysisResult {
 
-	public void addError(Cause[] causes, String message, int lineNumber);
+	public void add(AnalysisMessage notification);
 
-	public void addNote(Cause[] causes, String message, int lineNumber);
+	public List<AnalysisError> getErrors();
 
-	public void addWarning(Cause[] causes, String message, int lineNumber);
+	public List<AnalysisNote> getNotes();
+
+	public List<AnalysisWarning> getWarnings();
 }

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisResultNormal.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisResultNormal.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisResultNormal.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -14,36 +14,17 @@
 	private List<AnalysisWarning> warnings = new ArrayList<AnalysisWarning>();
 	private List<AnalysisError> errors = new ArrayList<AnalysisError>();
 
-	public void addError( String ruleName,
-			String message, int lineNumber) {
-		AnalysisError error = new AnalysisError();
-		error.setRuleName(ruleName);
-		error.setMessage(message);
-		error.setLineNumber(lineNumber);
+	public void add(AnalysisMessage notification) {
+		if (notification instanceof AnalysisError) {
+			errors.add((AnalysisError) notification);
+		} else if (notification instanceof AnalysisWarning) {
+			warnings.add((AnalysisWarning) notification);
+		} else if (notification instanceof AnalysisNote) {
+			notes.add((AnalysisNote) notification);
+		}
 
-		errors.add(error);
 	}
 
-	public void addNote( String ruleName,
-			String message, int lineNumber) {
-		AnalysisNote note = new AnalysisNote();
-		note.setRuleName(ruleName);
-		note.setMessage(message);
-		note.setLineNumber(lineNumber);
-
-		notes.add(note);
-	}
-
-	public void addWarning( String ruleName,
-			String message, int lineNumber) {
-		AnalysisWarning warning = new AnalysisWarning();
-		warning.setRuleName(ruleName);
-		warning.setMessage(message);
-		warning.setLineNumber(lineNumber);
-
-		warnings.add(warning);
-	}
-
 	public List<AnalysisError> getErrors() {
 		return errors;
 	}
@@ -55,19 +36,4 @@
 	public List<AnalysisWarning> getWarnings() {
 		return warnings;
 	}
-
-	public void addError(Cause[] causes, String message, int lineNumber) {
-		// TODO Auto-generated method stub
-		
-	}
-
-	public void addNote(Cause[] causes, String message, int lineNumber) {
-		// TODO Auto-generated method stub
-		
-	}
-
-	public void addWarning(Cause[] causes, String message, int lineNumber) {
-		// TODO Auto-generated method stub
-		
-	}
 }

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisWarning.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisWarning.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisWarning.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -1,8 +1,8 @@
 package org.drools.analytics.result;
 
 import java.io.Serializable;
+import java.util.List;
 
-
 /**
  * 
  * @author Toni Rikkola
@@ -12,7 +12,32 @@
 
 	private static int warningIndex = 0;
 
-	public AnalysisWarning() {
+	public AnalysisWarning(String ruleName, String message, List<Cause> reasons) {
+		super(ruleName, message, reasons);
 		id = warningIndex++;
 	}
+
+	public String toString() {
+		StringBuffer str = new StringBuffer("Warning id = ");
+		str.append(id);
+		str.append(":\n");
+
+		if (ruleName != null) {
+			str.append("in rule ");
+			str.append(ruleName);
+			str.append(": ");
+		}
+
+		str.append(message);
+		str.append(" \n\tCauses are [ \n");
+
+		for (Cause cause : causes) {
+			str.append("\t\t");
+			str.append(cause);
+			str.append("\n");
+		}
+		str.append("\t]");
+
+		return str.toString();
+	}
 }

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Cause.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Cause.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Cause.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -5,5 +5,8 @@
  * @author Toni Rikkola
  */
 public interface Cause {
+
+	public int getId();
+	
 	public String getRuleName();
 }

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Gap.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Gap.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Gap.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -1,33 +1,52 @@
 package org.drools.analytics.result;
 
+import org.drools.analytics.components.Restriction;
+
 /**
  * 
  * @author Toni Rikkola
  */
-public class Gap {
+public class Gap implements Cause {
 
+	private static int index = 0;
+
+	private int id;
+
 	private Cause cause;
-	private String ruleName;
+	private Restriction restriction;
 	private String firedRuleName;
-	private String evaluator;
-	private String value;
 
-	public String getReversedEvaluator() {
-		if (evaluator.equals("!=")) {
+	public Gap(Cause cause, Restriction restriction, String firedRuleName) {
+		id = index;
+		this.cause = cause;
+		this.restriction = restriction;
+		this.firedRuleName = firedRuleName;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public String getRuleName() {
+		return restriction.getRuleName();
+	}
+
+	private String getReversedEvaluator() {
+		if (restriction.getEvaluator().equals("!=")) {
 			return "==";
-		} else if (evaluator.equals("==")) {
+		} else if (restriction.getEvaluator().equals("==")) {
 			return "!=";
-		} else if (evaluator.equals(">")) {
+		} else if (restriction.getEvaluator().equals(">")) {
 			return "<=";
-		} else if (evaluator.equals("<")) {
+		} else if (restriction.getEvaluator().equals("<")) {
 			return ">=";
-		} else if (evaluator.equals(">=")) {
+		} else if (restriction.getEvaluator().equals(">=")) {
 			return "<";
-		} else if (evaluator.equals("<=")) {
+		} else if (restriction.getEvaluator().equals("<=")) {
 			return ">";
 		}
 
-		return evaluator;
+		return null;
 	}
 
 	public Cause getCause() {
@@ -38,12 +57,12 @@
 		this.cause = cause;
 	}
 
-	public String getEvaluator() {
-		return evaluator;
+	public Restriction getRestriction() {
+		return restriction;
 	}
 
-	public void setEvaluator(String evaluator) {
-		this.evaluator = evaluator;
+	public void setRestriction(Restriction restriction) {
+		this.restriction = restriction;
 	}
 
 	public String getFiredRuleName() {
@@ -54,24 +73,9 @@
 		this.firedRuleName = firedRuleName;
 	}
 
-	public String getValue() {
-		return value;
-	}
-
-	public void setValue(String value) {
-		this.value = value;
-	}
-
 	@Override
 	public String toString() {
-		return "Gap: (" + cause + ") " + getReversedEvaluator() + " " + value;
+		return "Gap: (" + cause + ") " + getReversedEvaluator() + " "
+				+ restriction.getValueAsString();
 	}
-
-	public String getRuleName() {
-		return ruleName;
-	}
-
-	public void setRuleName(String ruleName) {
-		this.ruleName = ruleName;
-	}
 }

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Redundancy.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Redundancy.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Redundancy.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -1,11 +1,21 @@
 package org.drools.analytics.result;
 
 /**
+ * Presents a redundancy between two Causes. The link between them can be WEAK
+ * or STRONG.
  * 
+ * WEAK redundancy is for example two AnalyticsRules, but not theys rule
+ * possibilities. STRONG redundancy includes possibilities.
+ * 
  * @author Toni Rikkola
  */
 public class Redundancy {
 
+	public enum Type {
+		WEAK, STRONG
+	}
+
+	private Type type = Type.WEAK; // By default the redundancy is weak.
 	private Cause left;
 	private Cause right;
 
@@ -14,6 +24,12 @@
 		this.right = right;
 	}
 
+	public Redundancy(Type type, Cause left, Cause right) {
+		this.type = type;
+		this.left = left;
+		this.right = right;
+	}
+
 	public Cause getLeft() {
 		return left;
 	}
@@ -30,6 +46,14 @@
 		this.right = right;
 	}
 
+	public Type getType() {
+		return type;
+	}
+
+	public void setType(Type type) {
+		this.type = type;
+	}
+
 	@Override
 	public String toString() {
 		return "Redundacy between: (" + left + ") and (" + right + ").";

Copied: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/ReportWriter.java (from rev 14749, labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Writer.java)
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/ReportWriter.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/ReportWriter.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -0,0 +1,55 @@
+package org.drools.analytics.result;
+
+import com.thoughtworks.xstream.XStream;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class ReportWriter {
+
+	public static String writeXML(AnalysisResultNormal result) {
+		XStream xstream = new XStream();
+
+		xstream.alias("result", AnalysisResultNormal.class);
+		xstream.alias("note", AnalysisNote.class);
+		xstream.alias("error", AnalysisError.class);
+		xstream.alias("warning", AnalysisWarning.class);
+
+		return "<?xml version=\"1.0\"?>\n" + xstream.toXML(result);
+	}
+
+	public static String writePlainText(AnalysisResultNormal result) {
+
+		StringBuffer str = new StringBuffer();
+
+		str.append("************* ERRORS ");
+		str.append(result.getErrors().size());
+		str.append(" ******************\n");
+		for (AnalysisError error : result.getErrors()) {
+			str.append(error);
+			str.append("\n");
+		}
+		str.append("\n");
+
+		str.append("************* WARNINGS ");
+		str.append(result.getWarnings().size());
+		str.append(" ******************\n");
+		for (AnalysisWarning warning : result.getWarnings()) {
+			str.append(warning);
+			str.append("\n");
+		}
+		str.append("\n");
+
+		str.append("************* NOTES ");
+		str.append(result.getNotes().size());
+		str.append(" ******************\n");
+		for (AnalysisNote note : result.getNotes()) {
+			str.append(note);
+			str.append("\n");
+		}
+
+		return str.toString();
+	}
+
+}

Deleted: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Writer.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Writer.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Writer.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -1,22 +0,0 @@
-package org.drools.analytics.result;
-
-import com.thoughtworks.xstream.XStream;
-
-/**
- * 
- * @author Toni Rikkola
- */
-public class Writer {
-
-	public static String write(AnalysisResultNormal result) {
-		XStream xstream = new XStream();
-
-		xstream.alias("result", AnalysisResultNormal.class);
-		xstream.alias("note", AnalysisNote.class);
-		xstream.alias("error", AnalysisError.class);
-		xstream.alias("warning", AnalysisWarning.class);
-
-		return "<?xml version=\"1.0\"?>\n" + xstream.toXML(result);
-	}
-
-}

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckDates.drl
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckDates.drl	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckDates.drl	2007-09-06 14:21:13 UTC (rev 14912)
@@ -62,15 +62,8 @@
 											patternIsNot == $r.patternIsNot, 
 											eval( dateValue.equals($r.getDateValue()) ) )
 		)
-		$rule :AnalyticsRule( id == $r.ruleId )
 	then
-		Gap gap = new Gap();
-		gap.setCause($f);
-		gap.setRuleName($rule.getRuleName());
-		gap.setEvaluator($r.getEvaluator());
-		gap.setFiredRuleName(drools.getRule().getName());
-		gap.setValue( dateToString($r.getDateValue()));
-		insert( gap );
+		insert( new Gap( $f, $r, drools.getRule().getName()) );
 end
 
 # If all ranges are not checked for a field.
@@ -93,15 +86,8 @@
 								( evaluator == "<" || == "<=" ), 
 								patternIsNot == $r.patternIsNot, 
 								eval( dateValue.equals($r.getDateValue())) )
-		$rule :AnalyticsRule( id == $r.ruleId )
 	then
-		Gap gap = new Gap();
-		gap.setCause($f);
-		gap.setRuleName($rule.getRuleName());
-		gap.setEvaluator("<");
-		gap.setFiredRuleName(drools.getRule().getName());
-		gap.setValue( dateToString($r.getDateValue()));
-		insert( gap );
+		insert( new Gap( $f, $r, drools.getRule().getName()) );
 end
 
 # If all ranges are not checked for a field.
@@ -124,13 +110,6 @@
 								( evaluator == ">" || == ">=" ), 
 								patternIsNot == $r.patternIsNot, 
 								eval( dateValue.equals($r.getDateValue())) )
-		$rule :AnalyticsRule( id == $r.ruleId )
 	then
-		Gap gap = new Gap();
-		gap.setCause($f);
-		gap.setRuleName($rule.getRuleName());
-		gap.setEvaluator(">");
-		gap.setFiredRuleName(drools.getRule().getName());
-		gap.setValue( dateToString($r.getDateValue()));
-		insert( gap );
+		insert( new Gap( $f, $r, drools.getRule().getName()) );
 end

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckDoubles.drl
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckDoubles.drl	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckDoubles.drl	2007-09-06 14:21:13 UTC (rev 14912)
@@ -49,15 +49,8 @@
 											patternIsNot == $r.patternIsNot, 
 											doubleValue == $r.doubleValue )
 		)
-		$rule :AnalyticsRule( id == $r.ruleId )
 	then
-		Gap gap = new Gap();
-		gap.setCause($f);
-		gap.setRuleName($rule.getRuleName());
-		gap.setEvaluator($r.getEvaluator());
-		gap.setFiredRuleName(drools.getRule().getName());
-		gap.setValue($r.getDoubleValue() +"");
-		insert( gap );
+		insert( new Gap( $f, $r, drools.getRule().getName()) );
 end
 
 # If all ranges are not checked for a field.
@@ -80,15 +73,8 @@
 								( evaluator == "<" || == "<=" ), 
 								patternIsNot == $r.patternIsNot, 
 								doubleValue == $r.doubleValue )
-		$rule :AnalyticsRule( id == $r.ruleId )
 	then
-		Gap gap = new Gap();
-		gap.setCause($f);
-		gap.setRuleName($rule.getRuleName());
-		gap.setEvaluator("<");
-		gap.setFiredRuleName(drools.getRule().getName());
-		gap.setValue($r.getDoubleValue() + "");
-		insert( gap );
+		insert( new Gap( $f, $r, drools.getRule().getName()) );
 end
 
 # If all ranges are not checked for a field.
@@ -111,14 +97,7 @@
 								( evaluator == ">" || == ">=" ), 
 								patternIsNot == $r.patternIsNot, 
 								doubleValue == $r.doubleValue )
-		$rule :AnalyticsRule( id == $r.ruleId )
 	then
-		Gap gap = new Gap();
-		gap.setCause($f);
-		gap.setRuleName($rule.getRuleName());
-		gap.setEvaluator(">");
-		gap.setFiredRuleName(drools.getRule().getName());
-		gap.setValue($r.getDoubleValue() +"");
-		insert( gap );
+		insert( new Gap( $f, $r, drools.getRule().getName()) );
 end
 

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckIntegers.drl
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckIntegers.drl	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckIntegers.drl	2007-09-06 14:21:13 UTC (rev 14912)
@@ -13,9 +13,6 @@
 import java.text.SimpleDateFormat;
 import java.util.Locale;
 
-#declare any global variables here
-global AnalysisResult result
-
 # If all ranges are not checked for a field.
 # 
 # Type: Warning
@@ -42,7 +39,6 @@
 			and
 				not LiteralRestriction( fieldId == $fieldId, evaluator  == ">", 
 											patternIsNot == $patternIsNot, intValue == $value )
-			# XXX: Field might be double, then this pattern is useless.
 			and
 				not LiteralRestriction( fieldId == $fieldId, evaluator  == ">=", 
 											patternIsNot == $patternIsNot, eval( intValue == $value + 1 ) )
@@ -52,20 +48,12 @@
 			and
 				not LiteralRestriction( fieldId == $fieldId, evaluator  == "<", 
 											patternIsNot == $patternIsNot, intValue == $value )
-			# XXX: Field might be double, then this pattern is useless. 
 			and
 				not LiteralRestriction( fieldId == $fieldId, evaluator  == "<=", 
 											patternIsNot == $patternIsNot, eval( intValue == $value - 1 ) )
 		)
-		$rule :AnalyticsRule( id == $r.ruleId )
 	then
-		Gap gap = new Gap();
-		gap.setCause($f);
-		gap.setRuleName($rule.getRuleName());
-		gap.setEvaluator($r.getEvaluator());
-		gap.setFiredRuleName(drools.getRule().getName());
-		gap.setValue($value +"");
-		insert( gap );
+		insert( new Gap( $f, $r, drools.getRule().getName()) );
 end
 
 # If all ranges are not checked for a field.
@@ -107,19 +95,12 @@
 								( evaluator == "==" || == "<=" ), 
 								patternIsNot == $r.patternIsNot, 
 								eval( intValue == $r.getIntValue() - 1 ) )
-		$rule :AnalyticsRule( id == $r.ruleId )
 	then
-		Gap gap = new Gap();
-		gap.setCause($f);
-		gap.setRuleName($rule.getRuleName());
-		gap.setEvaluator("<");
-		gap.setFiredRuleName(drools.getRule().getName());
-		gap.setValue($r.getIntValue() + "");
-		insert( gap );
+		insert( new Gap( $f, $r, drools.getRule().getName()) );
 end
 
 # If all ranges are not checked for a field.
-# If equality and smaller than exist check that greater than exists too.
+# If equality and greater than exist check that smaller than exists too.
 #
 # Type: Warning
 # Example: in "Rule 1" Foo(bar == 42 ) and in "Rule 2" Foo( bar > 42 )
@@ -157,13 +138,6 @@
 								( evaluator == "==" || == ">=" ), 
 								patternIsNot == $r.patternIsNot, 
 								eval( intValue == $r.getIntValue() + 1 ) )
-		$rule :AnalyticsRule( id == $r.ruleId )
 	then
-		Gap gap = new Gap();
-		gap.setCause($f);
-		gap.setRuleName($rule.getRuleName());
-		gap.setEvaluator(">");
-		gap.setFiredRuleName(drools.getRule().getName());
-		gap.setValue($r.getIntValue() +"");
-		insert( gap );
+		insert( new Gap( $f, $r, drools.getRule().getName()) );
 end

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/Redundancy.drl
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/Redundancy.drl	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/Redundancy.drl	2007-09-06 14:21:13 UTC (rev 14912)
@@ -7,6 +7,7 @@
 
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.HashSet;
 
 #declare any global variables here
 global AnalysisResult result
@@ -64,7 +65,7 @@
 			objectId == $v.objectId
 		)
 	then
-		insert( new Redundancy( $left, $right ) );
+		insert( new Redundancy( Redundancy.Type.STRONG, $left, $right ) );
 end
 
 /*
@@ -167,7 +168,7 @@
 			right == $right 
 		)
 	then
-		insert( new Redundancy( $left, $right ) );
+		insert( new Redundancy( Redundancy.Type.STRONG, $left, $right ) );
 end
 
 
@@ -196,7 +197,7 @@
 			right == $right 
 		)
 	then
-		insert( new Redundancy( $left, $right ) );
+		insert( new Redundancy( Redundancy.Type.WEAK, $left, $right ) );
 end
 
 #
@@ -220,7 +221,7 @@
 			right == $right 
 		)
 	then
-		insert( new Redundancy( $left, $right ) );
+		insert( new Redundancy( Redundancy.Type.WEAK, $left, $right ) );
 end
 
 
@@ -273,55 +274,159 @@
 			ruleId == $r2.id, 
 			items contains $redundancy.right 
 		)
+		# TODO: Not here.
 	then
 		insert( new PartialRedundancy( $rp1, $rp2, $redundancy ) );
 end
 
-/*
+
 #
 # Handles both RulePossibilities and PatternPossibilities.
 #
 rule "Find subsumptant Possibilities"
 	when
-		$pp1 :Possibility()
-		$pp2 :Possibility( id != $pp1.id )
+		$p1 :Possibility()
+		$p2 :Possibility( id != $p1.id )
 		
-		# Count that there is as many redundant items as there is PartialRedundancies.
-		Number( intValue == $pp1.items.size )
-			from accumulate(
-				$pr :PartialRedundancy( 
-					left == $pp1, 
-					right == $pp2 
-				), 
-				count( $pr )
+		not Subsumption( 
+				left == $p1, 
+				right == $p2 
+		)
+		
+		# At least one partial redundancy exists between these possibilities.
+		exists( 
+				PartialRedundancy( 
+					left == $p1, 
+					right == $p2 
+				) 
+		)
+		
+		# Collect all the partial redundancies.
+		$list :ArrayList()
+			from collect(
+				PartialRedundancy( 
+					left == $p1, 
+					right == $p2 
+				)
 			)
+			
+		# If there as much partial redundancies as there is items in $p1,
+		# then $p1 is subsumptant to $p2.
+		eval( $list.size() == $p1.getAmountOfItems() )
 	then
-		insert( new Subsumption( $pp1, $pp2 ) );
+		insert( new Subsumption( $p1, $p2 ) );
 end
 
-
 #
-# Checks for all PartialRedundancys that contain either PatternPossibilities
-# or RulePossibilities.
+# If two possibilities are subsumptant to each others, then they are redundant.
+# Since this tests only one possibility, the entire rule or pattern might not be redundant.
 #
-rule "Find redundant PartialRedundancies"
+rule "Find redundant Possibilities"
 	when
-		# If both sides are in subsumption with each other, 
-		# then they are also redundant.
-		$pr :PartialRedundancy()
-		PartialRedundancy( 
-			leftParent == $pr.rightParent, 
-			rightParent == $pr.leftParent 
+		$p1 :Possibility()
+		$p2 :Possibility( id != $p1.id )
+		
+		not Redundancy( 
+			left == $p1, 
+			right == $p2 
 		)
+		
+		not Redundancy( 
+			left == $p2, 
+			right == $p1 
+		)
+		
+		Subsumption( 
+				left == $p1, 
+				right == $p2 
+		)
+		
+		Subsumption( 
+				left == $p2, 
+				right == $p1 
+		)
 	then
-		insert( new Redundancy( $pr.leftParent, $pr.rightParent ) );
+		insert( new Redundancy( $p1, $p2 ) );
 end
 
+/*
+#
+# When two patterns and all theyr possibilities are redundant.
+#
+rule "Find redundant pattern"
+	when
+		$p1 :Pattern()
+		$p2 :Pattern( id != $p1.id )
+		
+		$set1 :HashSet()
+			from collect(
+				PatternPossibility( patternId == $p1.id )
+			)
 
+		$set2 :HashSet()
+			from collect(
+				PatternPossibility( patternId == $p2.id )
+			)
+		
+		# Check that sizes are the same.
+		eval( $set1.size() == $set2.size() )
+		
+		$redundancyList :ArrayList()
+			from collect(
+				Redundancy( 
+					eval( $set1.contains( left ) ),
+					eval( $set2.contains( right ) )
+				)
+			)
+		
+		eval( $set1.size() == $redundancyList.size() )
+		
+	then
+		# Type is set to strong because all the pattern possibilities are redundant.
+		insert( new Redundancy( Redundancy.Type.STRONG, $p1, $p2 ) );
+end
+
+#
+# When two rules and all theyr possibilities are redundant.
+#
+rule "Find redundant rule"
+	when
+		$r1 :AnalyticsRule()
+		$r2 :AnalyticsRule( id != $r1.id )
+		
+		# If all the patterns in rule 1 are strongly redundant to rule 2, and vice versa.
+		# Then the redundancy is strong.
+		$set1 :HashSet()
+			from collect(
+				Pattern( ruleId == $r1.id )
+			)
+
+		$set2 :HashSet()
+			from collect(
+				Pattern( ruleId == $r2.id )
+			)
+		
+		# Find only strong pattern
+		$redundancyList :ArrayList()
+			from collect(
+				Redundancy( 
+					type == Redundancy.Type.STRONG,
+					eval( $set1.contains( left ) ),
+					eval( $set2.contains( right ) )
+				)
+			)
+		 
+		eval( $set1.size() == $redundancyList.size() )
+		
+	then
+		# Type is set to strong because all the rule possibilities are redundant.
+		insert( new Redundancy( Redundancy.Type.STRONG, $r1, $r2 ) );
+end
+*/
+/*
 # TODO: Partial redundancy, when some two rulepossibilities from different rules 
 # are redundant. but not all of the possibilities are redundant!
 # NOTE: Write this one to to out put rules.
-
 */
 
 

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/reports/RangeCheckReports.drl
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/reports/RangeCheckReports.drl	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/reports/RangeCheckReports.drl	2007-09-06 14:21:13 UTC (rev 14912)
@@ -0,0 +1,24 @@
+#created on: 7.6.2007
+package org.drools.analytics.rangeChecks.reports;
+
+#list any import classes here.
+import org.drools.analytics.components.Field;
+import org.drools.analytics.result.AnalysisWarning;
+import org.drools.analytics.result.AnalysisResult;
+import org.drools.analytics.result.Gap;
+
+import java.util.ArrayList;
+
+#declare any global variables here
+global AnalysisResult result
+
+rule "Collect gaps"
+	when
+		$f :Field()
+		$list :ArrayList( size > 1)
+			from collect(
+				Gap( cause == $f )
+			)
+	then
+		result.add( new AnalysisWarning( $f.getRuleName(), $f + " has one or more gaps.", $list ) );
+end
\ No newline at end of file

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RangeCheckDatesTest.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RangeCheckDatesTest.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RangeCheckDatesTest.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -11,11 +11,10 @@
 import org.drools.analytics.result.Gap;
 import org.drools.base.RuleNameMatchesAgendaFilter;
 
-
 /**
  * 
  * @author Toni Rikkola
- *
+ * 
  */
 public class RangeCheckDatesTest extends TestBase {
 
@@ -26,7 +25,7 @@
 		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
 				"Range check for dates, smaller and greater than"));
 
-		Collection<Object> data = getTestData(this.getClass()
+		Collection<? extends Object> data = getTestData(this.getClass()
 				.getResourceAsStream("MissingRangesForDates.drl"));
 
 		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
@@ -88,7 +87,7 @@
 		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
 				"Range check for dates, equal and greater than"));
 
-		Collection<Object> data = getTestData(this.getClass()
+		Collection<? extends Object> data = getTestData(this.getClass()
 				.getResourceAsStream("MissingRangesForDates.drl"));
 
 		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
@@ -124,7 +123,7 @@
 		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
 				"Range check for dates, equal and smaller than"));
 
-		Collection<Object> data = getTestData(this.getClass()
+		Collection<? extends Object> data = getTestData(this.getClass()
 				.getResourceAsStream("MissingRangesForDates.drl"));
 
 		AnalysisResultNormal analysisResult = new AnalysisResultNormal();

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RangeCheckDoublesTest.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RangeCheckDoublesTest.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RangeCheckDoublesTest.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -26,7 +26,7 @@
 		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
 				"Range check for doubles, smaller and greater than"));
 
-		Collection<Object> data = getTestData(this.getClass()
+		Collection<? extends Object> data = getTestData(this.getClass()
 				.getResourceAsStream("MissingRangesForDoubles.drl"));
 
 		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
@@ -88,7 +88,7 @@
 		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
 				"Range check for doubles, equal and greater than"));
 
-		Collection<Object> data = getTestData(this.getClass()
+		Collection<? extends Object> data = getTestData(this.getClass()
 				.getResourceAsStream("MissingRangesForDoubles.drl"));
 
 		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
@@ -124,7 +124,7 @@
 		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
 				"Range check for doubles, equal and smaller than"));
 
-		Collection<Object> data = getTestData(this.getClass()
+		Collection<? extends Object> data = getTestData(this.getClass()
 				.getResourceAsStream("MissingRangesForDoubles.drl"));
 
 		AnalysisResultNormal analysisResult = new AnalysisResultNormal();

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RangeCheckIntegersTest.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RangeCheckIntegersTest.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RangeCheckIntegersTest.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -26,7 +26,7 @@
 		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
 				"Range check for integers, smaller and greater than"));
 
-		Collection<Object> data = getTestData(this.getClass()
+		Collection<? extends Object> data = getTestData(this.getClass()
 				.getResourceAsStream("MissingRangesForInts.drl"));
 
 		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
@@ -84,7 +84,7 @@
 		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
 				"Range check for integers, equal and greater than"));
 
-		Collection<Object> data = getTestData(this.getClass()
+		Collection<? extends Object> data = getTestData(this.getClass()
 				.getResourceAsStream("MissingRangesForInts.drl"));
 
 		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
@@ -121,7 +121,7 @@
 		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
 				"Range check for integers, equal and smaller than"));
 
-		Collection<Object> data = getTestData(this.getClass()
+		Collection<? extends Object> data = getTestData(this.getClass()
 				.getResourceAsStream("MissingRangesForInts.drl"));
 
 		AnalysisResultNormal analysisResult = new AnalysisResultNormal();

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RedundancyTest.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RedundancyTest.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RedundancyTest.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -28,54 +28,6 @@
  */
 public class RedundancyTest extends TestBase {
 
-//	public void testSubsumptantPossibilitiesPattern() throws Exception {
-//		StatelessSession session = getStatelessSession(this.getClass()
-//				.getResourceAsStream("Redundancy.drl"));
-//
-//		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
-//				"Find subsumptant Possibilities"));
-//
-//		Collection<Object> data = new ArrayList<Object>();
-//
-//		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
-//		session.setGlobal("result", analysisResult);
-//
-//		String ruleName1 = "Rule 1";
-//		String ruleName2 = "Rule 2";
-//
-//		LiteralRestriction lr1 = new LiteralRestriction();
-//		lr1.setRuleName(ruleName1);
-//		LiteralRestriction lr2 = new LiteralRestriction();
-//		lr2.setRuleName(ruleName1);
-//
-//		PatternPossibility pp1 = new PatternPossibility();
-//		pp1.setRuleName(ruleName1);
-//		pp1.add(lr1);
-//		pp1.add(lr2);
-//
-//		LiteralRestriction lr3 = new LiteralRestriction();
-//		lr3.setRuleName(ruleName2);
-//
-//		PatternPossibility pp2 = new PatternPossibility();
-//		pp2.setRuleName(ruleName2);
-//		pp2.add(lr3);
-//
-//		Redundancy redundancy1 = new Redundancy(pp1, pp2);
-//
-//		PartialRedundancy pr1 = new PartialRedundancy(pp1, pp2, redundancy1);
-//
-//		StatelessSessionResult sessionResult = session.executeWithResults(data);
-//
-//		Map<String, Set<String>> map = createSubsumptionMap(sessionResult
-//				.iterateObjects());
-//
-//		assertTrue(mapContains(map, ruleName2, ruleName1));
-//
-//		if (!map.isEmpty()) {
-//			fail("More redundancies than was expected.");
-//		}
-//	}
-
 	public void testPartOfRulePossibilityRedundancy() throws Exception {
 		StatelessSession session = getStatelessSession(this.getClass()
 				.getResourceAsStream("Redundancy.drl"));
@@ -145,13 +97,56 @@
 			}
 		}
 
-		assertTrue(mapContains(map, ruleName1 + ":" + ruleName2, redundancy1));
+		assertTrue(RedundancyTest.mapContains(map, ruleName1 + ":" + ruleName2,
+				redundancy1));
 
 		if (!map.isEmpty()) {
 			fail("More redundancies than was expected.");
 		}
 	}
 
+	public void testPossibilityRedundancy() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("Redundancy.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Find redundant Possibilities"));
+
+		Collection<Object> data = new ArrayList<Object>();
+
+		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
+		session.setGlobal("result", analysisResult);
+
+		String ruleName1 = "Rule 1";
+		String ruleName2 = "Rule 2";
+
+		PatternPossibility pp1 = new PatternPossibility();
+		pp1.setRuleName(ruleName1);
+
+		PatternPossibility pp2 = new PatternPossibility();
+		pp2.setRuleName(ruleName2);
+
+		Subsumption s1 = new Subsumption(pp1, pp2);
+		Subsumption s2 = new Subsumption(pp2, pp1);
+
+		data.add(pp1);
+		data.add(pp2);
+		data.add(s1);
+		data.add(s2);
+
+		StatelessSessionResult sessionResult = session.executeWithResults(data);
+
+		Iterator iter = sessionResult.iterateObjects();
+
+		Map<String, Set<String>> map = createRedundancyMap(iter);
+
+		assertTrue(RedundancyTest.mapContains(map, ruleName2, ruleName1));
+
+		if (!map.isEmpty()) {
+			fail("More redundancies than was expected.");
+		}
+	}
+
 	public void testPartOfPatternPossibilityRedundancy() throws Exception {
 		StatelessSession session = getStatelessSession(this.getClass()
 				.getResourceAsStream("Redundancy.drl"));
@@ -221,7 +216,8 @@
 			}
 		}
 
-		assertTrue(mapContains(map, ruleName1 + ":" + ruleName2, r1));
+		assertTrue(RedundancyTest.mapContains(map, ruleName1 + ":" + ruleName2,
+				r1));
 
 		if (!map.isEmpty()) {
 			fail("More redundancies than was expected.");
@@ -269,7 +265,7 @@
 		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
 				"Find redundant Pattern shells"));
 
-		Collection<Object> data = getTestData(this.getClass()
+		Collection<? extends Object> data = getTestData(this.getClass()
 				.getResourceAsStream("PatternRedundancyTest.drl"));
 
 		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
@@ -280,21 +276,21 @@
 		Map<String, Set<String>> map = createRedundancyMap(sessionResult
 				.iterateObjects());
 
-		assertTrue(mapContains(map, "Pattern redundancy 1a",
+		assertTrue(TestBase.mapContains(map, "Pattern redundancy 1a",
 				"Pattern redundancy 1b"));
-		assertTrue(mapContains(map, "Pattern redundancy 1b",
+		assertTrue(TestBase.mapContains(map, "Pattern redundancy 1b",
 				"Pattern redundancy 1a"));
-		assertTrue(mapContains(map, "Pattern redundancy 2a",
+		assertTrue(TestBase.mapContains(map, "Pattern redundancy 2a",
 				"Pattern redundancy 2b"));
-		assertTrue(mapContains(map, "Pattern redundancy 2b",
+		assertTrue(TestBase.mapContains(map, "Pattern redundancy 2b",
 				"Pattern redundancy 2a"));
-		assertTrue(mapContains(map, "Pattern redundancy 3a",
+		assertTrue(TestBase.mapContains(map, "Pattern redundancy 3a",
 				"Pattern redundancy 3b"));
-		assertTrue(mapContains(map, "Pattern redundancy 3b",
+		assertTrue(TestBase.mapContains(map, "Pattern redundancy 3b",
 				"Pattern redundancy 3a"));
-		assertTrue(mapContains(map, "Pattern redundancy 4a",
+		assertTrue(TestBase.mapContains(map, "Pattern redundancy 4a",
 				"Pattern redundancy 4b"));
-		assertTrue(mapContains(map, "Pattern redundancy 4b",
+		assertTrue(TestBase.mapContains(map, "Pattern redundancy 4b",
 				"Pattern redundancy 4a"));
 
 		if (!map.isEmpty()) {
@@ -309,7 +305,7 @@
 		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
 				"Find redundant LiteralRestriction"));
 
-		Collection<Object> data = getTestData(this.getClass()
+		Collection<? extends Object> data = getTestData(this.getClass()
 				.getResourceAsStream("RedundancyLiteralRestrictionTest.drl"));
 
 		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
@@ -320,18 +316,18 @@
 		Map<String, Set<String>> map = createRedundancyMap(sessionResult
 				.iterateObjects());
 
-		assertTrue(mapContains(map, "Redundant 1a", "Redundant 1b"));
-		assertTrue(mapContains(map, "Redundant 1b", "Redundant 1a"));
-		assertTrue(mapContains(map, "Redundant 2a", "Redundant 2b"));
-		assertTrue(mapContains(map, "Redundant 2b", "Redundant 2a"));
-		assertTrue(mapContains(map, "Redundant 3a", "Redundant 3b"));
-		assertTrue(mapContains(map, "Redundant 3b", "Redundant 3a"));
-		assertTrue(mapContains(map, "Redundant 4a", "Redundant 4b"));
-		assertTrue(mapContains(map, "Redundant 4b", "Redundant 4a"));
-		assertTrue(mapContains(map, "Redundant 5a", "Redundant 5b"));
-		assertTrue(mapContains(map, "Redundant 5b", "Redundant 5a"));
-		assertTrue(mapContains(map, "Redundant 6a", "Redundant 6b"));
-		assertTrue(mapContains(map, "Redundant 6b", "Redundant 6a"));
+		assertTrue(TestBase.mapContains(map, "Redundant 1a", "Redundant 1b"));
+		assertTrue(TestBase.mapContains(map, "Redundant 1b", "Redundant 1a"));
+		assertTrue(TestBase.mapContains(map, "Redundant 2a", "Redundant 2b"));
+		assertTrue(TestBase.mapContains(map, "Redundant 2b", "Redundant 2a"));
+		assertTrue(TestBase.mapContains(map, "Redundant 3a", "Redundant 3b"));
+		assertTrue(TestBase.mapContains(map, "Redundant 3b", "Redundant 3a"));
+		assertTrue(TestBase.mapContains(map, "Redundant 4a", "Redundant 4b"));
+		assertTrue(TestBase.mapContains(map, "Redundant 4b", "Redundant 4a"));
+		assertTrue(TestBase.mapContains(map, "Redundant 5a", "Redundant 5b"));
+		assertTrue(TestBase.mapContains(map, "Redundant 5b", "Redundant 5a"));
+		assertTrue(TestBase.mapContains(map, "Redundant 6a", "Redundant 6b"));
+		assertTrue(TestBase.mapContains(map, "Redundant 6b", "Redundant 6a"));
 
 		if (!map.isEmpty()) {
 			fail("More redundancies than was expected.");
@@ -345,7 +341,7 @@
 		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
 				"Find redundant VariableRestriction"));
 
-		Collection<Object> data = getTestData(this.getClass()
+		Collection<? extends Object> data = getTestData(this.getClass()
 				.getResourceAsStream("SubsumptionVariableRestrictionTest.drl"));
 
 		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
@@ -356,9 +352,9 @@
 		Map<String, Set<String>> map = createRedundancyMap(sessionResult
 				.iterateObjects());
 
-		assertTrue(mapContains(map, "Redundant 1a", "Redundant 1b"));
-		assertTrue(mapContains(map, "Redundant 1b", "Redundant 1a"));
-		assertTrue(mapContains(map, "Redundant 2a", "Redundant 2a"));
+		assertTrue(TestBase.mapContains(map, "Redundant 1a", "Redundant 1b"));
+		assertTrue(TestBase.mapContains(map, "Redundant 1b", "Redundant 1a"));
+		assertTrue(TestBase.mapContains(map, "Redundant 2a", "Redundant 2a"));
 
 		if (!map.isEmpty()) {
 			fail("More redundancies than was expected.");
@@ -394,58 +390,6 @@
 	}
 
 	/**
-	 * Creates redundancy map from Redundancy objects, one rule may have several
-	 * redundancy dependencies.
-	 * 
-	 * @param iter
-	 * @return
-	 */
-	private Map<String, Set<String>> createSubsumptionMap(Iterator iter) {
-
-		Map<String, Set<String>> map = new HashMap<String, Set<String>>();
-		while (iter.hasNext()) {
-			Object o = (Object) iter.next();
-			if (o instanceof Subsumption) {
-				Subsumption s = (Subsumption) o;
-				if (map.containsKey(s.getLeft().getRuleName())) {
-					Set<String> set = map.get(s.getLeft().getRuleName());
-					set.add(s.getRight().getRuleName());
-				} else {
-					Set<String> set = new HashSet<String>();
-					set.add(s.getRight().getRuleName());
-					map.put(s.getLeft().getRuleName(), set);
-				}
-			}
-		}
-
-		return map;
-	}
-
-	/**
-	 * Returns true if map contains redundancy where ruleName1 is redundant to
-	 * ruleName2.
-	 * 
-	 * @param map
-	 * @param ruleName1
-	 * @param ruleName2
-	 * @return True if redundancy exists.
-	 */
-	private boolean mapContains(Map<String, Set<String>> map, String ruleName1,
-			String ruleName2) {
-		if (map.containsKey(ruleName1)) {
-			Set<String> set = map.get(ruleName1);
-			boolean exists = set.remove(ruleName2);
-
-			// If set is empty remove key from map.
-			if (set.isEmpty()) {
-				map.remove(ruleName1);
-			}
-			return exists;
-		}
-		return false;
-	}
-
-	/**
 	 * Returns true if map contains redundancy where key is redundant to value.
 	 * 
 	 * @param map
@@ -453,8 +397,8 @@
 	 * @param value
 	 * @return True if redundancy exists.
 	 */
-	private boolean mapContains(Map<String, Set<Redundancy>> map, String key,
-			Object value) {
+	private static boolean mapContains(Map<String, Set<Redundancy>> map,
+			String key, Object value) {
 		if (map.containsKey(key)) {
 			Set<Redundancy> set = map.get(key);
 			boolean exists = set.remove(value);

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/SubsumptantPossibilitiesRuleTest.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/SubsumptantPossibilitiesRuleTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/SubsumptantPossibilitiesRuleTest.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -0,0 +1,224 @@
+package org.drools.analytics;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.drools.StatelessSession;
+import org.drools.StatelessSessionResult;
+import org.drools.analytics.components.LiteralRestriction;
+import org.drools.analytics.components.PatternPossibility;
+import org.drools.analytics.components.RulePossibility;
+import org.drools.analytics.result.PartialRedundancy;
+import org.drools.analytics.result.Redundancy;
+import org.drools.analytics.result.Subsumption;
+import org.drools.base.RuleNameMatchesAgendaFilter;
+
+public class SubsumptantPossibilitiesRuleTest extends TestBase {
+
+	private static final String RULE_NAME = "Find subsumptant Possibilities";
+
+	public void testSubsumptantPossibilitiesPattern() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("Redundancy.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(RULE_NAME));
+
+		String ruleName1 = "Rule 1";
+		String ruleName2 = "Rule 2";
+
+		StatelessSessionResult sessionResult = session
+				.executeWithResults(createSubsumptantPatternData(ruleName1,
+						ruleName2));
+
+		Map<String, Set<String>> map = createSubsumptionMap(sessionResult
+				.iterateObjects());
+
+		assertTrue(TestBase.mapContains(map, ruleName2, ruleName1));
+
+		if (!map.isEmpty()) {
+			fail("More subsumpt cases than was expected.");
+		}
+	}
+
+	public void testSubsumptantPossibilitiesRule() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("Redundancy.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(RULE_NAME));
+
+		String ruleName1 = "Rule 1";
+		String ruleName2 = "Rule 2";
+
+		StatelessSessionResult sessionResult = session
+				.executeWithResults(createSubsumptantRuleData(ruleName1,
+						ruleName2));
+
+		Map<String, Set<String>> map = createSubsumptionMap(sessionResult
+				.iterateObjects());
+
+		assertTrue(TestBase.mapContains(map, ruleName2, ruleName1));
+
+		if (!map.isEmpty()) {
+			fail("More subsumpt cases than was expected.");
+		}
+	}
+
+	public void testSubsumptantPossibilitiesBoth() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("Redundancy.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(RULE_NAME));
+
+		String ruleName1 = "Rule 1";
+		String ruleName2 = "Rule 2";
+		String ruleName3 = "Rule 3";
+		String ruleName4 = "Rule 4";
+		String ruleName5 = "Rule 5";
+		String ruleName6 = "Rule 6";
+		String ruleName7 = "Rule 7";
+		String ruleName8 = "Rule 8";
+		String ruleName9 = "Rule 9";
+		String ruleName10 = "Rule 10";
+		String ruleName11 = "Rule 11";
+		String ruleName12 = "Rule 12";
+
+		// Rule data
+		Collection<Object> data = createSubsumptantRuleData(ruleName1,
+				ruleName2);
+		data.addAll(createSubsumptantRuleData(ruleName3, ruleName4));
+		data.addAll(createSubsumptantRuleData(ruleName5, ruleName6));
+
+		// Pattern data.
+		data.addAll(createSubsumptantPatternData(ruleName7, ruleName8));
+		data.addAll(createSubsumptantPatternData(ruleName9, ruleName10));
+		data.addAll(createSubsumptantPatternData(ruleName11, ruleName12));
+
+		StatelessSessionResult sessionResult = session.executeWithResults(data);
+
+		Map<String, Set<String>> map = createSubsumptionMap(sessionResult
+				.iterateObjects());
+
+		assertTrue(TestBase.mapContains(map, ruleName2, ruleName1));
+		assertTrue(TestBase.mapContains(map, ruleName4, ruleName3));
+		assertTrue(TestBase.mapContains(map, ruleName6, ruleName5));
+
+		assertTrue(TestBase.mapContains(map, ruleName8, ruleName7));
+		assertTrue(TestBase.mapContains(map, ruleName10, ruleName9));
+		assertTrue(TestBase.mapContains(map, ruleName12, ruleName11));
+
+		if (!map.isEmpty()) {
+			fail("More subsumpt cases than was expected.");
+		}
+	}
+
+	private Collection<Object> createSubsumptantPatternData(String ruleName1,
+			String ruleName2) {
+
+		Collection<Object> data = new ArrayList<Object>();
+
+		LiteralRestriction lr1 = new LiteralRestriction();
+		lr1.setRuleName(ruleName1);
+		LiteralRestriction lr2 = new LiteralRestriction();
+		lr2.setRuleName(ruleName1);
+
+		PatternPossibility pp1 = new PatternPossibility();
+		pp1.setRuleName(ruleName1);
+		pp1.add(lr1);
+		pp1.add(lr2);
+
+		LiteralRestriction lr3 = new LiteralRestriction();
+		lr3.setRuleName(ruleName2);
+
+		PatternPossibility pp2 = new PatternPossibility();
+		pp2.setRuleName(ruleName2);
+		pp2.add(lr3);
+
+		Redundancy redundancy1 = new Redundancy(lr1, lr3);
+
+		PartialRedundancy pr1 = new PartialRedundancy(pp1, pp2, redundancy1);
+		PartialRedundancy pr2 = new PartialRedundancy(pp2, pp1, redundancy1);
+
+		data.add(lr1);
+		data.add(lr2);
+		data.add(lr3);
+		data.add(pp1);
+		data.add(pp2);
+		data.add(redundancy1);
+		data.add(pr1);
+		data.add(pr2);
+
+		return data;
+	}
+
+	private Collection<Object> createSubsumptantRuleData(String ruleName1,
+			String ruleName2) {
+
+		Collection<Object> data = new ArrayList<Object>();
+
+		PatternPossibility pp1 = new PatternPossibility();
+		pp1.setRuleName(ruleName1);
+		PatternPossibility pp2 = new PatternPossibility();
+		pp2.setRuleName(ruleName1);
+
+		RulePossibility rp1 = new RulePossibility();
+		rp1.setRuleName(ruleName1);
+		rp1.add(pp1);
+		rp1.add(pp2);
+
+		PatternPossibility pp3 = new PatternPossibility();
+		pp3.setRuleName(ruleName2);
+
+		RulePossibility rp2 = new RulePossibility();
+		rp2.setRuleName(ruleName2);
+		rp2.add(pp3);
+
+		Redundancy redundancy1 = new Redundancy(pp1, pp3);
+
+		PartialRedundancy pr1 = new PartialRedundancy(rp1, rp2, redundancy1);
+		PartialRedundancy pr2 = new PartialRedundancy(rp2, rp1, redundancy1);
+
+		data.add(pp1);
+		data.add(pp2);
+		data.add(rp1);
+		data.add(pp3);
+		data.add(rp2);
+		data.add(redundancy1);
+		data.add(pr1);
+		data.add(pr2);
+
+		return data;
+	}
+
+	/**
+	 * Creates redundancy map from Redundancy objects, one rule may have several
+	 * redundancy dependencies.
+	 * 
+	 * @param iter
+	 * @return
+	 */
+	private Map<String, Set<String>> createSubsumptionMap(Iterator iter) {
+
+		Map<String, Set<String>> map = new HashMap<String, Set<String>>();
+		while (iter.hasNext()) {
+			Object o = (Object) iter.next();
+			if (o instanceof Subsumption) {
+				Subsumption s = (Subsumption) o;
+				if (map.containsKey(s.getLeft().getRuleName())) {
+					Set<String> set = map.get(s.getLeft().getRuleName());
+					set.add(s.getRight().getRuleName());
+				} else {
+					Set<String> set = new HashSet<String>();
+					set.add(s.getRight().getRuleName());
+					map.put(s.getLeft().getRuleName(), set);
+				}
+			}
+		}
+
+		return map;
+	}
+}

Modified: labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/TestBase.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/TestBase.java	2007-09-06 13:32:24 UTC (rev 14911)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/TestBase.java	2007-09-06 14:21:13 UTC (rev 14912)
@@ -4,12 +4,15 @@
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
 
 import junit.framework.TestCase;
 
 import org.drools.RuleBase;
 import org.drools.RuleBaseFactory;
 import org.drools.StatelessSession;
+import org.drools.analytics.dao.AnalyticsDataMaps;
 import org.drools.compiler.DrlParser;
 import org.drools.compiler.PackageBuilder;
 import org.drools.lang.descr.PackageDescr;
@@ -18,7 +21,7 @@
 /**
  * 
  * @author Toni Rikkola
- *
+ * 
  */
 abstract class TestBase extends TestCase {
 
@@ -31,18 +34,6 @@
 
 	}
 
-	public Collection<Object> getTestData(InputStream stream) throws Exception {
-		Reader drlReader = new InputStreamReader(stream);
-		PackageDescr descr = new DrlParser().parse(drlReader);
-
-		RuleFlattener ruleFlattener = new RuleFlattener();
-
-		ruleFlattener.insert(descr);
-
-		// Rules with relations
-		return ruleFlattener.getDataObjects();
-	}
-
 	public StatelessSession getStatelessSession(InputStream stream)
 			throws Exception {
 		// read in the source
@@ -59,4 +50,41 @@
 
 		return ruleBase.newStatelessSession();
 	}
+
+	/**
+	 * Returns true if map contains redundancy where ruleName1 is redundant to
+	 * ruleName2.
+	 * 
+	 * @param map
+	 * @param ruleName1
+	 * @param ruleName2
+	 * @return True if redundancy exists.
+	 */
+	protected static boolean mapContains(Map<String, Set<String>> map,
+			String ruleName1, String ruleName2) {
+		if (map.containsKey(ruleName1)) {
+			Set<String> set = map.get(ruleName1);
+			boolean exists = set.remove(ruleName2);
+
+			// If set is empty remove key from map.
+			if (set.isEmpty()) {
+				map.remove(ruleName1);
+			}
+			return exists;
+		}
+		return false;
+	}
+
+	public Collection<? extends Object> getTestData(InputStream stream)
+			throws Exception {
+		Reader drlReader = new InputStreamReader(stream);
+		PackageDescr descr = new DrlParser().parse(drlReader);
+
+		PackageDescrFlattener ruleFlattener = new PackageDescrFlattener();
+
+		ruleFlattener.insert(descr);
+
+		// Rules with relations
+		return AnalyticsDataMaps.getAnalyticsDataMaps().getAll();
+	}
 }




More information about the jboss-svn-commits mailing list