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

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Aug 27 12:08:25 EDT 2007


Author: Rikkola
Date: 2007-08-27 12:08:25 -0400 (Mon, 27 Aug 2007)
New Revision: 14650

Added:
   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/PatternSolver.java
   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/RuleSolver.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Solver.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Solvers.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/accumulateFunction/
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/accumulateFunction/ValidatePattern.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/accumulateFunction/ValidatePatternResult.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsAccessorDescr.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsAccumulateDescr.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsClass.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsCollectDescr.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsComponent.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsComponentType.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsEvalDescr.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsFieldAccessDescr.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsFromDescr.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsFunctionCallDescr.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsMethodAccessDescr.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsPredicateDescr.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsRule.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Constraint.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Field.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/FieldClassLink.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/InlineEvalDescr.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/OperatorDescr.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Pattern.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/ReturValueFieldDescr.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/Variable.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/
   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/
   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/PartialRedundancy.java
   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/Subsumption.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Writer.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/
   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/RangeCheckPatterns.drl
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckVariables.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/PatternSolverTest.java
   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/SolversTest.java
   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/accumulateFunction/
   labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/accumulateFunction/ValidatePatternTest.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/test/resources/
   labs/jbossrules/trunk/experimental/drools-analytics/src/test/resources/org/
   labs/jbossrules/trunk/experimental/drools-analytics/src/test/resources/org/drools/
Removed:
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/AnalysisResult.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Constraint.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Pattern.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Rule.java
   labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/BasicTest.java
Modified:
   labs/jbossrules/trunk/experimental/drools-analytics/.classpath
Log:
First commit

Modified: labs/jbossrules/trunk/experimental/drools-analytics/.classpath
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/.classpath	2007-08-27 14:53:06 UTC (rev 14649)
+++ labs/jbossrules/trunk/experimental/drools-analytics/.classpath	2007-08-27 16:08:25 UTC (rev 14650)
@@ -1,5 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
+	<classpathentry combineaccessrules="false" kind="src" path="/drools-compiler"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/drools-core"/>
 	<classpathentry kind="src" path="src/test/java"/>
 	<classpathentry kind="src" path="src/main/resources"/>
 	<classpathentry kind="src" path="src/main/java"/>
@@ -7,7 +9,5 @@
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
 	<classpathentry kind="var" path="M2_REPO/xstream/xstream/1.1.3/xstream-1.1.3.jar"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/drools-compiler"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/drools-core"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>

Deleted: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/AnalysisResult.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/AnalysisResult.java	2007-08-27 14:53:06 UTC (rev 14649)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/AnalysisResult.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -1,56 +0,0 @@
-package org.drools.analytics;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.drools.spi.KnowledgeHelper;
-
-/**
- * This is a class which contains lists of warnings and errors to be reported to the user via a user interface or static report of
- * some form. 
- * 
- * It uses the ReportItem class to contains rules/warnings as pertains to them. Display them or ignore them as you will.
- * 
- * @author Michael Neale
- *
- */
-public class AnalysisResult implements Serializable {
-
-    
-    private static final long serialVersionUID = -6207688526236713721L;
-    private List warnings = new ArrayList();
-    private List errors = new ArrayList();
-    
-    public void addWarning(KnowledgeHelper k, String message) {
-        warnings.add( new ReportItem(k.getRule().getName(), message) );
-    }
-    
-    public void addError(KnowledgeHelper k, String message) {
-        errors.add( new ReportItem(k.getRule().getName(), message) );
-    }
-    
-    public List getWarnings() {
-        return warnings;
-    }
-    
-    static class ReportItem implements Serializable {
-        private static final long serialVersionUID = 400L;
-        public String rule;
-        public String message;
-        
-        public ReportItem(String rule, String message) {
-            this.rule = rule;
-            this.message = message;
-        }
-        
-        public String toString() {
-            return rule + ": " + message;
-        }
-    }
-
-    public List getErrors() {
-        return errors;
-    }
-    
-}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Analyzer.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,90 @@
+package org.drools.analytics;
+
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.Collection;
+
+import org.drools.RuleBase;
+import org.drools.RuleBaseFactory;
+import org.drools.WorkingMemory;
+import org.drools.analytics.result.AnalysisResultNormal;
+import org.drools.analytics.result.Writer;
+import org.drools.compiler.PackageBuilder;
+import org.drools.lang.descr.PackageDescr;
+import org.drools.rule.Package;
+
+
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class Analyzer {
+
+	private AnalysisResultNormal result = new AnalysisResultNormal();
+
+	public void solvePackageDescr(PackageDescr descr) {
+		try {
+
+			System.setProperty("drools.accumulate.function.validatePattern",
+					"com.analytics.accumulateFunction.ValidatePattern");
+
+			// load up the rulebase
+			RuleBase ruleBase = readRules();
+
+			WorkingMemory workingMemory = ruleBase.newStatefulSession();
+
+			RuleFlattener ruleFlattener = new RuleFlattener();
+
+			ruleFlattener.insert(descr);
+
+			// Rules with relations
+			Collection<Object > objects = ruleFlattener.getDataObjects();
+			for (Object o : objects) {
+				workingMemory.insert(o);
+			}
+
+			// Object that returns the results.
+			AnalysisResultNormal result = new AnalysisResultNormal();
+			workingMemory.setGlobal("result", result);
+			workingMemory.fireAllRules();
+
+		} catch (Throwable t) {
+			t.printStackTrace();
+		}
+	}
+
+	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 XML.
+	 * 
+	 * @return Analysis results as XML
+	 */
+	public String getResultAsXML() {
+		return Writer.write(result);
+	}
+
+	/**
+	 * Returns the analysis results as <code>AnalysisResult</code> object.
+	 * 
+	 * @return Analysis result
+	 */
+	public AnalysisResultNormal getResult() {
+		return result;
+	}
+}

Deleted: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Constraint.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Constraint.java	2007-08-27 14:53:06 UTC (rev 14649)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Constraint.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -1,53 +0,0 @@
-package org.drools.analytics;
-
-public class Constraint {
-
-    private String field;
-    private String operator;
-    private String value;
-    private String objectType;
-    private String ruleName;
-    private String parentCE = "rule";
-    
-    public static String CE_OR;
-    public static String CE_NOT;
-    public static String CE_EXIST;    
-    
-    public String getParentCE() {
-        return parentCE;
-    }
-    public void setParentCE(String parentCE) {
-        this.parentCE = parentCE;
-    }
-    public String getObjectType() {
-        return objectType;
-    }
-    public void setObjectType(String objectType) {
-        this.objectType = objectType;
-    }
-    public String getRuleName() {
-        return ruleName;
-    }
-    public void setRuleName(String ruleName) {
-        this.ruleName = ruleName;
-    }
-    public String getField() {
-        return field;
-    }
-    public void setField(String field) {
-        this.field = field;
-    }
-    public String getOperator() {
-        return operator;
-    }
-    public void setOperator(String operator) {
-        this.operator = operator;
-    }
-    public String getValue() {
-        return value;
-    }
-    public void setValue(String value) {
-        this.value = value;
-    }
-    
-}

Deleted: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Pattern.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Pattern.java	2007-08-27 14:53:06 UTC (rev 14649)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Pattern.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -1,30 +0,0 @@
-package org.drools.analytics;
-
-public class Pattern {
-
-    public String id;
-    public String objectType;
-    public Constraint[] constraints;
-    
-    
-    
-    public Constraint[] getConstraints() {
-        return constraints;
-    }
-    public void setConstraints(Constraint[] constraints) {
-        this.constraints = constraints;
-    }
-    public String getId() {
-        return id;
-    }
-    public void setId(String id) {
-        this.id = id;
-    }
-    public String getObjectType() {
-        return objectType;
-    }
-    public void setObjectType(String objectType) {
-        this.objectType = objectType;
-    }
-    
-}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/PatternSolver.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/PatternSolver.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/PatternSolver.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,23 @@
+package org.drools.analytics;
+
+import org.drools.analytics.components.OperatorDescr;
+import org.drools.analytics.components.Pattern;
+
+/**
+ * Takes a list of Constraints and makes possibilities from them.
+ * 
+ * @author Toni Rikkola
+ */
+public class PatternSolver extends Solver {
+
+	private Pattern pattern;
+
+	public PatternSolver(Pattern pattern) {
+		super(OperatorDescr.Type.OR);
+		this.pattern = (Pattern) pattern.clone();
+	}
+
+	public Pattern getPattern() {
+		return pattern;
+	}
+}

Deleted: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Rule.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Rule.java	2007-08-27 14:53:06 UTC (rev 14649)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Rule.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -1,36 +0,0 @@
-package org.drools.analytics;
-
-public class Rule {
-
-    
-    public String name;
-    public Pattern[] patterns;
-    public String rhs;
-    
-    private int salienceValue;
-    
-    public String getName() {
-        return name;
-    }
-    public void setName(String name) {
-        this.name = name;
-    }
-    public Pattern[] getPatterns() {
-        return patterns;
-    }
-    public void setPatterns(Pattern[] patterns) {
-        this.patterns = patterns;
-    }
-    public String getRhs() {
-        return rhs;
-    }
-    public void setRhs(String rhs) {
-        this.rhs = rhs;
-    }
-    public int getSalienceValue() {
-        return salienceValue;
-    }
-    public void setSalienceValue(int salience) {
-        this.salienceValue = salience;
-    }
-}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/RuleFlattener.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,568 @@
+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;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/RuleSolver.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/RuleSolver.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/RuleSolver.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,23 @@
+package org.drools.analytics;
+
+import org.drools.analytics.components.AnalyticsRule;
+import org.drools.analytics.components.OperatorDescr;
+
+/**
+ * Takes a list of Constraints and makes possibilities from them.
+ * 
+ * @author Toni Rikkola
+ */
+public class RuleSolver extends Solver {
+
+	private AnalyticsRule rule;
+
+	public RuleSolver(AnalyticsRule rule) {
+		super(OperatorDescr.Type.OR);
+		this.rule = (AnalyticsRule) rule.clone();
+	}
+
+	public AnalyticsRule getRule() {
+		return rule;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Solver.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Solver.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Solver.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,146 @@
+package org.drools.analytics;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.drools.analytics.components.AnalyticsComponent;
+import org.drools.analytics.components.OperatorDescr;
+
+
+
+/**
+ * Takes a list of Constraints and makes possibilities from them.
+ * 
+ * @author Toni Rikkola
+ */
+class Solver {
+
+	private List<Set<AnalyticsComponent>> possibilityLists = new ArrayList<Set<AnalyticsComponent>>();
+	private Solver subSolver = null;
+	private boolean isChildExists = false;
+	private boolean isChildForall = false;
+	private boolean isChildNot = false;
+
+	private OperatorDescr.Type type;
+
+	protected Solver(OperatorDescr.Type type) {
+		this.type = type;
+	}
+
+	public void add(AnalyticsComponent descr) {
+		if (subSolver != null) {
+			subSolver.add(descr);
+		} else if (descr instanceof OperatorDescr) {
+			OperatorDescr operatorDescr = (OperatorDescr) descr;
+			subSolver = new Solver(operatorDescr.getType());
+		} else {
+			if (type == OperatorDescr.Type.AND) {
+				if (possibilityLists.isEmpty()) {
+					possibilityLists.add(new HashSet<AnalyticsComponent>());
+				}
+				for (Set<AnalyticsComponent> set : possibilityLists) {
+					set.add(descr);
+				}
+			} else if (type == OperatorDescr.Type.OR) {
+				Set<AnalyticsComponent> set = new HashSet<AnalyticsComponent>();
+				set.add(descr);
+				possibilityLists.add(set);
+			}
+		}
+	}
+
+	/**
+	 * Ends subSolvers data collection.
+	 * 
+	 */
+	protected void end() {
+		if (subSolver != null && subSolver.subSolver == null) {
+			if (type == OperatorDescr.Type.AND) {
+				if (possibilityLists.isEmpty()) {
+					possibilityLists.add(new HashSet<AnalyticsComponent>());
+				}
+
+				List<Set<AnalyticsComponent>> newPossibilities = new ArrayList<Set<AnalyticsComponent>>();
+
+				List<Set<AnalyticsComponent>> sets = subSolver
+						.getPossibilityLists();
+				for (Set<AnalyticsComponent> possibilityList : possibilityLists) {
+
+					for (Set<AnalyticsComponent> set : sets) {
+						Set<AnalyticsComponent> newSet = new HashSet<AnalyticsComponent>();
+						newSet.addAll(possibilityList);
+						newSet.addAll(set);
+						newPossibilities.add(newSet);
+					}
+				}
+				possibilityLists = newPossibilities;
+
+			} else if (type == OperatorDescr.Type.OR) {
+
+				possibilityLists.addAll(subSolver.getPossibilityLists());
+
+			}
+
+			subSolver = null;
+
+		} else if (subSolver != null && subSolver.subSolver != null) {
+
+			subSolver.end();
+		}
+
+	}
+
+	public void setChildForall(boolean b) {
+		if (subSolver != null) {
+			subSolver.setChildForall(b);
+		} else {
+			isChildForall = b;
+		}
+	}
+
+	public void setChildExists(boolean b) {
+		if (subSolver != null) {
+			subSolver.setChildExists(b);
+		} else {
+			isChildExists = b;
+		}
+	}
+
+	public void setChildNot(boolean b) {
+		if (subSolver != null) {
+			subSolver.setChildNot(b);
+		} else {
+			isChildNot = b;
+		}
+	}
+
+	public boolean isForall() {
+		if (subSolver != null) {
+			return subSolver.isForall();
+		} else {
+			return isChildForall;
+		}
+	}
+
+	public boolean isExists() {
+		if (subSolver != null) {
+			return subSolver.isExists();
+		} else {
+			return isChildExists;
+		}
+	}
+
+	public boolean isChildNot() {
+		if (subSolver != null) {
+			return subSolver.isChildNot();
+		} else {
+			return isChildNot;
+		}
+	}
+
+	public List<Set<AnalyticsComponent>> getPossibilityLists() {
+		return possibilityLists;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Solvers.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Solvers.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/Solvers.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,171 @@
+package org.drools.analytics;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.drools.analytics.components.AnalyticsComponent;
+import org.drools.analytics.components.AnalyticsRule;
+import org.drools.analytics.components.OperatorDescr;
+import org.drools.analytics.components.Pattern;
+import org.drools.analytics.components.PatternPossibility;
+import org.drools.analytics.components.Restriction;
+import org.drools.analytics.components.RulePossibility;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class Solvers {
+
+	private RuleSolver ruleSolver = null;
+	private PatternSolver patternSolver = null;
+
+	private List<PatternPossibility> patternPossibilities = new ArrayList<PatternPossibility>();
+	private List<RulePossibility> rulePossibilities = new ArrayList<RulePossibility>();
+
+	public void startRuleSolver(AnalyticsRule rule) {
+		ruleSolver = new RuleSolver(rule);
+	}
+
+	public void endRuleSolver() {
+		createRulePossibilities();
+		ruleSolver = null;
+	}
+
+	public void startPatternSolver(Pattern pattern) {
+		patternSolver = new PatternSolver(pattern);
+
+		patternSolver.getPattern().setPatternNot(ruleSolver.isChildNot());
+	}
+
+	public void endPatternSolver() {
+		createPatternPossibilities();
+		patternSolver = null;
+	}
+
+	public void startForall() {
+		if (patternSolver != null) {
+			patternSolver.setChildForall(true);
+		} else if (ruleSolver != null) {
+			ruleSolver.setChildForall(true);
+		}
+	}
+
+	public void endForall() {
+		if (patternSolver != null) {
+			patternSolver.setChildForall(false);
+		} else if (ruleSolver != null) {
+			ruleSolver.setChildForall(false);
+		}
+	}
+
+	public void startExists() {
+		if (patternSolver != null) {
+			patternSolver.setChildExists(true);
+		} else if (ruleSolver != null) {
+			ruleSolver.setChildExists(true);
+		}
+	}
+
+	public void endExists() {
+		if (patternSolver != null) {
+			patternSolver.setChildExists(false);
+		} else if (ruleSolver != null) {
+			ruleSolver.setChildExists(false);
+		}
+	}
+
+	public void startNot() {
+		if (patternSolver != null) {
+			patternSolver.setChildNot(true);
+		} else if (ruleSolver != null) {
+			ruleSolver.setChildNot(true);
+		}
+	}
+
+	public void endNot() {
+		if (patternSolver != null) {
+			patternSolver.setChildNot(false);
+		} else if (ruleSolver != null) {
+			ruleSolver.setChildNot(false);
+		}
+	}
+
+	public void startOperator(OperatorDescr operatorDescr) {
+		if (patternSolver != null) {
+			patternSolver.add(operatorDescr);
+		} else if (ruleSolver != null) {
+			ruleSolver.add(operatorDescr);
+		}
+	}
+
+	public void endOperator() {
+		if (patternSolver != null) {
+			patternSolver.end();
+		} else if (ruleSolver != null) {
+			ruleSolver.end();
+		}
+	}
+
+	public void addRestriction(Restriction restriction) {
+		patternSolver.add(restriction);
+	}
+
+	private void createPatternPossibilities() {
+		for (Set<AnalyticsComponent> list : patternSolver.getPossibilityLists()) {
+			PatternPossibility possibility = new PatternPossibility();
+
+			possibility.setRuleId(ruleSolver.getRule().getId());
+			possibility.setPatternId(patternSolver.getPattern().getId());
+
+			for (AnalyticsComponent descr : list) {
+				possibility.add((Restriction) descr);
+			}
+
+			ruleSolver.add(possibility);
+			patternPossibilities.add(possibility);
+		}
+	}
+
+	private void createRulePossibilities() {
+		for (Set<AnalyticsComponent> list : ruleSolver.getPossibilityLists()) {
+			RulePossibility possibility = new RulePossibility();
+
+			possibility.setRuleId(ruleSolver.getRule().getId());
+			possibility.setRuleName(ruleSolver.getRule().getRuleName());
+
+			for (AnalyticsComponent descr : list) {
+				PatternPossibility patternPossibility = (PatternPossibility) descr;
+				possibility.add(patternPossibility);
+			}
+
+			rulePossibilities.add(possibility);
+		}
+	}
+
+	public List<PatternPossibility> getPatternPossibilities() {
+		return patternPossibilities;
+	}
+
+	public void setPatternPossibilities(
+			List<PatternPossibility> patternPossibilities) {
+		this.patternPossibilities = patternPossibilities;
+	}
+
+	public List<RulePossibility> getRulePossibilities() {
+		return rulePossibilities;
+	}
+
+	public void setRulePossibilities(List<RulePossibility> rulePossibilities) {
+		this.rulePossibilities = rulePossibilities;
+	}
+
+	public PatternSolver getPatternSolver() {
+		return patternSolver;
+	}
+
+	public RuleSolver getRuleSolver() {
+		return ruleSolver;
+	}
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/accumulateFunction/ValidatePattern.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/accumulateFunction/ValidatePattern.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/accumulateFunction/ValidatePattern.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,194 @@
+package org.drools.analytics.accumulateFunction;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.drools.analytics.components.LiteralRestriction;
+import org.drools.base.accumulators.AccumulateFunction;
+
+
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class ValidatePattern implements AccumulateFunction {
+
+	private static final int MIN_NUMBER_OF_CONSTRAINTS = 4;
+	private static List<LiteralRestriction> restrictions = new ArrayList<LiteralRestriction>();
+
+	public Object createContext() {
+		return restrictions;
+	}
+
+	public void init(Object context) throws Exception {
+		// constraints = new ArrayList<Constraint>();
+	}
+
+	public void accumulate(Object context, Object value) {
+		List<LiteralRestriction> list = (List<LiteralRestriction>) context;
+
+		list.add((LiteralRestriction) value);
+	}
+
+	public Object getResult(Object context) throws Exception {
+		List<LiteralRestriction> list = (List<LiteralRestriction>) context;
+		ValidatePatternResult result = new ValidatePatternResult();
+
+		if (list != null && list.size() >= MIN_NUMBER_OF_CONSTRAINTS) {
+			result.setValue(testForPattern(list));
+		}
+
+		return result;
+	}
+
+	public void reverse(Object context, Object value) throws Exception {
+		// TODO Auto-generated method stub
+
+	}
+
+	public boolean supportsReverse() {
+		return false;
+	}
+
+	/**
+	 * Test if the values in constraints are in pattern.
+	 * 
+	 * @param constraints
+	 * @return false if can't find a pattern or constraints list is null or size
+	 *         of the list is under 3.
+	 */
+	protected static Number testForPattern(List<LiteralRestriction> constraints) {
+
+		if (constraints == null || constraints.size() < 4) {
+			return null;
+		}
+
+		BigDecimal[] numbers = new BigDecimal[constraints.size()];
+
+		int index = 0;
+		for (LiteralRestriction restriction : restrictions) {
+			numbers[index++] = BigDecimal.valueOf(restriction.getDoubleValue());
+		}
+
+		Arrays.sort(numbers);
+
+		Number missingNumber = findSumPattern(numbers);
+		if (missingNumber != null) {
+			return missingNumber;
+		} else {
+			missingNumber = findMultiplicationPattern(numbers);
+			if (missingNumber != null) {
+				return missingNumber;
+			}
+		}
+
+		return null;
+	}
+
+	/**
+	 * Looks for sum pattern, on each step x is added or removed. -x is the same
+	 * as +(-x) so this works for both.
+	 * 
+	 * @param numbers
+	 * @return true if pattern is found.
+	 */
+	protected static Number findSumPattern(BigDecimal[] numbers) {
+		if (numbers == null || numbers.length < MIN_NUMBER_OF_CONSTRAINTS) {
+			return null;
+		}
+		BigDecimal gap = null;
+		Number missingNumber = null;
+
+		BigDecimal a = numbers[0];
+		BigDecimal b = numbers[1];
+		BigDecimal c = numbers[2];
+		BigDecimal d = numbers[3];
+
+		// Uses first four numbers to check if there is a pattern and to
+		// calculate the gap between them. One missing value is allowed.
+		if (b.subtract(a).equals(c.subtract(b))) {
+			gap = b.subtract(a);
+		} else if (c.subtract(b).equals(d.subtract(c))) {
+			gap = c.subtract(b);
+		} else if (b.subtract(a).equals(d.subtract(c))) {
+			gap = b.subtract(a);
+		} else {
+			// No pattern found.
+			return null;
+		}
+
+		for (int i = 0; i < (numbers.length - 1); i++) {
+			BigDecimal first = numbers[i];
+			BigDecimal second = numbers[i + 1];
+
+			if (missingNumber == null && !second.subtract(first).equals(gap)) {
+				missingNumber = second.subtract(gap);
+			} else if (!second.subtract(first).equals(gap)
+					&& missingNumber != null) {
+				// Happends if there is no pattern found, or more than 1
+				// missing number.
+				return null;
+			}
+		}
+
+		return missingNumber;
+	}
+
+	/**
+	 * Looks for multiplication pattern, on each step x multiplied or divided.
+	 * *x is the same as *(1/x) so this works for both.
+	 * 
+	 * @param numbers
+	 * @return true if pattern is found.
+	 */
+	protected static Number findMultiplicationPattern(BigDecimal[] numbers) {
+		if (numbers == null || numbers.length < MIN_NUMBER_OF_CONSTRAINTS) {
+			return null;
+		}
+		try {
+
+			BigDecimal gap = null;
+			Number missingNumber = null;
+
+			BigDecimal a = numbers[0];
+			BigDecimal b = numbers[1];
+			BigDecimal c = numbers[2];
+			BigDecimal d = numbers[3];
+
+			// Uses first four numbers to check if there is a pattern and to
+			// calculate the gap between them. One missing value is allowed.
+			if (b.divide(a).equals(c.divide(b))) {
+				gap = b.divide(a);
+			} else if (c.divide(b).equals(d.divide(c))) {
+				gap = c.divide(b);
+			} else if (b.divide(a).equals(d.divide(c))) {
+				gap = b.divide(a);
+			} else {
+				// No pattern found.
+				return null;
+			}
+
+			BigDecimal first = null;
+			BigDecimal second = null;
+			for (int i = 0; i < (numbers.length - 1); i++) {
+				first = numbers[i];
+				second = numbers[i + 1];
+
+				if (missingNumber == null && !second.divide(first).equals(gap)) {
+					missingNumber = first.multiply(gap);
+				} else if (!second.divide(first).equals(gap)
+						&& missingNumber != null) {
+					// Happends if there is no pattern found, or more than 1
+					// missing number.
+					return null;
+				}
+			}
+			return missingNumber;
+		} catch (Exception e) {
+			return null;
+		}
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/accumulateFunction/ValidatePatternResult.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/accumulateFunction/ValidatePatternResult.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/accumulateFunction/ValidatePatternResult.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,26 @@
+package org.drools.analytics.accumulateFunction;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class ValidatePatternResult {
+
+	private Number value = null;
+
+	public Number getValue() {
+		return value;
+	}
+
+	public void setValue(Number value) {
+		this.value = value;
+	}
+
+	public String toString() {
+		if (value != null) {
+			return value.toString();
+		} else {
+			return "Empty, value null";
+		}
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsAccessorDescr.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsAccessorDescr.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsAccessorDescr.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,19 @@
+package org.drools.analytics.components;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class AnalyticsAccessorDescr extends AnalyticsComponent {
+
+	private static int index = 0;
+
+	public AnalyticsAccessorDescr() {
+		super(index++);
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.ACCESSOR;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsAccumulateDescr.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsAccumulateDescr.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsAccumulateDescr.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,111 @@
+package org.drools.analytics.components;
+
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class AnalyticsAccumulateDescr extends AnalyticsComponent {
+
+	private static int index = 0;
+
+	private int inputPatternId;
+	private String initCode;
+	private String actionCode;
+	private String reverseCode;
+	private String resultCode;
+	private String[] declarations;
+	private String className;
+	private boolean externalFunction = false;
+	private String functionIdentifier;
+	private String expression;
+
+	public AnalyticsAccumulateDescr() {
+		super(index++);
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.ACCUMULATE;
+	}
+
+	public String getActionCode() {
+		return actionCode;
+	}
+
+	public void setActionCode(String actionCode) {
+		this.actionCode = actionCode;
+	}
+
+	public String getClassName() {
+		return className;
+	}
+
+	public void setClassName(String className) {
+		this.className = className;
+	}
+
+	public String[] getDeclarations() {
+		return declarations;
+	}
+
+	public void setDeclarations(String[] declarations) {
+		this.declarations = declarations;
+	}
+
+	public String getExpression() {
+		return expression;
+	}
+
+	public void setExpression(String expression) {
+		this.expression = expression;
+	}
+
+	public boolean isExternalFunction() {
+		return externalFunction;
+	}
+
+	public void setExternalFunction(boolean externalFunction) {
+		this.externalFunction = externalFunction;
+	}
+
+	public String getFunctionIdentifier() {
+		return functionIdentifier;
+	}
+
+	public void setFunctionIdentifier(String functionIdentifier) {
+		this.functionIdentifier = functionIdentifier;
+	}
+
+	public String getInitCode() {
+		return initCode;
+	}
+
+	public void setInitCode(String initCode) {
+		this.initCode = initCode;
+	}
+
+	public int getInputPatternId() {
+		return inputPatternId;
+	}
+
+	public void setInputPatternId(int inputPatternId) {
+		this.inputPatternId = inputPatternId;
+	}
+
+	public String getResultCode() {
+		return resultCode;
+	}
+
+	public void setResultCode(String resultCode) {
+		this.resultCode = resultCode;
+	}
+
+	public String getReverseCode() {
+		return reverseCode;
+	}
+
+	public void setReverseCode(String reverseCode) {
+		this.reverseCode = reverseCode;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsClass.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsClass.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsClass.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,32 @@
+package org.drools.analytics.components;
+
+import java.io.Serializable;
+
+/**
+ * @author Toni Rikkola
+ * 
+ */
+public class AnalyticsClass implements Serializable {
+	private static final long serialVersionUID = -783733402566313623L;
+
+	private static int index = 0;
+
+	private int id = index++;
+	private String name;
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsCollectDescr.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsCollectDescr.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsCollectDescr.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,38 @@
+package org.drools.analytics.components;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class AnalyticsCollectDescr extends AnalyticsComponent {
+
+	private static int index = 0;
+
+	private int insidePatternId;
+	private String classMethodName;
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.COLLECT;
+	}
+
+	public int getInsidePatternId() {
+		return insidePatternId;
+	}
+
+	public void setInsidePatternId(int insidePatternId) {
+		this.insidePatternId = insidePatternId;
+	}
+
+	public String getClassMethodName() {
+		return classMethodName;
+	}
+
+	public void setClassMethodName(String classMethodName) {
+		this.classMethodName = classMethodName;
+	}
+
+	public AnalyticsCollectDescr() {
+		super(index++);
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsComponent.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsComponent.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsComponent.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,29 @@
+package org.drools.analytics.components;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public abstract class AnalyticsComponent {
+
+	protected String ruleName;
+	protected int id;
+
+	public abstract AnalyticsComponentType getComponentType();
+
+	public AnalyticsComponent(int id) {
+		this.id = id;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public String getRuleName() {
+		return ruleName;
+	}
+
+	public void setRuleName(String ruleName) {
+		this.ruleName = ruleName;
+	}
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsComponentType.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsComponentType.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsComponentType.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,29 @@
+package org.drools.analytics.components;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public enum AnalyticsComponentType {
+	NOTHING,
+	CLASS, 
+	FIELD, 
+	RULE, 
+	CONSTRAINT, 
+	VARIABLE, 
+	PATTERN, 
+	PATTERN_POSSIBILITY, 
+	RULE_POSSIBILITY,
+	RESTRICTION, 
+	OPERATOR, 
+	FIELD_CLASS_LINK, 
+	COLLECT, 
+	ACCUMULATE, 
+	FROM, 
+	EVAL, 
+	PREDICATE, 
+	METHOD_ACCESSOR, 
+	FIELD_ACCESSOR, 
+	FUNCTION_CALL, 
+	ACCESSOR
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsEvalDescr.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsEvalDescr.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsEvalDescr.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,38 @@
+package org.drools.analytics.components;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class AnalyticsEvalDescr extends AnalyticsComponent {
+
+	private static int index = 0;
+
+	private String content;
+	private String classMethodName;
+
+	public AnalyticsEvalDescr() {
+		super(index++);
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.EVAL;
+	}
+
+	public String getClassMethodName() {
+		return classMethodName;
+	}
+
+	public void setClassMethodName(String classMethodName) {
+		this.classMethodName = classMethodName;
+	}
+
+	public String getContent() {
+		return content;
+	}
+
+	public void setContent(String content) {
+		this.content = content;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsFieldAccessDescr.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsFieldAccessDescr.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsFieldAccessDescr.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,38 @@
+package org.drools.analytics.components;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class AnalyticsFieldAccessDescr extends AnalyticsComponent {
+
+	private static int index = 0;
+
+	private String fieldName;
+	private String argument;
+
+	public AnalyticsFieldAccessDescr() {
+		super(index++);
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.FIELD_ACCESSOR;
+	}
+
+	public String getArgument() {
+		return argument;
+	}
+
+	public void setArgument(String argument) {
+		this.argument = argument;
+	}
+
+	public String getFieldName() {
+		return fieldName;
+	}
+
+	public void setFieldName(String fieldName) {
+		this.fieldName = fieldName;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsFromDescr.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsFromDescr.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsFromDescr.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,38 @@
+package org.drools.analytics.components;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class AnalyticsFromDescr extends AnalyticsComponent {
+
+	private static int index = 0;
+
+	private AnalyticsComponentType dataSourceType;
+	private int dataSourceId;
+
+	public AnalyticsFromDescr() {
+		super(index++);
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.FROM;
+	}
+
+	public int getDataSourceId() {
+		return dataSourceId;
+	}
+
+	public void setDataSourceId(int dataSourceId) {
+		this.dataSourceId = dataSourceId;
+	}
+
+	public AnalyticsComponentType getDataSourceType() {
+		return dataSourceType;
+	}
+
+	public void setDataSourceType(AnalyticsComponentType dataSourceType) {
+		this.dataSourceType = dataSourceType;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsFunctionCallDescr.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsFunctionCallDescr.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsFunctionCallDescr.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,38 @@
+package org.drools.analytics.components;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class AnalyticsFunctionCallDescr extends AnalyticsComponent {
+
+	private static int index = 0;
+
+	private String name;
+	private String arguments;
+
+	public AnalyticsFunctionCallDescr() {
+		super(index++);
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.FUNCTION_CALL;
+	}
+
+	public String getArguments() {
+		return arguments;
+	}
+
+	public void setArguments(String arguments) {
+		this.arguments = arguments;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsMethodAccessDescr.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsMethodAccessDescr.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsMethodAccessDescr.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,38 @@
+package org.drools.analytics.components;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class AnalyticsMethodAccessDescr extends AnalyticsComponent {
+
+	private static int index = 0;
+
+	private String methodName;
+	private String arguments;
+
+	public AnalyticsMethodAccessDescr() {
+		super(index++);
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.METHOD_ACCESSOR;
+	}
+
+	public String getArguments() {
+		return arguments;
+	}
+
+	public void setArguments(String arguments) {
+		this.arguments = arguments;
+	}
+
+	public String getMethodName() {
+		return methodName;
+	}
+
+	public void setMethodName(String methodName) {
+		this.methodName = methodName;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsPredicateDescr.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsPredicateDescr.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsPredicateDescr.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,38 @@
+package org.drools.analytics.components;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class AnalyticsPredicateDescr extends AnalyticsComponent {
+
+	private static int index = 0;
+
+	private String content;
+	private String classMethodName;
+
+	public AnalyticsPredicateDescr() {
+		super(index++);
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.PREDICATE;
+	}
+
+	public String getClassMethodName() {
+		return classMethodName;
+	}
+
+	public void setClassMethodName(String classMethodName) {
+		this.classMethodName = classMethodName;
+	}
+
+	public String getContent() {
+		return content;
+	}
+
+	public void setContent(String content) {
+		this.content = content;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsRule.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsRule.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/AnalyticsRule.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,77 @@
+package org.drools.analytics.components;
+
+import org.drools.analytics.result.Cause;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class AnalyticsRule extends AnalyticsComponent implements Cloneable,
+		Cause {
+
+	private static int index = 0;
+
+	private String ruleSalience;
+	private String ruleAgendaGroup;
+	private String consequence;
+	private int lineNumber;
+
+	public AnalyticsRule() {
+		super(index++);
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.RULE;
+	}
+
+	public String getRuleAgendaGroup() {
+		return ruleAgendaGroup;
+	}
+
+	public void setRuleAgendaGroup(String agendaGroup) {
+		this.ruleAgendaGroup = agendaGroup;
+	}
+
+	public String getRuleSalience() {
+		return ruleSalience;
+	}
+
+	public void setRuleSalience(String salience) {
+		this.ruleSalience = salience;
+	}
+
+	public String getConsequence() {
+		return consequence;
+	}
+
+	public void setConsequence(String consequence) {
+		this.consequence = consequence;
+	}
+
+	public int getLineNumber() {
+		return lineNumber;
+	}
+
+	public void setLineNumber(int lineNumber) {
+		this.lineNumber = lineNumber;
+	}
+
+	@Override
+	public Object clone() {
+		AnalyticsRule clone = new AnalyticsRule();
+
+		clone.setRuleName(ruleName);
+		clone.setRuleSalience(ruleSalience);
+		clone.setRuleAgendaGroup(ruleAgendaGroup);
+		clone.setConsequence(consequence);
+		clone.setLineNumber(lineNumber);
+
+		return clone;
+	}
+
+	@Override
+	public String toString() {
+		return "Rule '" + ruleName + "'";
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Constraint.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Constraint.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Constraint.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,68 @@
+package org.drools.analytics.components;
+
+import java.io.Serializable;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class Constraint extends AnalyticsComponent implements Serializable {
+	private static final long serialVersionUID = -1564096753608593465L;
+
+	private static int index = 0;
+
+	private int ruleId;
+	private int patternId;
+	private boolean patternIsNot;
+	private int fieldId;
+	private int lineNumber;
+
+	public Constraint() {
+		super(index++);
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.CONSTRAINT;
+	}
+
+	public int getFieldId() {
+		return fieldId;
+	}
+
+	public void setFieldId(int fieldId) {
+		this.fieldId = fieldId;
+	}
+
+	public int getRuleId() {
+		return ruleId;
+	}
+
+	public void setRuleId(int ruleId) {
+		this.ruleId = ruleId;
+	}
+
+	public int getLineNumber() {
+		return lineNumber;
+	}
+
+	public void setLineNumber(int lineNumber) {
+		this.lineNumber = lineNumber;
+	}
+
+	public int getPatternId() {
+		return patternId;
+	}
+
+	public void setPatternId(int patternId) {
+		this.patternId = patternId;
+	}
+
+	public boolean isPatternIsNot() {
+		return patternIsNot;
+	}
+
+	public void setPatternIsNot(boolean patternIsNot) {
+		this.patternIsNot = patternIsNot;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Field.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Field.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Field.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,82 @@
+package org.drools.analytics.components;
+
+import org.drools.analytics.result.Cause;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class Field extends AnalyticsComponent implements Cause {
+
+	public static enum FieldType {
+		BOOLEAN, STRING, INT, DOUBLE, DATE, VARIABLE, OBJECT
+	}
+
+	private static int index = 0;
+
+	private int classId;
+	private String className;
+	private String name;
+	private FieldType fieldType;
+
+	private int lineNumber;
+
+	public Field() {
+		super(index++);
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.FIELD;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public FieldType getFieldType() {
+		return fieldType;
+	}
+
+	public void setFieldType(FieldType fieldType) {
+		// Only set fieldType to variable if there is no other fieldType found.
+		if (fieldType == FieldType.VARIABLE && this.fieldType == null) {
+			this.fieldType = fieldType;
+		} else {
+			this.fieldType = fieldType;
+		}
+	}
+
+	public int getClassId() {
+		return classId;
+	}
+
+	public void setClassId(int classId) {
+		this.classId = classId;
+	}
+
+	public int getLineNumber() {
+		return lineNumber;
+	}
+
+	public void setLineNumber(int lineNumber) {
+		this.lineNumber = lineNumber;
+	}
+
+	public String getClassName() {
+		return className;
+	}
+
+	public void setClassName(String className) {
+		this.className = className;
+	}
+
+	@Override
+	public String toString() {
+		return "Field '" + name + "' from class '" + className + "'";
+	}
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/FieldClassLink.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/FieldClassLink.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/FieldClassLink.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,38 @@
+package org.drools.analytics.components;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class FieldClassLink extends AnalyticsComponent {
+
+	private static int index = 0;
+
+	private int fieldId;
+	private int classId;
+
+	public FieldClassLink() {
+		super(index++);
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.FIELD_CLASS_LINK;
+	}
+
+	public int getClassId() {
+		return classId;
+	}
+
+	public void setClassId(int classId) {
+		this.classId = classId;
+	}
+
+	public int getFieldId() {
+		return fieldId;
+	}
+
+	public void setFieldId(int fieldId) {
+		this.fieldId = fieldId;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/InlineEvalDescr.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/InlineEvalDescr.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/InlineEvalDescr.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,9 @@
+package org.drools.analytics.components;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class InlineEvalDescr {
+
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/LiteralRestriction.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,106 @@
+package org.drools.analytics.components;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import org.drools.analytics.result.Cause;
+
+
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class LiteralRestriction extends Restriction implements Cause {
+
+	private Field.FieldType valueType;
+
+	private boolean booleanValue;
+	private int intValue;
+	private double doubleValue;
+	private String stringValue;
+	private Date dateValue;
+
+	public RestrictionType getRestrictionType() {
+		return Restriction.RestrictionType.LITERAL;
+	}
+
+	public String getStringValue() {
+		return stringValue;
+	}
+
+	public double getDoubleValue() {
+		return doubleValue;
+	}
+
+	public int getIntValue() {
+		return intValue;
+	}
+
+	public Field.FieldType getValueType() {
+		return valueType;
+	}
+
+	public Date getDateValue() {
+		return dateValue;
+	}
+
+	public void setValue(String value) {
+
+		if ("true".equals(value) || "false".equals(value)) {
+			booleanValue = value.equals("true");
+			valueType = Field.FieldType.BOOLEAN;
+			stringValue = value;
+		}
+
+		try {
+			intValue = Integer.parseInt(value);
+			valueType = Field.FieldType.INT;
+			stringValue = value;
+			return;
+		} catch (NumberFormatException e) {
+			// Not int.
+		}
+
+		try {
+			doubleValue = Double.parseDouble(value);
+			valueType = Field.FieldType.DOUBLE;
+			stringValue = value;
+			return;
+		} catch (NumberFormatException e) {
+			// Not double.
+		}
+
+		try {
+			String fmt = System.getProperty("drools.dateformat");
+			if (fmt == null) {
+				fmt = "dd-MMM-yyyy";
+			}
+
+			dateValue = new SimpleDateFormat(fmt, Locale.ENGLISH).parse(value);
+			valueType = Field.FieldType.DATE;
+			stringValue = value;
+			return;
+		} catch (Exception e) {
+			// Not a date.
+		}
+
+		stringValue = value;
+		valueType = Field.FieldType.STRING;
+	}
+
+	public boolean isBooleanValue() {
+		return booleanValue;
+	}
+
+	public void setBooleanValue(boolean booleanValue) {
+		this.booleanValue = booleanValue;
+	}
+
+	@Override
+	public String toString() {
+		return "LiteralRestriction from rule '" + ruleName + "' value '"
+				+ stringValue + "'";
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/OperatorDescr.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/OperatorDescr.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/OperatorDescr.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,51 @@
+package org.drools.analytics.components;
+
+import java.io.Serializable;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class OperatorDescr extends AnalyticsComponent implements Serializable {
+	private static final long serialVersionUID = 8393994152436331910L;
+
+	private static int index = 0;
+
+	private static final OperatorDescr OR_OPERATOR = new OperatorDescr(Type.OR);
+	private static final OperatorDescr AND_OPERATOR = new OperatorDescr(Type.AND);
+
+	public static enum Type {
+		AND, OR
+	};
+
+	private Type type;
+
+	private OperatorDescr() {
+		super(index++);
+	}
+
+	public static OperatorDescr valueOf(Type type) {
+		switch (type) {
+		case OR:
+			return OR_OPERATOR;
+		case AND:
+			return AND_OPERATOR;
+		default:
+			return null;
+		}
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.OPERATOR;
+	}
+
+	private OperatorDescr(Type operatorType) {
+		super(index++);
+		this.type = operatorType;
+	}
+
+	public Type getType() {
+		return type;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Pattern.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Pattern.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Pattern.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,102 @@
+package org.drools.analytics.components;
+
+import org.drools.analytics.result.Cause;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class Pattern extends AnalyticsComponent implements Cloneable, Cause {
+
+	private static final long serialVersionUID = 5852308145251025423L;
+
+	private static int index = 0;
+
+	private int ruleId;
+	private int classId;
+	private AnalyticsComponentType sourceType;
+	private int sourceId;
+	
+	private boolean isPatternNot = false;
+	private boolean isPatternExists = false;
+	private boolean isPatternForall = false;
+
+	public Pattern() {
+		super(index++);
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.PATTERN;
+	}
+
+	public boolean isPatternNot() {
+		return isPatternNot;
+	}
+
+	public void setPatternNot(boolean isNot) {
+		this.isPatternNot = isNot;
+	}
+
+	public int getRuleId() {
+		return ruleId;
+	}
+
+	public void setRuleId(int ruleId) {
+		this.ruleId = ruleId;
+	}
+
+	public boolean isPatternExists() {
+		return isPatternExists;
+	}
+
+	public void setPatternExists(boolean isExists) {
+		this.isPatternExists = isExists;
+	}
+
+	public int getClassId() {
+		return classId;
+	}
+
+	public void setClassId(int classId) {
+		this.classId = classId;
+	}
+
+	public boolean isPatternForall() {
+		return isPatternForall;
+	}
+
+	public void setPatternForall(boolean isForall) {
+		this.isPatternForall = isForall;
+	}
+
+	public int getSourceId() {
+		return sourceId;
+	}
+
+	public void setSourceId(int sourceId) {
+		this.sourceId = sourceId;
+	}
+
+	public AnalyticsComponentType getSourceType() {
+		return sourceType;
+	}
+
+	public void setSourceType(AnalyticsComponentType sourceType) {
+		this.sourceType = sourceType;
+	}
+
+	@Override
+	public Object clone() {
+		Pattern clone = new Pattern();
+		clone.setRuleId(ruleId);
+		clone.setClassId(classId);
+		clone.setSourceType(sourceType);
+		clone.setSourceId(sourceId);
+		clone.setPatternNot(isPatternNot);
+		clone.setPatternExists(isPatternExists);
+		clone.setPatternForall(isPatternForall);
+
+		return clone;
+	}
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/PatternPossibility.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,59 @@
+package org.drools.analytics.components;
+
+import java.util.HashSet;
+import java.util.Set;
+
+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
+ * combination are true.
+ * 
+ * @author Toni Rikkola
+ */
+public class PatternPossibility extends AnalyticsComponent implements
+		Possibility {
+	private static final long serialVersionUID = 8871361928380977116L;
+
+	private static int index = 0;
+
+	private int patternId;
+	private int ruleId;
+	private Set<Cause> items = new HashSet<Cause>();
+
+	public PatternPossibility() {
+		super(index++);
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.PATTERN_POSSIBILITY;
+	}
+
+	public Set<Cause> getItems() {
+		return items;
+	}
+
+	public int getPatternId() {
+		return patternId;
+	}
+
+	public int getRuleId() {
+		return ruleId;
+	}
+
+	public void setRuleId(int ruleId) {
+		this.ruleId = ruleId;
+	}
+
+	public void setPatternId(int patternId) {
+		this.patternId = patternId;
+	}
+
+	public void add(Restriction restriction) {
+		items.add(restriction);
+	}
+}
\ No newline at end of file

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Possibility.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,16 @@
+package org.drools.analytics.components;
+
+import java.util.Set;
+
+import org.drools.analytics.result.Cause;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public interface Possibility extends Cause {
+
+	public int getId();
+
+	public Set<Cause> getItems();
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/QualifiedIdentifierRestriction.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,47 @@
+package org.drools.analytics.components;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class QualifiedIdentifierRestriction extends Restriction {
+
+	private int variableId;
+	private String variableName;
+	private String variablePath;
+
+	@Override
+	public RestrictionType getRestrictionType() {
+		return RestrictionType.QUALIFIED_IDENTIFIER;
+	}
+
+	public int getVariableId() {
+		return variableId;
+	}
+
+	public void setVariableId(int variableId) {
+		this.variableId = variableId;
+	}
+
+	public String getVariableName() {
+		return variableName;
+	}
+
+	public void setVariableName(String variableName) {
+		this.variableName = variableName;
+	}
+
+	public String getVariablePath() {
+		return variablePath;
+	}
+
+	public void setVariablePath(String variablePath) {
+		this.variablePath = variablePath;
+	}
+
+	@Override
+	public String toString() {
+		return "QualifiedIdentifierRestriction name: " + variableName
+				+ variablePath;
+	}
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Restriction.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,83 @@
+package org.drools.analytics.components;
+
+import org.drools.analytics.result.Cause;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public abstract class Restriction extends AnalyticsComponent implements Cause {
+	public static enum RestrictionType {
+		LITERAL, VARIABLE, QUALIFIED_IDENTIFIER, RETURN_VALUE_RESTRICTION
+	}
+
+	private static int index = 0;
+
+	private int ruleId;
+	private int patternId;
+	private boolean patternIsNot;
+	private int constraintId;
+	// Id of the field that this restriction is compared to.
+	private int fieldId;
+
+	private String evaluator;
+
+	public Restriction() {
+		super(index++);
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.RESTRICTION;
+	}
+
+	public abstract RestrictionType getRestrictionType();
+
+	public String getEvaluator() {
+		return evaluator;
+	}
+
+	public void setEvaluator(String evaluator) {
+		this.evaluator = evaluator;
+	}
+
+	public int getConstraintId() {
+		return constraintId;
+	}
+
+	public void setConstraintId(int constraintId) {
+		this.constraintId = constraintId;
+	}
+
+	public int getRuleId() {
+		return ruleId;
+	}
+
+	public void setRuleId(int ruleId) {
+		this.ruleId = ruleId;
+	}
+
+	public int getPatternId() {
+		return patternId;
+	}
+
+	public void setPatternId(int patternId) {
+		this.patternId = patternId;
+	}
+
+	public int getFieldId() {
+		return fieldId;
+	}
+
+	public void setFieldId(int fieldId) {
+		this.fieldId = fieldId;
+	}
+
+	public boolean isPatternIsNot() {
+		return patternIsNot;
+	}
+
+	public void setPatternIsNot(boolean patternIsNot) {
+		this.patternIsNot = patternIsNot;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/ReturValueFieldDescr.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/ReturValueFieldDescr.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/ReturValueFieldDescr.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,9 @@
+package org.drools.analytics.components;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class ReturValueFieldDescr {
+
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/ReturnValueRestriction.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,43 @@
+package org.drools.analytics.components;
+
+import org.drools.analytics.result.Cause;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class ReturnValueRestriction extends Restriction implements Cause {
+
+	private Object content;
+	private String[] declarations;
+	private String classMethodName;
+
+	@Override
+	public RestrictionType getRestrictionType() {
+		return RestrictionType.RETURN_VALUE_RESTRICTION;
+	}
+
+	public String getClassMethodName() {
+		return classMethodName;
+	}
+
+	public void setClassMethodName(String classMethodName) {
+		this.classMethodName = classMethodName;
+	}
+
+	public Object getContent() {
+		return content;
+	}
+
+	public void setContent(Object content) {
+		this.content = content;
+	}
+
+	public String[] getDeclarations() {
+		return declarations;
+	}
+
+	public void setDeclarations(String[] declarations) {
+		this.declarations = declarations;
+	}
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/RulePossibility.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,51 @@
+package org.drools.analytics.components;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+
+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
+ * PatternPosibilities in the combination are true.
+ * 
+ * @author Toni Rikkola
+ */
+public class RulePossibility extends AnalyticsComponent implements
+		Serializable, Possibility {
+	private static final long serialVersionUID = 8871361928380977116L;
+
+	private static int index = 0;
+
+	private int ruleId;
+	private Set<Cause> items = new HashSet<Cause>();
+
+	public RulePossibility() {
+		super(index++);
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.RULE_POSSIBILITY;
+	}
+
+	public Set<Cause> getItems() {
+		return items;
+	}
+
+	public int getRuleId() {
+		return ruleId;
+	}
+
+	public void setRuleId(int ruleId) {
+		this.ruleId = ruleId;
+	}
+
+	public void add(PatternPossibility patternPossibility) {
+		items.add(patternPossibility);
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Variable.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Variable.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/Variable.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,68 @@
+package org.drools.analytics.components;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class Variable extends AnalyticsComponent {
+
+	private static int index;
+
+	private int ruleId;
+	private AnalyticsComponentType objectType;
+	private int objectId;
+	private String objectName;
+	private String name;
+
+	public Variable() {
+		super(index++);
+	}
+
+	@Override
+	public AnalyticsComponentType getComponentType() {
+		return AnalyticsComponentType.VARIABLE;
+	}
+
+	public int getRuleId() {
+		return ruleId;
+	}
+
+	public void setRuleId(int ruleId) {
+		this.ruleId = ruleId;
+	}
+
+	public int getObjectId() {
+		return objectId;
+	}
+
+	public void setObjectId(int variableId) {
+		this.objectId = variableId;
+	}
+
+	public AnalyticsComponentType getObjectType() {
+		return objectType;
+	}
+
+	public void setObjectType(AnalyticsComponentType type) {
+		// AnalyticsComponentType.CLASS dominates AnalyticsComponentType.FIELD.
+		if (objectType == null || objectType != AnalyticsComponentType.CLASS) {
+			this.objectType = type;
+		}
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getObjectName() {
+		return objectName;
+	}
+
+	public void setObjectName(String objectName) {
+		this.objectName = objectName;
+	}
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/components/VariableRestriction.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,39 @@
+package org.drools.analytics.components;
+
+import org.drools.analytics.result.Cause;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class VariableRestriction extends Restriction implements Cause {
+
+	protected String variableName;
+	protected int variableId;
+
+	public int getVariableId() {
+		return variableId;
+	}
+
+	public void setVariableId(int variableId) {
+		this.variableId = variableId;
+	}
+
+	public String getVariableName() {
+		return variableName;
+	}
+
+	public void setVariableName(String variableName) {
+		this.variableName = variableName;
+	}
+
+	public RestrictionType getRestrictionType() {
+		return Restriction.RestrictionType.VARIABLE;
+	}
+
+	@Override
+	public String toString() {
+		return "VariableRestriction from rule '" + ruleName + "' name '"
+				+ variableName + "'";
+	}
+}
\ No newline at end of file

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsData.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,48 @@
+package org.drools.analytics.dao;
+
+import java.util.Collection;
+
+import org.drools.analytics.components.AnalyticsClass;
+import org.drools.analytics.components.AnalyticsRule;
+import org.drools.analytics.components.Constraint;
+import org.drools.analytics.components.Field;
+import org.drools.analytics.components.FieldClassLink;
+import org.drools.analytics.components.Pattern;
+import org.drools.analytics.components.Restriction;
+import org.drools.analytics.components.Variable;
+
+
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public interface AnalyticsData {
+
+	public void insert(AnalyticsClass clazz);
+
+	public void insert(Field field);
+
+	public void insert(Variable variable);
+
+	public void insert(AnalyticsRule rule);
+
+	public void insert(Pattern pattern);
+
+	public void insert(Constraint constraint);
+
+	public void insert(Restriction restriction);
+
+	public void insert(FieldClassLink link);
+
+	public AnalyticsClass getClassByName(String name);
+
+	public Field getFieldByClassAndFieldName(String className, String fieldName);
+
+	public Variable getVariableByRuleAndVariableName(String ruleName,
+			String variableName);
+
+	public Collection<? extends Object> getAll();
+
+	public FieldClassLink getFieldClassLink(int id, int id2);
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/dao/AnalyticsDataMaps.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,110 @@
+package org.drools.analytics.dao;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.analytics.components.AnalyticsClass;
+import org.drools.analytics.components.AnalyticsRule;
+import org.drools.analytics.components.Constraint;
+import org.drools.analytics.components.Field;
+import org.drools.analytics.components.FieldClassLink;
+import org.drools.analytics.components.Pattern;
+import org.drools.analytics.components.Restriction;
+import org.drools.analytics.components.Variable;
+
+
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class AnalyticsDataMaps implements AnalyticsData {
+
+	private Map<Integer, AnalyticsClass> classesById = new HashMap<Integer, AnalyticsClass>();
+	private Map<String, AnalyticsClass> classesByName = new HashMap<String, AnalyticsClass>();
+	private Map<String, Field> fieldsByClassAndFieldName = new HashMap<String, Field>();
+	private Map<String, FieldClassLink> fieldClassLinkByIds = new HashMap<String, FieldClassLink>();
+
+	private Map<Integer, AnalyticsRule> rulesById = new HashMap<Integer, AnalyticsRule>();
+	private Map<Integer, Pattern> patternsById = new HashMap<Integer, Pattern>();
+	private Map<Integer, Constraint> constraintsById = new HashMap<Integer, Constraint>();
+	private Map<Integer, Restriction> restrictionsById = new HashMap<Integer, Restriction>();
+
+	private Map<String, Variable> variablesByRuleAndVariableName = new HashMap<String, Variable>();
+
+	public void insert(AnalyticsClass clazz) {
+		classesById.put(Integer.valueOf(clazz.getId()), clazz);
+		classesByName.put(clazz.getName(), clazz);
+	}
+
+	public void insert(Field field) {
+		AnalyticsClass clazz = classesById.get(Integer.valueOf(field
+				.getClassId()));
+		fieldsByClassAndFieldName.put(clazz.getName() + "." + field.getName(),
+				field);
+	}
+
+	public void insert(Variable variable) {
+		AnalyticsRule rule = rulesById.get(Integer
+				.valueOf(variable.getRuleId()));
+		variablesByRuleAndVariableName.put(rule.getRuleName() + "."
+				+ variable.getName(), variable);
+	}
+
+	public void insert(AnalyticsRule rule) {
+		rulesById.put(Integer.valueOf(rule.getId()), rule);
+	}
+
+	public void insert(Pattern pattern) {
+		patternsById.put(Integer.valueOf(pattern.getId()), pattern);
+	}
+
+	public void insert(Constraint constraint) {
+		constraintsById.put(Integer.valueOf(constraint.getId()), constraint);
+	}
+
+	public void insert(Restriction restriction) {
+		restrictionsById.put(restriction.getId(), restriction);
+	}
+
+	public void insert(FieldClassLink link) {
+		fieldClassLinkByIds.put(link.getFieldId() + "." + link.getClassId(),
+				link);
+	}
+
+	public AnalyticsClass getClassByName(String name) {
+		return classesByName.get(name);
+	}
+
+	public Field getFieldByClassAndFieldName(String className, String fieldName) {
+		return fieldsByClassAndFieldName.get(className + "." + fieldName);
+	}
+
+	public Variable getVariableByRuleAndVariableName(String ruleName,
+			String variableName) {
+		return variablesByRuleAndVariableName
+				.get(ruleName + "." + variableName);
+	}
+
+	public FieldClassLink getFieldClassLink(int id, int id2) {
+		return fieldClassLinkByIds.get(id + "." + id2);
+	}
+
+	public Collection<? extends Object> getAll() {
+		List<Object> objects = new ArrayList<Object>();
+
+		objects.addAll(rulesById.values());
+		objects.addAll(patternsById.values());
+		objects.addAll(constraintsById.values());
+		objects.addAll(restrictionsById.values());
+
+		objects.addAll(classesByName.values());
+		objects.addAll(fieldsByClassAndFieldName.values());
+		objects.addAll(variablesByRuleAndVariableName.values());
+
+		return objects;
+	}
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisError.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,17 @@
+package org.drools.analytics.result;
+
+import java.io.Serializable;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class AnalysisError extends AnalysisMessage implements Serializable {
+	private static final long serialVersionUID = -7589664008092901491L;
+	
+	private static int errorIndex = 0;
+
+	public AnalysisError() {
+		id = errorIndex++;
+	}
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisMessage.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,52 @@
+package org.drools.analytics.result;
+
+import java.io.Serializable;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+abstract class AnalysisMessage implements Serializable {
+
+	protected int id;
+
+	protected String ruleName;
+	protected String message;
+	protected int lineNumber;
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public int getLineNumber() {
+		return lineNumber;
+	}
+
+	public void setLineNumber(int lineNumber) {
+		this.lineNumber = lineNumber;
+	}
+
+	public String getMessage() {
+		return message;
+	}
+
+	public void setMessage(String message) {
+		this.message = message;
+	}
+
+	public String getRuleName() {
+		return ruleName;
+	}
+
+	public void setRuleName(String ruleName) {
+		this.ruleName = ruleName;
+	}
+
+	public String toString() {
+		return ruleName + ": " + message + " On line " + lineNumber;
+	}
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisNote.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,17 @@
+package org.drools.analytics.result;
+
+import java.io.Serializable;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class AnalysisNote extends AnalysisMessage implements Serializable {
+	private static final long serialVersionUID = 5853338910928403832L;
+	
+	private static int noteIndex = 0;
+
+	public AnalysisNote() {
+		id = noteIndex++;
+	}
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisResult.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,14 @@
+package org.drools.analytics.result;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public interface AnalysisResult {
+
+	public void addError(Cause[] causes, String message, int lineNumber);
+
+	public void addNote(Cause[] causes, String message, int lineNumber);
+
+	public void addWarning(Cause[] causes, String message, int lineNumber);
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisResultNormal.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,73 @@
+package org.drools.analytics.result;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class AnalysisResultNormal implements AnalysisResult {
+	private static final long serialVersionUID = -6207688526236713721L;
+
+	private List<AnalysisNote> notes = new ArrayList<AnalysisNote>();
+	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);
+
+		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;
+	}
+
+	public List<AnalysisNote> getNotes() {
+		return notes;
+	}
+
+	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
+		
+	}
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/AnalysisWarning.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,18 @@
+package org.drools.analytics.result;
+
+import java.io.Serializable;
+
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class AnalysisWarning extends AnalysisMessage implements Serializable {
+	private static final long serialVersionUID = 1791682284155920123L;
+
+	private static int warningIndex = 0;
+
+	public AnalysisWarning() {
+		id = warningIndex++;
+	}
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Cause.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,9 @@
+package org.drools.analytics.result;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public interface Cause {
+	public String getRuleName();
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Gap.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,77 @@
+package org.drools.analytics.result;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class Gap {
+
+	private Cause cause;
+	private String ruleName;
+	private String firedRuleName;
+	private String evaluator;
+	private String value;
+
+	public String getReversedEvaluator() {
+		if (evaluator.equals("!=")) {
+			return "==";
+		} else if (evaluator.equals("==")) {
+			return "!=";
+		} else if (evaluator.equals(">")) {
+			return "<=";
+		} else if (evaluator.equals("<")) {
+			return ">=";
+		} else if (evaluator.equals(">=")) {
+			return "<";
+		} else if (evaluator.equals("<=")) {
+			return ">";
+		}
+
+		return evaluator;
+	}
+
+	public Cause getCause() {
+		return cause;
+	}
+
+	public void setCause(Cause cause) {
+		this.cause = cause;
+	}
+
+	public String getEvaluator() {
+		return evaluator;
+	}
+
+	public void setEvaluator(String evaluator) {
+		this.evaluator = evaluator;
+	}
+
+	public String getFiredRuleName() {
+		return firedRuleName;
+	}
+
+	public void setFiredRuleName(String firedRuleName) {
+		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;
+	}
+
+	public String getRuleName() {
+		return ruleName;
+	}
+
+	public void setRuleName(String ruleName) {
+		this.ruleName = ruleName;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/PartialRedundancy.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/PartialRedundancy.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/PartialRedundancy.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,53 @@
+package org.drools.analytics.result;
+
+/**
+ * Partial redundancy between left and right. Eedundancy stores the connection
+ * between left and right.
+ * 
+ * @author Toni Rikkola
+ */
+public class PartialRedundancy {
+
+	private Cause left;
+	private Cause right;
+	private Redundancy redundancy;
+
+	/**
+	 * 
+	 * @param left
+	 *            Left side parent.
+	 * @param right
+	 *            Right side parent.
+	 * @param redundancy
+	 *            Connection between left and right.
+	 */
+	public PartialRedundancy(Cause left, Cause right, Redundancy redundancy) {
+		this.left = left;
+		this.right = right;
+		this.redundancy = redundancy;
+	}
+
+	public Cause getLeft() {
+		return left;
+	}
+
+	public void setLeft(Cause left) {
+		this.left = left;
+	}
+
+	public Redundancy getRedundancy() {
+		return redundancy;
+	}
+
+	public void setRedundancy(Redundancy redundancy) {
+		this.redundancy = redundancy;
+	}
+
+	public Cause getRight() {
+		return right;
+	}
+
+	public void setRight(Cause right) {
+		this.right = right;
+	}
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Redundancy.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,37 @@
+package org.drools.analytics.result;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class Redundancy {
+
+	private Cause left;
+	private Cause right;
+
+	public Redundancy(Cause left, Cause right) {
+		this.left = left;
+		this.right = right;
+	}
+
+	public Cause getLeft() {
+		return left;
+	}
+
+	public void setLeft(Cause left) {
+		this.left = left;
+	}
+
+	public Cause getRight() {
+		return right;
+	}
+
+	public void setRight(Cause right) {
+		this.right = right;
+	}
+
+	@Override
+	public String toString() {
+		return "Redundacy between: (" + left + ") and (" + right + ").";
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Subsumption.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Subsumption.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Subsumption.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,32 @@
+package org.drools.analytics.result;
+
+/**
+ * 
+ * @author Toni Rikkola
+ */
+public class Subsumption {
+
+	private Cause left;
+	private Cause right;
+
+	public Subsumption(Cause left, Cause right) {
+		this.left = left;
+		this.right = right;
+	}
+
+	public Cause getLeft() {
+		return left;
+	}
+
+	public void setLeft(Cause left) {
+		this.left = left;
+	}
+
+	public Cause getRight() {
+		return right;
+	}
+
+	public void setRight(Cause right) {
+		this.right = right;
+	}
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/java/org/drools/analytics/result/Writer.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,22 @@
+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);
+	}
+
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckDates.drl	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,136 @@
+#created on: 7.6.2007
+package org.drools.analytics.rangeChecks.dates;
+
+#list any import classes here.
+import org.drools.analytics.components.*;
+import org.drools.analytics.accumulateFunction.ValidatePattern;
+import org.drools.analytics.accumulateFunction.ValidatePatternResult;
+import org.drools.analytics.result.AnalysisResult;
+import org.drools.analytics.result.Gap;
+
+import java.util.ArrayList;
+import java.util.TreeSet;
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+import java.util.Date;
+
+#declare any global variables here
+global AnalysisResult result
+
+
+function String dateToString(Date date) {
+		String fmt = System.getProperty("drools.dateformat");
+		if (fmt == null) {
+			fmt = "dd-MMM-yyyy";
+		}
+		
+		return new SimpleDateFormat(fmt, Locale.ENGLISH).format(date);
+}
+
+
+#
+# If all ranges are not checked for a date field.
+# 
+# Type: Warning
+# Example: in "Rule 1" Foo( bar < "27-Oct-2007" ) and in "Rule 2" Foo( bar > "27-Oct-2007" )
+# 					then Foo( bar == "27-Oct-2007" ) is missing.
+rule "Range check for dates, smaller and greater than"
+	when
+		$f :Field( fieldType == Field.FieldType.DATE )
+		(
+				$r :LiteralRestriction( fieldId == $f.id, evaluator == ">" )
+			and
+				not LiteralRestriction( fieldId == $f.id, ( evaluator == "==" || == "<=" ), 
+											patternIsNot == $r.patternIsNot, 
+											eval( dateValue.equals($r.getDateValue()) ) )
+		) or (
+				$r :LiteralRestriction( fieldId == $f.id, evaluator == "<" )
+			and
+				not LiteralRestriction( fieldId == $f.id, ( evaluator == "==" || == ">=" ), 
+											patternIsNot == $r.patternIsNot, 
+											eval( dateValue.equals($r.getDateValue()) ) )
+		) or (
+				$r :LiteralRestriction( fieldId == $f.id, evaluator == "<=" )
+			and
+				not LiteralRestriction( fieldId == $f.id, evaluator == ">", 
+											patternIsNot == $r.patternIsNot, 
+											eval( dateValue.equals($r.getDateValue()) ) )
+		) or (
+				$r :LiteralRestriction( fieldId == $f.id, evaluator == ">=" )
+			and
+				not LiteralRestriction( fieldId == $f.id, 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($r.getEvaluator());
+		gap.setFiredRuleName(drools.getRule().getName());
+		gap.setValue( dateToString($r.getDateValue()));
+		insert( gap );
+end
+
+# If all ranges are not checked for a field.
+# If equality and smaller than exist check that greater than exists too.
+#
+# Type: Warning
+# Example: in "Rule 1" Foo(bar == "27-Oct-2007" ) and in "Rule 2" Foo( bar < "27-Oct-2007" )
+# 					then Foo( bar > "27-Oct-2007" ) is missing.
+rule "Range check for dates, equal and greater than"
+	when
+		# Case Foo( bar == "27-Oct-2007" ) Foo( bar >= "27-Oct-2007" || > "27-Oct-2007" ).
+		$f :Field( fieldType == Field.FieldType.DATE )
+		$r :LiteralRestriction( fieldId == $f.id, evaluator == "==" )
+		LiteralRestriction( fieldId == $f.id, 
+								( evaluator == ">" || == ">=" ), 
+								patternIsNot == $r.patternIsNot, 
+								eval( dateValue.equals($r.getDateValue())) )
+		# Check if Foo( bar < "27-Oct-2007" || <= "27-Oct-2007" ) is missing.
+		not	LiteralRestriction( fieldId == $f.id, 
+								( 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 );
+end
+
+# If all ranges are not checked for a field.
+# If equality and smaller than exist check that greater than exists too.
+#
+# Type: Warning
+# Example: in "Rule 1" Foo(bar == "27-Oct-2007" ) and in "Rule 2" Foo( bar > "27-Oct-2007" )
+# 					then Foo( bar < "27-Oct-2007" ) is missing.
+rule "Range check for dates, equal and smaller than"
+	when
+		# Case Foo( bar == "27-Oct-2007" ) Foo( bar <= "27-Oct-2007" || < "27-Oct-2007" ).
+		$f :Field( fieldType == Field.FieldType.DATE )
+		$r :LiteralRestriction( fieldId == $f.id, evaluator == "==" )
+		LiteralRestriction( fieldId == $f.id, 
+								( evaluator == "<" || == "<=" ), 
+								patternIsNot == $r.patternIsNot, 
+								eval( dateValue.equals($r.getDateValue())) )
+		# Check if Foo( bar > "27-Oct-2007" || >= "27-Oct-2007" ) is missing.
+		not	LiteralRestriction( fieldId == $f.id, 
+								( 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 );
+end

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckDoubles.drl	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,124 @@
+#created on: 7.6.2007
+package org.drools.analytics.rangeChecks.doubles;
+
+#list any import classes here.
+import org.drools.analytics.components.*;
+import org.drools.analytics.accumulateFunction.ValidatePattern;
+import org.drools.analytics.accumulateFunction.ValidatePatternResult;
+import org.drools.analytics.result.AnalysisResult;
+import org.drools.analytics.result.Gap;
+
+import java.util.ArrayList;
+import java.util.TreeSet;
+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
+# Example: in "Rule 1" Foo(bar > 42 ) and in "Rule 2" Foo( bar < 42 )
+# 					then Foo( bar == 42 ) is missing.
+rule "Range check for doubles, smaller and greater than"
+	when
+		$f :Field( fieldType == Field.FieldType.DOUBLE )
+		(
+				$r :LiteralRestriction( fieldId == $f.id, evaluator == ">" )
+			and
+				not LiteralRestriction( fieldId == $f.id, ( evaluator == "==" || == "<=" ), 
+											patternIsNot == $r.patternIsNot, 
+											doubleValue == $r.doubleValue )
+		) or (
+				$r :LiteralRestriction( fieldId == $f.id, evaluator == "<" )
+			and
+				not LiteralRestriction( fieldId == $f.id, ( evaluator == "==" || == ">=" ), 
+											patternIsNot == $r.patternIsNot, 
+											doubleValue == $r.doubleValue )
+		) or (
+				$r :LiteralRestriction( fieldId == $f.id, evaluator == "<=" )
+			and
+				not LiteralRestriction( fieldId == $f.id, evaluator  == ">", 
+											patternIsNot == $r.patternIsNot, 
+											doubleValue == $r.doubleValue )
+		) or (
+				$r :LiteralRestriction( fieldId == $f.id, evaluator == ">=" )
+			and
+				not LiteralRestriction( fieldId == $f.id, 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($r.getEvaluator());
+		gap.setFiredRuleName(drools.getRule().getName());
+		gap.setValue($r.getDoubleValue() +"");
+		insert( gap );
+end
+
+# If all ranges are not checked for a field.
+# If equality and smaller than exist check that greater than exists too.
+#
+# Type: Warning
+# Example: in "Rule 1" Foo(bar == 42 ) and in "Rule 2" Foo( bar < 42 )
+# 					then Foo( bar > 42 ) is missing.
+rule "Range check for doubles, equal and greater than"
+	when
+		# Case Foo( bar == 42 ) Foo( bar >= 42 || > 42 ).
+		$f :Field( fieldType == Field.FieldType.DOUBLE )
+		$r :LiteralRestriction( fieldId == $f.id, evaluator == "==" )
+		LiteralRestriction( fieldId == $f.id, 
+								( evaluator == ">" || == ">=" ), 
+								patternIsNot == $r.patternIsNot, 
+								doubleValue == $r.doubleValue )
+		# Check if Foo( bar < 42 || <= 42 ) is missing.
+		not	LiteralRestriction( fieldId == $f.id, 
+								( 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 );
+end
+
+# If all ranges are not checked for a field.
+# If equality and smaller than exist check that greater than exists too.
+#
+# Type: Warning
+# Example: in "Rule 1" Foo(bar == 42 ) and in "Rule 2" Foo( bar > 42 )
+# 					then Foo( bar < 42 ) is missing.
+rule "Range check for doubles, equal and smaller than"
+	when
+		# Case Foo( bar == 42 ) Foo( bar <= 42 || < 42 ).
+		$f :Field( fieldType == Field.FieldType.DOUBLE )
+		$r :LiteralRestriction( fieldId == $f.id, evaluator == "==" )
+		LiteralRestriction( fieldId == $f.id, 
+								( evaluator == "<" || == "<=" ), 
+								patternIsNot == $r.patternIsNot, 
+								doubleValue == $r.doubleValue )
+		# Check if Foo( bar > 42 || >= 42 ) is missing.
+		not	LiteralRestriction( fieldId == $f.id, 
+								( 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 );
+end
+

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckIntegers.drl	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,169 @@
+#created on: 7.6.2007
+package org.drools.analytics.rangeChecks.integers;
+
+#list any import classes here.
+import org.drools.analytics.components.*;
+import org.drools.analytics.accumulateFunction.ValidatePattern;
+import org.drools.analytics.accumulateFunction.ValidatePatternResult;
+import org.drools.analytics.result.AnalysisResult;
+import org.drools.analytics.result.Gap;
+
+import java.util.ArrayList;
+import java.util.TreeSet;
+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
+# Example: in "Rule 1" Foo(bar > 42 ) and in "Rule 2" Foo( bar < 42 )
+# 					then Foo( bar == 42 ) is missing.
+rule "Range check for integers, smaller and greater than"
+	when
+		$f :Field( fieldType == Field.FieldType.INT, $fieldId :id, $fieldName :name, $classId :classId )
+		(
+				$r :LiteralRestriction( fieldId == $fieldId, evaluator == ">", 
+											$patternIsNot :patternIsNot, $value :intValue )
+			and
+				not LiteralRestriction( fieldId == $fieldId, ( evaluator == "==" || == "<=" ), 
+											patternIsNot == $patternIsNot, intValue == $value )
+		) or (
+				$r :LiteralRestriction( fieldId == $fieldId, evaluator == "<", 
+											$patternIsNot :patternIsNot, $value :intValue )
+			and
+				not LiteralRestriction( fieldId == $fieldId, ( evaluator == "==" || == ">=" ), 
+											patternIsNot == $patternIsNot, intValue == $value )
+		) or (
+				$r :LiteralRestriction( fieldId == $fieldId, evaluator == "<=", 
+											$patternIsNot :patternIsNot, $value :intValue )
+			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 ) )
+		) or (
+				$r :LiteralRestriction( fieldId == $fieldId, evaluator == ">=", 
+											$patternIsNot :patternIsNot, $value :intValue )
+			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 );
+end
+
+# If all ranges are not checked for a field.
+# If equality and smaller than exist check that greater than exists too.
+#
+# Type: Warning
+# Example: in "Rule 1" Foo(bar == 42 ) and in "Rule 2" Foo( bar < 42 )
+# 					then Foo( bar > 42 ) is missing.
+rule "Range check for integers, equal and greater than"
+	when
+		(
+		# Case Foo( bar == 42 ) Foo( bar >= 43 || == 43 ).
+				$f :Field( fieldType == Field.FieldType.INT )
+			and
+				$r :LiteralRestriction( fieldId == $f.id, evaluator == "==" )
+			and
+				LiteralRestriction( fieldId == $f.id, 
+										( evaluator == "==" || == ">=" ),
+										patternIsNot == $r.patternIsNot, 
+										eval( intValue == $r.getIntValue() + 1 ) )
+		) or (
+		# Case Foo( bar == 42 ) Foo( bar >= 42 || > 42 ).
+				$f :Field( fieldType == Field.FieldType.INT )
+			and
+				$r :LiteralRestriction( fieldId == $f.id, evaluator == "==" )
+			and
+				LiteralRestriction( fieldId == $f.id, 
+										( evaluator == ">" || == ">=" ), 
+										patternIsNot == $r.patternIsNot, 
+										intValue == $r.intValue )
+		)
+		# Check if Foo( bar < 42 || <= 42 ) is missing.
+		not	LiteralRestriction( fieldId == $f.id, 
+								( evaluator == "<" || == "<=" ), 
+								patternIsNot == $r.patternIsNot, 
+								intValue == $r.intValue )
+		# Check if Foo( bar == 41 || <= 41 ) is missing.
+		not	LiteralRestriction( fieldId == $f.id, 
+								( 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 );
+end
+
+# If all ranges are not checked for a field.
+# If equality and smaller than exist check that greater than exists too.
+#
+# Type: Warning
+# Example: in "Rule 1" Foo(bar == 42 ) and in "Rule 2" Foo( bar > 42 )
+# 					then Foo( bar < 42 ) is missing.
+rule "Range check for integers, equal and smaller than"
+	when
+		(
+		# Case Foo( bar == 42 ) Foo( bar <= 43 || == 43 ).
+				$f :Field( fieldType == Field.FieldType.INT )
+			and
+				$r :LiteralRestriction( fieldId == $f.id, evaluator == "==" )
+			and
+				LiteralRestriction( fieldId == $f.id, 
+										( evaluator == "==" || == "<=" ),
+										patternIsNot == $r.patternIsNot, 
+										eval( intValue == $r.getIntValue() - 1 ) )
+		) or (
+		# Case Foo( bar == 42 ) Foo( bar <= 42 || < 42 ).
+				$f :Field( fieldType == Field.FieldType.INT )
+			and
+				$r :LiteralRestriction( fieldId == $f.id, evaluator == "==" )
+			and
+				LiteralRestriction( fieldId == $f.id, 
+										( evaluator == "<" || == "<=" ), 
+										patternIsNot == $r.patternIsNot, 
+										intValue == $r.intValue )
+		)
+		# Check if Foo( bar > 42 || >= 42 ) is missing.
+		not	LiteralRestriction( fieldId == $f.id, 
+								( evaluator == ">" || == ">=" ), 
+								patternIsNot == $r.patternIsNot, 
+								intValue == $r.intValue )
+		# Check if Foo( bar == 41 || >= 41 ) is missing.
+		not	LiteralRestriction( fieldId == $f.id, 
+								( 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 );
+end

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckPatterns.drl
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckPatterns.drl	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckPatterns.drl	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,56 @@
+#created on: 7.6.2007
+package org.drools.analytics.rangeChecks.patterns;
+
+#list any import classes here.
+import org.drools.analytics.components.*;
+import org.drools.analytics.accumulateFunction.ValidatePattern;
+import org.drools.analytics.accumulateFunction.ValidatePatternResult;
+import org.drools.analytics.result.AnalysisResult;
+import org.drools.analytics.result.Gap;
+
+import java.util.ArrayList;
+import java.util.TreeSet;
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+#declare any global variables here
+global AnalysisResult result
+
+#
+# If all pattern ranges are not checked for a field.
+# 
+# Type: Warning
+# Example: in "Rule 1" Foo( bar == 10 ) and in "Rule 2" Foo( bar == 20 ) and in "Rule 3" Foo( bar == 40 )
+# 					then Foo( bar == 30 ) is missing.
+rule "Range check for number patterns"
+	when
+		$f :Field( ( fieldType == Field.FieldType.INT || == Field.FieldType.DOUBLE ), 
+					$fieldId :id, $fieldName :name, $classId :classId )
+		AnalyticsClass( id == $classId, $className :name )
+		(
+			# Where pattern is false.
+			$validationResult :ValidatePatternResult( value != null)
+				from accumulate(
+					$r :LiteralRestriction( fieldId == $fieldId, 
+						patternIsNot == false, ( evaluator == "==" || == "!=" )),
+					validatePattern( $r )
+				)
+		) or (
+			# Where pattern is true.
+			$validationResult :ValidatePatternResult( value != null)
+				from accumulate(
+					$r :LiteralRestriction( fieldId == $fieldId, 
+						patternIsNot == true, ( evaluator == "==" || == "!=" )),
+					validatePattern( $r )
+				)
+		)
+	then
+		// TODO: Find out if evaluator is == or !=.
+		Gap gap = new Gap();
+		gap.setCause($f);
+		#gap.setRuleName($rule.getRuleName());
+		#gap.setEvaluator($r.getEvaluator());
+		gap.setFiredRuleName(drools.getRule().getName());
+		gap.setValue($validationResult.toString());
+		insert( gap );
+end

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckVariables.drl
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckVariables.drl	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/RangeCheckVariables.drl	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,483 @@
+#created on: 7.6.2007
+package org.drools.analytics.rangeChecks.variables;
+
+#list any import classes here.
+import org.drools.analytics.components.*;
+import org.drools.analytics.accumulateFunction.ValidatePattern;
+import org.drools.analytics.accumulateFunction.ValidatePatternResult;
+import org.drools.analytics.result.AnalysisResult;
+import org.drools.analytics.result.Gap;
+
+import java.util.ArrayList;
+import java.util.TreeSet;
+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
+# Example: in "Rule 1" Foo(bar > 42 ) and in "Rule 2" Foo( bar < 42 )
+# 					then Foo( bar == 42 ) is missing.
+rule "Range check for integers, smaller and greater than"
+	when
+		$f :Field( fieldType == Field.FieldType.INT, $fieldId :id, $fieldName :name, $classId :classId )
+		(
+				$r :LiteralRestriction( fieldId == $fieldId, evaluator == ">", 
+											$patternIsNot :patternIsNot, $value :intValue )
+			and
+				not LiteralRestriction( fieldId == $fieldId, ( evaluator == "==" || == "<=" ), 
+											patternIsNot == $patternIsNot, intValue == $value )
+		) or (
+				$r :LiteralRestriction( fieldId == $fieldId, evaluator == "<", 
+											$patternIsNot :patternIsNot, $value :intValue )
+			and
+				not LiteralRestriction( fieldId == $fieldId, ( evaluator == "==" || == ">=" ), 
+											patternIsNot == $patternIsNot, intValue == $value )
+		) or (
+				$r :LiteralRestriction( fieldId == $fieldId, evaluator == "<=", 
+											$patternIsNot :patternIsNot, $value :intValue )
+			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 ) )
+		) or (
+				$r :LiteralRestriction( fieldId == $fieldId, evaluator == ">=", 
+											$patternIsNot :patternIsNot, $value :intValue )
+			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 );
+end
+
+# If all ranges are not checked for a field.
+# If equality and smaller than exist check that greater than exists too.
+#
+# Type: Warning
+# Example: in "Rule 1" Foo(bar == 42 ) and in "Rule 2" Foo( bar < 42 )
+# 					then Foo( bar > 42 ) is missing.
+rule "Range check for integers, equal and greater than"
+	when
+		(
+		# Case Foo( bar == 42 ) Foo( bar >= 43 || == 43 ).
+				$f :Field( fieldType == Field.FieldType.INT )
+			and
+				$r :LiteralRestriction( fieldId == $f.id, evaluator == "==" )
+			and
+				LiteralRestriction( fieldId == $f.id, 
+										( evaluator == "==" || == ">=" ),
+										patternIsNot == $r.patternIsNot, 
+										eval( intValue == $r.getIntValue() + 1 ) )
+		) or (
+		# Case Foo( bar == 42 ) Foo( bar >= 42 || > 42 ).
+				$f :Field( fieldType == Field.FieldType.INT )
+			and
+				$r :LiteralRestriction( fieldId == $f.id, evaluator == "==" )
+			and
+				LiteralRestriction( fieldId == $f.id, 
+										( evaluator == ">" || == ">=" ), 
+										patternIsNot == $r.patternIsNot, 
+										intValue == $r.intValue )
+		)
+		# Check if Foo( bar < 42 || <= 42 ) is missing.
+		not	LiteralRestriction( fieldId == $f.id, 
+								( evaluator == "<" || == "<=" ), 
+								patternIsNot == $r.patternIsNot, 
+								intValue == $r.intValue )
+		# Check if Foo( bar == 41 || <= 41 ) is missing.
+		not	LiteralRestriction( fieldId == $f.id, 
+								( 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 );
+end
+
+# If all ranges are not checked for a field.
+# If equality and smaller than exist check that greater than exists too.
+#
+# Type: Warning
+# Example: in "Rule 1" Foo(bar == 42 ) and in "Rule 2" Foo( bar > 42 )
+# 					then Foo( bar < 42 ) is missing.
+rule "Range check for integers, equal and smaller than"
+	when
+		(
+		# Case Foo( bar == 42 ) Foo( bar <= 43 || == 43 ).
+				$f :Field( fieldType == Field.FieldType.INT )
+			and
+				$r :LiteralRestriction( fieldId == $f.id, evaluator == "==" )
+			and
+				LiteralRestriction( fieldId == $f.id, 
+										( evaluator == "==" || == "<=" ),
+										patternIsNot == $r.patternIsNot, 
+										eval( intValue == $r.getIntValue() - 1 ) )
+		) or (
+		# Case Foo( bar == 42 ) Foo( bar <= 42 || < 42 ).
+				$f :Field( fieldType == Field.FieldType.INT )
+			and
+				$r :LiteralRestriction( fieldId == $f.id, evaluator == "==" )
+			and
+				LiteralRestriction( fieldId == $f.id, 
+										( evaluator == "<" || == "<=" ), 
+										patternIsNot == $r.patternIsNot, 
+										intValue == $r.intValue )
+		)
+		# Check if Foo( bar > 42 || >= 42 ) is missing.
+		not	LiteralRestriction( fieldId == $f.id, 
+								( evaluator == ">" || == ">=" ), 
+								patternIsNot == $r.patternIsNot, 
+								intValue == $r.intValue )
+		# Check if Foo( bar == 41 || >= 41 ) is missing.
+		not	LiteralRestriction( fieldId == $f.id, 
+								( 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 );
+end
+/*
+# If all ranges are not checked for a field.
+# If equality and greater than exist check that greater than exists too.
+#
+# Type: Warning
+# Example: in "Rule 1" Foo(bar == 42 ) and in "Rule 2" Foo( bar > 42 )
+# 					then Foo( bar < 42 ) is missing.
+rule "Range check for integers, equal and smaller than"
+	when
+		$f :Field( fieldType == Field.FieldType.INT, $fieldId :id, $fieldName :name, $classId :classId )
+		$r :LiteralRestriction( fieldId == $fieldId, evaluator == "==" )
+		(
+				LiteralRestriction( fieldId == $fieldId, 
+										( evaluator == "==" || == "<=" ), 
+										patternIsNot == $r.patternIsNot, 
+										eval( intValue == $r.getIntValue() - 1 ) )
+			or
+				LiteralRestriction( fieldId == $fieldId, 
+										( evaluator == "<" || == "<=" ), 
+										patternIsNot == $r.patternIsNot, intValue == $r.intValue )
+		)
+		not	LiteralRestriction( fieldId == $fieldId, 
+								( 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 );
+end
+*/
+# If all ranges are not checked for a field.
+# 
+# Type: Warning
+# Example: in "Rule 1" Foo(bar > 42 ) and in "Rule 2" Foo( bar < 42 )
+# 					then Foo( bar == 42 ) is missing.
+rule "Range check for doubles"
+	when
+		$f :Field( fieldType == Field.FieldType.DOUBLE, $fieldId :id, $fieldName :name, $classId :classId )
+		(
+				$r :LiteralRestriction( fieldId == $fieldId, evaluator == ">", 
+											$patternIsNot :patternIsNot, $value :doubleValue )
+			and
+				not LiteralRestriction( fieldId == $fieldId, ( evaluator == "==" || == "<=" ), 
+											patternIsNot == $patternIsNot, intValue == $value )
+		) or (
+				$r :LiteralRestriction( fieldId == $fieldId, evaluator == "<", 
+											$patternIsNot :patternIsNot, $value :doubleValue )
+			and
+				not LiteralRestriction( fieldId == $fieldId, ( evaluator == "==" || == ">=" ), 
+											patternIsNot == $patternIsNot, doubleValue == $value )
+		) or (
+				$r :LiteralRestriction( fieldId == $fieldId, evaluator == "<=", 
+											$patternIsNot :patternIsNot, $value :doubleValue )
+			and
+				not LiteralRestriction( fieldId == $fieldId, evaluator  == ">", 
+											patternIsNot == $patternIsNot, doubleValue == $value )
+		) or (
+				$r :LiteralRestriction( fieldId == $fieldId, evaluator == ">=", 
+											$patternIsNot :patternIsNot, $value :doubleValue )
+			and
+				not LiteralRestriction( fieldId == $fieldId, evaluator  == "<", 
+											patternIsNot == $patternIsNot, doubleValue == $value )
+		)
+		$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 );
+end
+
+# If all ranges are not checked for a date field.
+# 
+# Type: Warning
+# Example: in "Rule 1" Foo( bar < "27-Oct-2007" ) and in "Rule 2" Foo( bar > "27-Oct-2007" )
+# 					then Foo( bar == "27-Oct-2007" ) is missing.
+rule "Range check for dates"
+	when
+		$f :Field( fieldType == Field.FieldType.DATE, $fieldId :id, $fieldName :name, $classId :classId )
+		(
+				$r :LiteralRestriction( fieldId == $fieldId, evaluator == ">", 
+											$patternIsNot :patternIsNot, $value :dateValue )
+			and
+				not LiteralRestriction( fieldId == $fieldId, ( evaluator == "==" || == "<=" ), 
+											patternIsNot == $patternIsNot, eval( dateValue.equals($value) ) )
+		) or (
+				$r :LiteralRestriction( fieldId == $fieldId, evaluator == "<", 
+											$patternIsNot :patternIsNot, $value :dateValue )
+			and
+				not LiteralRestriction( fieldId == $fieldId, ( evaluator == "==" || == ">=" ), 
+											patternIsNot == $patternIsNot, eval( dateValue.equals($value) ) )
+		) or (
+				$r :LiteralRestriction( fieldId == $fieldId, evaluator == "<=", 
+											$patternIsNot :patternIsNot, $value :dateValue )
+			and
+				not LiteralRestriction( fieldId == $fieldId, evaluator == ">", 
+											patternIsNot == $patternIsNot, eval( dateValue.equals($value) ) )
+		) or (
+				$r :LiteralRestriction( fieldId == $fieldId, evaluator == ">=", 
+											$patternIsNot :patternIsNot, $value :dateValue )
+			and
+				not LiteralRestriction( fieldId == $fieldId, evaluator == "<", 
+											patternIsNot == $patternIsNot, eval( dateValue.equals($value) ) )
+		)
+		$rule :AnalyticsRule( id == $r.ruleId )
+	then
+		String fmt = System.getProperty("drools.dateformat");
+		if (fmt == null) {
+			fmt = "dd-MMM-yyyy";
+		}
+		Gap gap = new Gap();
+		gap.setCause($f);
+		gap.setRuleName($rule.getRuleName());
+		gap.setEvaluator($r.getEvaluator());
+		gap.setFiredRuleName(drools.getRule().getName());
+		gap.setValue(new SimpleDateFormat(fmt, Locale.ENGLISH).format($value));
+		insert( gap );
+end
+
+/*
+rule "test"
+	when
+		$o :Object()
+	then
+		System.out.println($o);
+end
+*/
+/*
+# If all ranges are not checked for a field.
+# 
+# Type: Warning
+# Example: in "Rule 1" Something( $value :value ) and Foo( bar > $value ) 
+#			and in "Rule 2" Something( $value :value ) and Foo( bar < $value ) 
+# 					then Foo( bar == Something.value ) is missing.
+rule "Range check for variables when restriction is QualifiedIdentifierRestriction"
+	when
+		# Find a field that is of type variable.
+		$f :Field( fieldType == Field.FieldType.VARIABLE )
+		# Find constraint that matches this field
+		# Find variable that is on the right side of this constraint i.e. bar > $foo
+		# Find another variable that points to the same field. 
+		# Find another constraint and check if it continues to check the range for this field.
+		(
+				$r :QualifiedIdentifierRestriction( fieldId == $f.id, evaluator == ">" )
+			and
+				$v1 :Variable( id == $r.variableId )
+			and
+			(
+				$v2 :Variable( objectId == $v1.objectId, objectType == $v1.objectType, id != $v1.id)
+			) or (
+			
+			and
+				not QualifiedIdentifierRestriction( fieldId == $f.id, ( evaluator == "==" || == "<=" ), 
+														variablePath == $r.variablePath, variableId == $v2.id,
+														patternIsNot == $r.patternIsNot )
+			)
+		) or (
+				$r :QualifiedIdentifierRestriction( fieldId == $f.id, evaluator == "<" )
+			and
+				$v1 :Variable( id == $r.variableId )
+			and
+				$v2 :Variable( objectId == $v1.objectId, objectType == $v1.objectType, id != $v1.id)
+			and
+				not QualifiedIdentifierRestriction( fieldId == $f.id, ( evaluator == "==" || == ">=" ), 
+														variablePath == $r.variablePath, variableId == $v2.id,
+														patternIsNot == $r.patternIsNot )
+		) or (
+				$r :QualifiedIdentifierRestriction( fieldId == $f.id, evaluator == "<=" )
+			and
+				$v1 :Variable( id == $r.variableId )
+			and
+				$v2 :Variable( objectId == $v1.objectId, objectType == $v1.objectType, id != $v1.id)
+			and
+				not QualifiedIdentifierRestriction( fieldId == $f.id, evaluator == ">", 
+														variablePath == $r.variablePath, variableId == $v2.id,
+														patternIsNot == $r.patternIsNot )
+		) or (
+				$r :QualifiedIdentifierRestriction( fieldId == $f.id, evaluator == ">=" )
+			and
+				$v1 :Variable( id == $r.variableId )
+			and
+				$v2 :Variable( objectId == $v1.objectId, objectType == $v1.objectType, id != $v1.id)
+			and
+				not QualifiedIdentifierRestriction( fieldId == $f.id, evaluator == "<", 
+														variablePath == $r.variablePath, variableId == $v2.id,
+														patternIsNot == $r.patternIsNot )
+		)
+		$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("variable");
+		insert( gap );
+		
+		#if(testTool != null){
+		#	testTool.getRulesThatHadErrors().add($rule.getRuleName());
+		#}
+end 
+
+# If all ranges are not checked for a field.
+# 
+# Type: Warning
+# Example: in "Rule 1" Something( $value :value ) and Foo( bar > $value ) 
+#			and in "Rule 2" Something( $value :value ) and Foo( bar < $value ) 
+# 					then Foo( bar == Something.value ) is missing.
+rule "Range check for variables when restriction is VariableRestriction"
+	when
+		# Find a field that is of type variable.
+		$f :Field( fieldType == Field.FieldType.VARIABLE )
+		# Find constraint that matches this field
+		# Find variable that is on the right side of this constraint i.e. bar > $foo
+		# Find another variable that points to the same field. 
+		# Find another constraint and check if it continues to check the range for this field.
+		(
+				$r :VariableRestriction( fieldId == $f.id, evaluator == ">" )
+			and
+				$v1 :Variable( id == $r.variableId )
+			and
+				$v2 :Variable( objectId == $v1.objectId, objectType == $v1.objectType, id != $v1.id)
+			and
+				not VariableRestriction( fieldId == $f.id, ( evaluator == "==" || == "<=" ), 
+														variableId == $v2.id,
+														patternIsNot == $r.patternIsNot )
+		) or (
+				$r :VariableRestriction( fieldId == $f.id, evaluator == "<" )
+			and
+				$v1 :Variable( id == $r.variableId )
+			and
+				$v2 :Variable( objectId == $v1.objectId, objectType == $v1.objectType, id != $v1.id)
+			and
+				not VariableRestriction( fieldId == $f.id, ( evaluator == "==" || == ">=" ), 
+														variableId == $v2.id,
+														patternIsNot == $r.patternIsNot )
+		) or (
+				$r :VariableRestriction( fieldId == $f.id, evaluator == "<=" )
+			and
+				$v1 :Variable( id == $r.variableId )
+			and
+				$v2 :Variable( objectId == $v1.objectId, objectType == $v1.objectType, id != $v1.id)
+			and
+				not VariableRestriction( fieldId == $f.id, evaluator == ">", 
+														variableId == $v2.id,
+														patternIsNot == $r.patternIsNot )
+		) or (
+				$r :VariableRestriction( fieldId == $f.id, evaluator == ">=" )
+			and
+				$v1 :Variable( id == $r.variableId )
+			and
+				$v2 :Variable( objectId == $v1.objectId, objectType == $v1.objectType, id != $v1.id)
+			and
+				not VariableRestriction( fieldId == $f.id, evaluator == "<", 
+														variableId == $v2.id,
+														patternIsNot == $r.patternIsNot )
+		)
+		$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("variable");
+		insert( gap );
+end 
+*/
+# If all pattern ranges are not checked for a field.
+# 
+# Type: Warning
+# Example: in "Rule 1" Foo( bar == 10 ) and in "Rule 2" Foo( bar == 20 ) and in "Rule 3" Foo( bar == 40 )
+# 					then Foo( bar == 30 ) is missing.
+rule "Range check for number patterns"
+	when
+		$f :Field( ( fieldType == Field.FieldType.INT || == Field.FieldType.DOUBLE ), 
+					$fieldId :id, $fieldName :name, $classId :classId )
+		AnalyticsClass( id == $classId, $className :name )
+		(
+			# Where pattern is false.
+			$validationResult :ValidatePatternResult( value != null)
+				from accumulate(
+					$r :LiteralRestriction( fieldId == $fieldId, 
+						patternIsNot == false, ( evaluator == "==" || == "!=" )),
+					validatePattern( $r )
+				)
+		) or (
+			# Where pattern is true.
+			$validationResult :ValidatePatternResult( value != null)
+				from accumulate(
+					$r :LiteralRestriction( fieldId == $fieldId, 
+						patternIsNot == true, ( evaluator == "==" || == "!=" )),
+					validatePattern( $r )
+				)
+		)
+	then
+		// TODO: Find out if evaluator is == or !=.
+		Gap gap = new Gap();
+		gap.setCause($f);
+		#gap.setRuleName($rule.getRuleName());
+		#gap.setEvaluator($r.getEvaluator());
+		gap.setFiredRuleName(drools.getRule().getName());
+		gap.setValue($validationResult.toString());
+		insert( gap );
+end

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/main/resources/org/drools/analytics/Redundancy.drl	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,342 @@
+#created on: 7.6.2007
+package org.drools.analytics
+
+#list any import classes here.
+import org.drools.analytics.components.*;
+import org.drools.analytics.result.*;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+
+#declare any global variables here
+global AnalysisResult result
+
+
+# TODO: And from and every object.
+//TODO: Also check that patterns and rules are redundant.
+/*
+rule "Find redundant ReturnValueRestriction"
+	when
+		# Check that Restrictions $left and $right have redundant fields.
+		$left :ReturnValueRestriction()
+		$right :ReturnValueRestriction( 
+			id != $left.id,
+			evaluator == $left.evaluator,
+			classMethodName matches $left.classMethodName,
+			compareStringArrays( declarations, $left.declarations )
+		)
+					
+		# Check that PatternPossibilities $pp1 and $pp2 have redundant fields
+		# and that they contain $left and $right.
+		$pp1 :PatternPossibility( restriction contains $left ) 
+		$pp2 :PatternPossibility( 
+					id != $pp1.id, 
+					restriction contains $right, 
+					exist == $pp1.exist, 
+					notExist == $pp1.notExist,
+					eval( restrictions.size() == $pp1.getRestrictions().size() ) 
+		)
+		# Check that there is not allready a pair with these values.
+		not RedundantPair( left == $left, right == $right )
+	then
+		insert( new RedundantPair( $pp1, $pp2, $left, $right ) );
+end
+*/
+rule "Find redundant VariableRestriction"
+	when
+		# Check that Restrictions $left and $right have redundant fields.
+		$left :VariableRestriction()
+		$right :VariableRestriction( 
+			id != $left.id, 
+			evaluator == $left.evaluator 
+		)
+		# Check that there is not already a pair with these values.
+		not Redundancy( 
+			left == $left, 
+			right == $right 
+		)
+		
+		# Check that these two variables point to the same object.
+		$v :Variable( id == $left.variableId )
+		Variable( 
+			id == $right.variableId,
+			objectType == $v.objectType,
+			objectId == $v.objectId
+		)
+	then
+		insert( new Redundancy( $left, $right ) );
+end
+
+/*
+XXX: Not sure if this can be done.
+rule "Find redundant QualifiedIdentifierRestriction"
+	when
+		# Check that Restrictions $left and $right have redundant fields.
+		$left :QualifiedIdentifierRestriction()
+		$right :QualifiedIdentifierRestriction( 
+			id != $left.id, 
+			evaluator == $left.evaluator 
+		)
+		
+		# Check that these two variables point to the same object.
+		$v :Variable( id == $left.variableId )
+		Variable( 
+			id == $right.variableId,
+			objectType == $v.objectType,
+			objectId == $v.objectId
+		)
+		
+		# Check that there is not already a pair with these values.
+		not Redundancy( 
+			left == $left, 
+			right == $right 
+		)
+		not Redundancy( 
+			left == $right, 
+			right == $left 
+		)
+	then
+		insert( new Redundancy( $left, $right ) );
+end
+*/
+
+
+rule "Find redundant LiteralRestriction"
+	when
+		# Check that Restrictions $left and $right have redundant fields.
+		$left :LiteralRestriction()
+		and
+		(
+				$right :LiteralRestriction( 
+					id != $left.id, 
+					evaluator == $left.evaluator,
+					valueType == Field.FieldType.BOOLEAN,
+					booleanValue == $left.booleanValue
+				)
+			or
+				$right :LiteralRestriction( id != $left.id, 
+					evaluator == $left.evaluator,
+					valueType == Field.FieldType.STRING,
+					stringValue matches $left.stringValue
+				)
+			or
+				$right :LiteralRestriction( 
+					id != $left.id, 
+					evaluator == $left.evaluator,
+					valueType == Field.FieldType.INT,
+					intValue == $left.intValue
+				)
+			or
+				$right :LiteralRestriction( 
+					id != $left.id, 
+					evaluator == $left.evaluator,
+					valueType == Field.FieldType.DOUBLE,
+					doubleValue == $left.doubleValue
+				)
+			or
+				$right :LiteralRestriction( 
+					id != $left.id, 
+					evaluator == $left.evaluator,
+					valueType == Field.FieldType.DATE,
+					eval( dateValue.equals($left.getDateValue()) )
+				)
+			or
+			(
+				$right :LiteralRestriction( 
+					id != $left.id, 
+					evaluator == $left.evaluator,
+					valueType == Field.FieldType.VARIABLE
+				)
+				and
+					$v :Variable( 
+						objectType == AnalyticsComponentType.FIELD,
+						objectId == $left.id
+					)
+				and
+					Variable( 
+						objectType == AnalyticsComponentType.FIELD,
+						objectId == $right.id,
+						objectName == $v.objectName,
+						name == $v.name
+					)
+			)
+		)
+		# Check that there is not already a pair with these values.
+		not Redundancy( 
+			left == $left, 
+			right == $right 
+		)
+	then
+		insert( new Redundancy( $left, $right ) );
+end
+
+
+#
+# Only checks for redundant pattern specifications, 
+# does not include actual restriction checks.
+#
+rule "Find redundant Pattern shells"
+	when
+		# Check that Patterns $left and $right have redundant fields.
+		$left :Pattern()
+		$right :Pattern( 
+			id != $left.id, 
+	  		classId == $left.classId,
+	  		# TODO: In some cases the source might be redundant with different sources.
+	 		sourceType == $left.sourceType, 
+	  		sourceId == $left.sourceId,
+	  		patternNot == $left.patternNot,
+	  		patternExists == $left.patternExists,
+	  		patternForall == $left.patternForall
+		)
+		
+		# Check that there is not already a pair with these values.
+		not Redundancy( 
+			left == $left, 
+			right == $right 
+		)
+	then
+		insert( new Redundancy( $left, $right ) );
+end
+
+#
+# Only checks for redundant rule specifications, 
+# does not include actual pattern and restriction checks.
+#
+rule "Find redundant Rule shells"
+	when
+		# Check that AnalyticsRule $left and $right have redundant fields.
+		$left :AnalyticsRule()
+		$right :AnalyticsRule( 
+			id != $left.id, 
+			ruleSalience == $left.ruleSalience,
+			ruleAgendaGroup == $left.ruleAgendaGroup,
+			consequence == $left.consequence # TODO: Check for redundancy when MVEL is solved.
+		)
+		
+		# Check that there is not already a pair with these values.
+		not Redundancy( 
+			left == $left, 
+			right == $right 
+		)
+	then
+		insert( new Redundancy( $left, $right ) );
+end
+
+
+rule "Find part of redundant PatternPossibility combination"
+	when
+		# Restriction Redundancy.
+		$redundancy :Redundancy()
+		
+		# Check that patterns are redundant.
+		$p1 :Pattern()
+		$p2 :Pattern( id != $p1.id )
+		Redundancy( 
+			left == $p1, 
+			right == $p2 
+		)
+		
+		# Find two PatternPossibilities.
+		$pp1 :PatternPossibility( 
+			patternId == $p1.id, 
+			items contains $redundancy.left 
+		)
+		$pp2 :PatternPossibility( 
+			patternId == $p2.id, 
+			items contains $redundancy.right 
+		)
+	then
+		insert( new PartialRedundancy( $pp1, $pp2, $redundancy ) );
+end
+
+
+rule "Find part of redundant RulePossibility combination"
+	when
+		# PatternPossibility Redundancy.
+		$redundancy :Redundancy()
+		
+		# Check that rules are redundant.
+		$r1 :AnalyticsRule()
+		$r2 :AnalyticsRule( id != $r1.id )
+		Redundancy( 
+			left == $r1, 
+			right == $r2 
+		)
+		
+		# Find two RulePossibilities.
+		$rp1 :RulePossibility( 
+			ruleId == $r1.id,
+			items contains $redundancy.left 
+		)
+		$rp2 :RulePossibility( 
+			ruleId == $r2.id, 
+			items contains $redundancy.right 
+		)
+	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 )
+		
+		# 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 )
+			)
+	then
+		insert( new Subsumption( $pp1, $pp2 ) );
+end
+
+
+#
+# Checks for all PartialRedundancys that contain either PatternPossibilities
+# or RulePossibilities.
+#
+rule "Find redundant PartialRedundancies"
+	when
+		# If both sides are in subsumption with each other, 
+		# then they are also redundant.
+		$pr :PartialRedundancy()
+		PartialRedundancy( 
+			leftParent == $pr.rightParent, 
+			rightParent == $pr.leftParent 
+		)
+	then
+		insert( new Redundancy( $pr.leftParent, $pr.rightParent ) );
+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.
+
+*/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

Deleted: labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/BasicTest.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/BasicTest.java	2007-08-27 14:53:06 UTC (rev 14649)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/BasicTest.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -1,147 +0,0 @@
-package org.drools.analytics;
-
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-
-import org.drools.CheckedDroolsException;
-import org.drools.RuleBase;
-import org.drools.WorkingMemory;
-import org.drools.compiler.RuleBaseLoader;
-
-import junit.framework.TestCase;
-
-public class BasicTest extends TestCase {
-
-    public void testLessThan() throws Exception {
-        Rule rule = new Rule();
-        
-        Constraint con = new Constraint();
-        con.setField( "foo" );
-        con.setObjectType( "Bar" );
-        con.setOperator( "<" );
-        con.setRuleName( "xxx" );
-        
-        WorkingMemory wm = getAnalysisEngine();
-        
-        AnalysisResult result = new AnalysisResult();
-        wm.setGlobal( "result", result );        
-        wm.assertObject( con );
-        wm.assertObject( rule );
-        
-        wm.fireAllRules();
-        
-        assertEquals(1, result.getWarnings().size());
-        assertEquals(0, result.getErrors().size());        
-    }
-    
-    public void testLessThanMultiple() throws Exception {
-        final Constraint con = new Constraint();
-        con.setField( "foo" );
-        con.setObjectType( "Bar" );
-        con.setOperator( "<" );
-        con.setRuleName( "xxx" );
-        
-        Constraint con2 = new Constraint();
-        con2.setField( "foo2" );
-        con2.setObjectType( "Bar" );
-        con2.setOperator( "<" );
-        con2.setRuleName( "zar" );
-        
-        
-        WorkingMemory wm = getAnalysisEngine();
-        
-        AnalysisResult result = new AnalysisResult();
-        wm.setGlobal( "result", result );        
-        wm.assertObject( con );
-        wm.assertObject( con2 );
-        wm.assertObject( new Rule() );
-        wm.fireAllRules();
-        
-        assertEquals(2, result.getWarnings().size());
-        assertEquals(0, result.getErrors().size());        
-    }    
-    
-    public void testLessThanMultiple2() throws Exception {
-        final Constraint con = new Constraint();
-        con.setField( "foo" );
-        con.setObjectType( "Bar" );
-        con.setOperator( "<" );
-        con.setRuleName( "xxx" );
-        
-        Constraint con2 = new Constraint();
-        con2.setField( "foo2" );
-        con2.setObjectType( "Bar" );
-        con2.setOperator( "<" );
-        con2.setRuleName( "xxx" );
-        
-        
-        WorkingMemory wm = getAnalysisEngine();
-        
-        AnalysisResult result = new AnalysisResult();
-        wm.setGlobal( "result", result );        
-        wm.assertObject( con );
-        wm.assertObject( con2 );
-        wm.assertObject( new Rule() );
-        
-        wm.fireAllRules();
-        
-        assertEquals(2, result.getWarnings().size());
-        assertEquals(0, result.getErrors().size());        
-    }       
-
-    private WorkingMemory getAnalysisEngine() throws CheckedDroolsException,
-                                             IOException {
-        Reader r = new InputStreamReader(this.getClass().getResourceAsStream( "/StaticQualityAnalysis.drl" ));
-        RuleBase rb = RuleBaseLoader.getInstance().loadFromReader( r );
-        WorkingMemory wm = rb.newWorkingMemory();
-        return wm;
-    }
-    
-    public void testLessThanOK() throws Exception {
-        Constraint con = new Constraint();
-        con.setField( "foo" );
-        con.setObjectType( "Bar" );
-        con.setOperator( "<" );
-        con.setRuleName( "xxx" );
-        
-        Constraint con2 = new Constraint();
-        con2.setField( "foo" );
-        con2.setObjectType( "Bar" );
-        con2.setOperator( ">=" );
-        con2.setRuleName( "xxx2" );
-        
-        
-        WorkingMemory wm = getAnalysisEngine();
-        
-        AnalysisResult result = new AnalysisResult();
-        wm.setGlobal( "result", result );        
-        
-        wm.assertObject( con );
-        wm.assertObject( con2 );
-        wm.assertObject( new Rule() );
-        
-        wm.fireAllRules();
-        
-        assertEquals(0, result.getWarnings().size());
-        assertEquals(0, result.getErrors().size());          
-    }
-    
-    public void testNoRHS() throws Exception {
-        WorkingMemory wm = getAnalysisEngine();
-        
-        Rule r = new Rule();
-        r.setRhs( "" );
-        
-        AnalysisResult result = new AnalysisResult();
-        
-        wm.setGlobal( "result", result );
-        
-        wm.assertObject( r );
-        
-        wm.fireAllRules();
-        
-        assertEquals(1, result.getWarnings().size());
-    }
-    
-}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/PatternSolverTest.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/PatternSolverTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/PatternSolverTest.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,395 @@
+package org.drools.analytics;
+
+import java.util.List;
+import java.util.Set;
+
+import org.drools.analytics.components.AnalyticsComponent;
+import org.drools.analytics.components.LiteralRestriction;
+import org.drools.analytics.components.OperatorDescr;
+import org.drools.analytics.components.Pattern;
+
+
+
+import junit.framework.TestCase;
+
+/**
+ * 
+ * @author Toni Rikkola
+ *
+ */
+public class PatternSolverTest extends TestCase {
+
+	/**
+	 * <pre>
+	 *      and
+	 *     /   \
+	 *  descr  descr2
+	 * </pre>
+	 * 
+	 * result:<br>
+	 * descr && descr2
+	 */
+	public void testAddBasicAnd() {
+		Pattern pattern = new Pattern();
+
+		LiteralRestriction literalRestriction = new LiteralRestriction();
+		LiteralRestriction literalRestriction2 = new LiteralRestriction();
+
+		OperatorDescr operatorDescr = OperatorDescr
+				.valueOf(OperatorDescr.Type.AND);
+		PatternSolver solver = new PatternSolver(pattern);
+
+		solver.add(operatorDescr);
+		solver.add(literalRestriction);
+		solver.add(literalRestriction2);
+		solver.end();
+
+		List<Set<AnalyticsComponent>> list = solver.getPossibilityLists();
+		assertEquals(1, list.size());
+		assertEquals(2, list.get(0).size());
+	}
+
+	/**
+	 * <pre>
+	 *       or
+	 *      /  \
+	 *  descr descr2
+	 * </pre>
+	 * 
+	 * result:<br>
+	 * descr<br>
+	 * or<br>
+	 * descr2
+	 */
+	public void testAddBasicOr() {
+		Pattern pattern = new Pattern();
+
+		LiteralRestriction literalRestriction = new LiteralRestriction();
+		LiteralRestriction literalRestriction2 = new LiteralRestriction();
+
+		OperatorDescr operatorDescr = OperatorDescr
+				.valueOf(OperatorDescr.Type.OR);
+		PatternSolver solver = new PatternSolver(pattern);
+
+		solver.add(operatorDescr);
+		solver.add(literalRestriction);
+		solver.add(literalRestriction2);
+		solver.end();
+
+		List<Set<AnalyticsComponent>> list = solver.getPossibilityLists();
+		assertEquals(2, list.size());
+		assertEquals(1, list.get(0).size());
+		assertEquals(1, list.get(1).size());
+	}
+
+	/**
+	 * <pre>
+	 *       or
+	 *      /  \
+	 *  descr  and
+	 *         / \
+	 *    descr2 descr3
+	 * </pre>
+	 * 
+	 * result:<br>
+	 * descr <br>
+	 * or<br>
+	 * descr2 && descr3
+	 */
+	public void testAddOrAnd() {
+		Pattern pattern = new Pattern();
+
+		LiteralRestriction literalRestriction = new LiteralRestriction();
+		LiteralRestriction literalRestriction2 = new LiteralRestriction();
+		LiteralRestriction literalRestriction3 = new LiteralRestriction();
+
+		OperatorDescr orDescr = OperatorDescr.valueOf(OperatorDescr.Type.OR);
+		OperatorDescr andDescr = OperatorDescr.valueOf(OperatorDescr.Type.AND);
+		PatternSolver solver = new PatternSolver(pattern);
+
+		solver.add(orDescr);
+		solver.add(literalRestriction);
+		solver.add(andDescr);
+		solver.add(literalRestriction2);
+		solver.add(literalRestriction3);
+		solver.end();
+		solver.end();
+
+		List<Set<AnalyticsComponent>> list = solver.getPossibilityLists();
+		assertEquals(2, list.size());
+
+		assertEquals(1, list.get(0).size());
+		assertTrue(list.get(0).contains(literalRestriction));
+
+		assertEquals(2, list.get(1).size());
+		assertTrue(list.get(1).contains(literalRestriction2));
+		assertTrue(list.get(1).contains(literalRestriction3));
+	}
+
+	/**
+	 * <pre>
+	 *       and
+	 *      /  \
+	 *  descr   or
+	 *         / \
+	 *    descr2 descr3
+	 * </pre>
+	 * 
+	 * result:<br>
+	 * descr && descr2 <br>
+	 * or<br>
+	 * descr && descr3
+	 */
+	public void testAddAndOr() {
+		Pattern pattern = new Pattern();
+
+		LiteralRestriction literalRestriction = new LiteralRestriction();
+		LiteralRestriction literalRestriction2 = new LiteralRestriction();
+		LiteralRestriction literalRestriction3 = new LiteralRestriction();
+
+		OperatorDescr orDescr = OperatorDescr.valueOf(OperatorDescr.Type.AND);
+		OperatorDescr andDescr = OperatorDescr.valueOf(OperatorDescr.Type.OR);
+		PatternSolver solver = new PatternSolver(pattern);
+
+		solver.add(orDescr);
+		solver.add(literalRestriction);
+		solver.add(andDescr);
+		solver.add(literalRestriction2);
+		solver.add(literalRestriction3);
+		solver.end();
+		solver.end();
+
+		List<Set<AnalyticsComponent>> list = solver.getPossibilityLists();
+		assertEquals(2, list.size());
+
+		assertEquals(2, list.get(0).size());
+		assertTrue(list.get(0).contains(literalRestriction));
+		assertTrue(list.get(0).contains(literalRestriction2));
+
+		assertEquals(2, list.get(1).size());
+		assertTrue(list.get(1).contains(literalRestriction));
+		assertTrue(list.get(1).contains(literalRestriction3));
+	}
+
+	/**
+	 * <pre>
+	 *            and
+	 *         /        \
+	 *       or          or
+	 *      /  \         / \
+	 * descr descr2 descr3 descr4
+	 * </pre>
+	 * 
+	 * result:<br>
+	 * descr && descr3<br>
+	 * or<br>
+	 * descr && descr4<br>
+	 * or<br>
+	 * descr2 && descr3<br>
+	 * or<br>
+	 * descr2 && descr4
+	 */
+	public void testAddAndOrOr() {
+		Pattern pattern = new Pattern();
+
+		LiteralRestriction literalRestriction = new LiteralRestriction();
+		LiteralRestriction literalRestriction2 = new LiteralRestriction();
+		LiteralRestriction literalRestriction3 = new LiteralRestriction();
+		LiteralRestriction literalRestriction4 = new LiteralRestriction();
+
+		OperatorDescr andDescr = OperatorDescr.valueOf(OperatorDescr.Type.AND);
+		OperatorDescr orDescr = OperatorDescr.valueOf(OperatorDescr.Type.OR);
+		OperatorDescr orDescr2 = OperatorDescr.valueOf(OperatorDescr.Type.OR);
+		PatternSolver solver = new PatternSolver(pattern);
+
+		solver.add(andDescr);
+		solver.add(orDescr);
+		solver.add(literalRestriction);
+		solver.add(literalRestriction2);
+		solver.end();
+		solver.add(orDescr2);
+		solver.add(literalRestriction3);
+		solver.add(literalRestriction4);
+		solver.end();
+		solver.end();
+
+		List<Set<AnalyticsComponent>> list = solver.getPossibilityLists();
+		assertEquals(4, list.size());
+
+		assertEquals(2, list.get(0).size());
+		assertTrue(list.get(0).contains(literalRestriction));
+		assertTrue(list.get(0).contains(literalRestriction3));
+
+		assertEquals(2, list.get(1).size());
+		assertTrue(list.get(1).contains(literalRestriction));
+		assertTrue(list.get(1).contains(literalRestriction4));
+
+		assertEquals(2, list.get(2).size());
+		assertTrue(list.get(2).contains(literalRestriction2));
+		assertTrue(list.get(2).contains(literalRestriction3));
+
+		assertEquals(2, list.get(3).size());
+		assertTrue(list.get(3).contains(literalRestriction2));
+		assertTrue(list.get(3).contains(literalRestriction4));
+	}
+
+	/**
+	 * <pre>
+	 *             or
+	 *         /        \
+	 *       and         and
+	 *      /  \         / \
+	 * descr descr2 descr3 descr4
+	 * </pre>
+	 * 
+	 * result:<br>
+	 * descr && descr2<br>
+	 * or<br>
+	 * descr3 && descr4
+	 */
+	public void testAddOrAndAnd() {
+		Pattern pattern = new Pattern();
+
+		LiteralRestriction literalRestriction = new LiteralRestriction();
+		LiteralRestriction literalRestriction2 = new LiteralRestriction();
+		LiteralRestriction literalRestriction3 = new LiteralRestriction();
+		LiteralRestriction literalRestriction4 = new LiteralRestriction();
+
+		OperatorDescr orDescr = OperatorDescr.valueOf(OperatorDescr.Type.OR);
+		OperatorDescr andDescr = OperatorDescr.valueOf(OperatorDescr.Type.AND);
+		OperatorDescr andDescr2 = OperatorDescr.valueOf(OperatorDescr.Type.AND);
+		PatternSolver solver = new PatternSolver(pattern);
+
+		solver.add(orDescr);
+		solver.add(andDescr);
+		solver.add(literalRestriction);
+		solver.add(literalRestriction2);
+		solver.end();
+		solver.add(andDescr2);
+		solver.add(literalRestriction3);
+		solver.add(literalRestriction4);
+		solver.end();
+		solver.end();
+
+		List<Set<AnalyticsComponent>> list = solver.getPossibilityLists();
+		assertEquals(2, list.size());
+
+		assertEquals(2, list.get(0).size());
+		assertTrue(list.get(0).contains(literalRestriction));
+		assertTrue(list.get(0).contains(literalRestriction2));
+
+		assertEquals(2, list.get(1).size());
+		assertTrue(list.get(1).contains(literalRestriction3));
+		assertTrue(list.get(1).contains(literalRestriction4));
+	}
+
+	/**
+	 * <pre>
+	 *             or
+	 *         /        \
+	 *       and         or
+	 *      /  \         / \
+	 * descr descr2 descr3 descr4
+	 * </pre>
+	 * 
+	 * result:<br>
+	 * descr && descr2<br>
+	 * or<br>
+	 * descr3<br>
+	 * or<br>
+	 * descr4
+	 */
+	public void testAddOrAndOr() {
+		Pattern pattern = new Pattern();
+
+		LiteralRestriction literalRestriction = new LiteralRestriction();
+		LiteralRestriction literalRestriction2 = new LiteralRestriction();
+		LiteralRestriction literalRestriction3 = new LiteralRestriction();
+		LiteralRestriction literalRestriction4 = new LiteralRestriction();
+
+		OperatorDescr orDescr = OperatorDescr.valueOf(OperatorDescr.Type.OR);
+		OperatorDescr andDescr = OperatorDescr.valueOf(OperatorDescr.Type.AND);
+		OperatorDescr orDescr2 = OperatorDescr.valueOf(OperatorDescr.Type.OR);
+		PatternSolver solver = new PatternSolver(pattern);
+
+		solver.add(orDescr);
+		solver.add(andDescr);
+		solver.add(literalRestriction);
+		solver.add(literalRestriction2);
+		solver.end();
+		solver.add(orDescr2);
+		solver.add(literalRestriction3);
+		solver.add(literalRestriction4);
+		solver.end();
+		solver.end();
+
+		List<Set<AnalyticsComponent>> list = solver.getPossibilityLists();
+		assertEquals(3, list.size());
+
+		assertEquals(2, list.get(0).size());
+		assertTrue(list.get(0).contains(literalRestriction));
+		assertTrue(list.get(0).contains(literalRestriction2));
+
+		assertEquals(1, list.get(1).size());
+		assertTrue(list.get(1).contains(literalRestriction3));
+
+		assertEquals(1, list.get(2).size());
+		assertTrue(list.get(2).contains(literalRestriction4));
+	}
+
+	/**
+	 * <pre>
+	 *                   and
+	 *          /         |      \
+	 *       and         or       descr5
+	 *      /  \         / \
+	 * descr descr2 descr3 descr4
+	 * </pre>
+	 * 
+	 * result:<br>
+	 * descr && descr2 && descr3 && descr5<br>
+	 * or<br>
+	 * descr && descr2 && descr4 && descr5<br>
+	 */
+	public void testAddOrAndOrDescr() {
+		Pattern pattern = new Pattern();
+
+		LiteralRestriction literalRestriction = new LiteralRestriction();
+		LiteralRestriction literalRestriction2 = new LiteralRestriction();
+		LiteralRestriction literalRestriction3 = new LiteralRestriction();
+		LiteralRestriction literalRestriction4 = new LiteralRestriction();
+		LiteralRestriction literalRestriction5 = new LiteralRestriction();
+
+		OperatorDescr andDescr = OperatorDescr.valueOf(OperatorDescr.Type.AND);
+		OperatorDescr andDescr2 = OperatorDescr.valueOf(OperatorDescr.Type.AND);
+		OperatorDescr orDescr = OperatorDescr.valueOf(OperatorDescr.Type.OR);
+		PatternSolver solver = new PatternSolver(pattern);
+
+		solver.add(andDescr);
+		solver.add(andDescr2);
+		solver.add(literalRestriction);
+		solver.add(literalRestriction2);
+		solver.end();
+		solver.add(orDescr);
+		solver.add(literalRestriction3);
+		solver.add(literalRestriction4);
+		solver.end();
+		solver.add(literalRestriction5);
+		solver.end();
+
+		List<Set<AnalyticsComponent>> list = solver.getPossibilityLists();
+		assertEquals(2, list.size());
+
+		assertEquals(4, list.get(0).size());
+		assertTrue(list.get(0).contains(literalRestriction));
+		assertTrue(list.get(0).contains(literalRestriction2));
+		assertTrue(list.get(0).contains(literalRestriction3));
+		assertTrue(list.get(0).contains(literalRestriction5));
+
+		assertEquals(4, list.get(1).size());
+		assertTrue(list.get(1).contains(literalRestriction));
+		assertTrue(list.get(1).contains(literalRestriction2));
+		assertTrue(list.get(1).contains(literalRestriction4));
+		assertTrue(list.get(1).contains(literalRestriction4));
+	}
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RangeCheckDatesTest.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,155 @@
+package org.drools.analytics;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.drools.StatelessSession;
+import org.drools.StatelessSessionResult;
+import org.drools.analytics.result.AnalysisResultNormal;
+import org.drools.analytics.result.Gap;
+import org.drools.base.RuleNameMatchesAgendaFilter;
+
+
+/**
+ * 
+ * @author Toni Rikkola
+ *
+ */
+public class RangeCheckDatesTest extends TestBase {
+
+	public void testSmallerAndGreaterThan() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("RangeCheckDates.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Range check for dates, smaller and greater than"));
+
+		Collection<Object> data = getTestData(this.getClass()
+				.getResourceAsStream("MissingRangesForDates.drl"));
+
+		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
+		session.setGlobal("result", analysisResult);
+
+		StatelessSessionResult sessionResult = session.executeWithResults(data);
+
+		Iterator iter = sessionResult.iterateObjects();
+
+		Set<String> rulesThatHadErrors = new HashSet<String>();
+		while (iter.hasNext()) {
+			Object o = (Object) iter.next();
+			if (o instanceof Gap) {
+				rulesThatHadErrors.add(((Gap) o).getRuleName());
+			}
+			// System.out.println(o);
+		}
+
+		assertTrue(rulesThatHadErrors.remove("Date range 1a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 2a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 3a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 4a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 7a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 7b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 8a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 8b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 9a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 9b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 10a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 10b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 11a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 11b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 12a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 13a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 14a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 15a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 18a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 18b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 19a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 19b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 20a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 20b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 21a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 21b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 22a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 22b, has gap"));
+
+		if (!rulesThatHadErrors.isEmpty()) {
+			for (String string : rulesThatHadErrors) {
+				fail("Rule " + string + " caused an error.");
+			}
+		}
+	}
+
+	public void testEqualAndGreaterThan() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("RangeCheckDates.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Range check for dates, equal and greater than"));
+
+		Collection<Object> data = getTestData(this.getClass()
+				.getResourceAsStream("MissingRangesForDates.drl"));
+
+		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
+		session.setGlobal("result", analysisResult);
+
+		StatelessSessionResult sessionResult = session.executeWithResults(data);
+
+		Iterator iter = sessionResult.iterateObjects();
+
+		Set<String> rulesThatHadErrors = new HashSet<String>();
+		while (iter.hasNext()) {
+			Object o = (Object) iter.next();
+			if (o instanceof Gap) {
+				rulesThatHadErrors.add(((Gap) o).getRuleName());
+			}
+			// System.out.println(o);
+		}
+
+		assertTrue(rulesThatHadErrors.remove("Date range 5b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 16b, has gap"));
+
+		if (!rulesThatHadErrors.isEmpty()) {
+			for (String string : rulesThatHadErrors) {
+				fail("Rule " + string + " fired.");
+			}
+		}
+	}
+
+	public void testEqualAndSmallerThan() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("RangeCheckDates.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Range check for dates, equal and smaller than"));
+
+		Collection<Object> data = getTestData(this.getClass()
+				.getResourceAsStream("MissingRangesForDates.drl"));
+
+		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
+		session.setGlobal("result", analysisResult);
+
+		StatelessSessionResult sessionResult = session.executeWithResults(data);
+
+		Iterator iter = sessionResult.iterateObjects();
+
+		Set<String> rulesThatHadErrors = new HashSet<String>();
+		while (iter.hasNext()) {
+			Object o = (Object) iter.next();
+			if (o instanceof Gap) {
+				rulesThatHadErrors.add(((Gap) o).getRuleName());
+			}
+			// System.out.println(o);
+		}
+
+		assertTrue(rulesThatHadErrors.remove("Date range 6b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Date range 17b, has gap"));
+
+		if (!rulesThatHadErrors.isEmpty()) {
+			for (String string : rulesThatHadErrors) {
+				fail("Rule " + string + " fired.");
+			}
+		}
+	}
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RangeCheckDoublesTest.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,155 @@
+package org.drools.analytics;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.drools.StatelessSession;
+import org.drools.StatelessSessionResult;
+import org.drools.analytics.result.AnalysisResultNormal;
+import org.drools.analytics.result.Gap;
+import org.drools.base.RuleNameMatchesAgendaFilter;
+
+
+/**
+ * 
+ * @author Toni Rikkola
+ *
+ */
+public class RangeCheckDoublesTest extends TestBase {
+
+	public void testSmallerAndGreaterThan() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("RangeCheckDoubles.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Range check for doubles, smaller and greater than"));
+
+		Collection<Object> data = getTestData(this.getClass()
+				.getResourceAsStream("MissingRangesForDoubles.drl"));
+
+		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
+		session.setGlobal("result", analysisResult);
+
+		StatelessSessionResult sessionResult = session.executeWithResults(data);
+
+		Iterator iter = sessionResult.iterateObjects();
+
+		Set<String> rulesThatHadErrors = new HashSet<String>();
+		while (iter.hasNext()) {
+			Object o = (Object) iter.next();
+			if (o instanceof Gap) {
+				rulesThatHadErrors.add(((Gap) o).getRuleName());
+			}
+			// System.out.println(o);
+		}
+
+		assertTrue(rulesThatHadErrors.remove("Double range 1a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 2a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 3a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 4a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 7a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 7b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 8a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 8b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 9a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 9b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 10a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 10b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 11a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 11b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 12a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 13a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 14a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 15a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 18a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 18b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 19a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 19b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 20a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 20b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 21a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 21b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 22a, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 22b, has gap"));
+
+		if (!rulesThatHadErrors.isEmpty()) {
+			for (String string : rulesThatHadErrors) {
+				fail("Rule " + string + " caused an error.");
+			}
+		}
+	}
+
+	public void testEqualAndGreaterThan() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("RangeCheckDoubles.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Range check for doubles, equal and greater than"));
+
+		Collection<Object> data = getTestData(this.getClass()
+				.getResourceAsStream("MissingRangesForDoubles.drl"));
+
+		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
+		session.setGlobal("result", analysisResult);
+
+		StatelessSessionResult sessionResult = session.executeWithResults(data);
+
+		Iterator iter = sessionResult.iterateObjects();
+
+		Set<String> rulesThatHadErrors = new HashSet<String>();
+		while (iter.hasNext()) {
+			Object o = (Object) iter.next();
+			if (o instanceof Gap) {
+				rulesThatHadErrors.add(((Gap) o).getRuleName());
+			}
+			// System.out.println(o);
+		}
+		
+		assertTrue(rulesThatHadErrors.remove("Double range 5b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 16b, has gap"));
+
+		if (!rulesThatHadErrors.isEmpty()) {
+			for (String string : rulesThatHadErrors) {
+				fail("Rule " + string + " fired.");
+			}
+		}
+	}
+
+	public void testEqualAndSmallerThan() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("RangeCheckDoubles.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Range check for doubles, equal and smaller than"));
+
+		Collection<Object> data = getTestData(this.getClass()
+				.getResourceAsStream("MissingRangesForDoubles.drl"));
+
+		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
+		session.setGlobal("result", analysisResult);
+
+		StatelessSessionResult sessionResult = session.executeWithResults(data);
+
+		Iterator iter = sessionResult.iterateObjects();
+
+		Set<String> rulesThatHadErrors = new HashSet<String>();
+		while (iter.hasNext()) {
+			Object o = (Object) iter.next();
+			if (o instanceof Gap) {
+				rulesThatHadErrors.add(((Gap) o).getRuleName());
+			}
+			// System.out.println(o);
+		}
+		
+		assertTrue(rulesThatHadErrors.remove("Double range 6b, has gap"));
+		assertTrue(rulesThatHadErrors.remove("Double range 17b, has gap"));
+
+		if (!rulesThatHadErrors.isEmpty()) {
+			for (String string : rulesThatHadErrors) {
+				fail("Rule " + string + " fired.");
+			}
+		}
+	}
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RangeCheckIntegersTest.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,152 @@
+package org.drools.analytics;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.drools.StatelessSession;
+import org.drools.StatelessSessionResult;
+import org.drools.analytics.result.AnalysisResultNormal;
+import org.drools.analytics.result.Gap;
+import org.drools.base.RuleNameMatchesAgendaFilter;
+
+
+/**
+ * 
+ * @author Toni Rikkola
+ *
+ */
+public class RangeCheckIntegersTest extends TestBase {
+
+	public void testSmallerAndGreaterThan() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("RangeCheckIntegers.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Range check for integers, smaller and greater than"));
+
+		Collection<Object> data = getTestData(this.getClass()
+				.getResourceAsStream("MissingRangesForInts.drl"));
+
+		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
+		session.setGlobal("result", analysisResult);
+
+		StatelessSessionResult sessionResult = session.executeWithResults(data);
+
+		Iterator iter = sessionResult.iterateObjects();
+
+		Set<String> rulesThatHadErrors = new HashSet<String>();
+		while (iter.hasNext()) {
+			Object o = (Object) iter.next();
+			if (o instanceof Gap) {
+				rulesThatHadErrors.add(((Gap) o).getRuleName());
+			}
+			// System.out.println(o);
+		}
+
+		assertTrue(rulesThatHadErrors.remove("Missing int range 1a, warning"));
+		assertTrue(rulesThatHadErrors.remove("Missing int range 1b, warning"));
+		assertTrue(rulesThatHadErrors.remove("Missing int range 2a, warning"));
+		assertTrue(rulesThatHadErrors.remove("Missing int range 2b, warning"));
+		assertTrue(rulesThatHadErrors.remove("Missing int range 3a, warning"));
+		assertTrue(rulesThatHadErrors.remove("Missing int range 3b, warning"));
+		assertTrue(rulesThatHadErrors.remove("Missing int range 4a, warning"));
+		assertTrue(rulesThatHadErrors.remove("Missing int range 4b, warning"));
+		assertTrue(rulesThatHadErrors
+				.remove("Missing not int range 7a, warning"));
+		assertTrue(rulesThatHadErrors
+				.remove("Missing not int range 7b, warning"));
+		assertTrue(rulesThatHadErrors
+				.remove("Missing not int range 8a, warning"));
+		assertTrue(rulesThatHadErrors
+				.remove("Missing not int range 8b, warning"));
+		assertTrue(rulesThatHadErrors
+				.remove("Missing not int range 9a, warning"));
+		assertTrue(rulesThatHadErrors
+				.remove("Missing not int range 9b, warning"));
+		assertTrue(rulesThatHadErrors
+				.remove("Missing not int range 10a, warning"));
+		assertTrue(rulesThatHadErrors
+				.remove("Missing not int range 10b, warning"));
+
+		if (!rulesThatHadErrors.isEmpty()) {
+			for (String string : rulesThatHadErrors) {
+				fail("Rule " + string + " caused an error.");
+			}
+		}
+	}
+
+	public void testEqualAndGreaterThan() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("RangeCheckIntegers.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Range check for integers, equal and greater than"));
+
+		Collection<Object> data = getTestData(this.getClass()
+				.getResourceAsStream("MissingRangesForInts.drl"));
+
+		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
+		session.setGlobal("result", analysisResult);
+
+		StatelessSessionResult sessionResult = session.executeWithResults(data);
+
+		Iterator iter = sessionResult.iterateObjects();
+
+		Set<String> rulesThatHadErrors = new HashSet<String>();
+		while (iter.hasNext()) {
+			Object o = (Object) iter.next();
+			if (o instanceof Gap) {
+				rulesThatHadErrors.add(((Gap) o).getRuleName());
+			}
+			// System.out.println(o);
+		}
+
+		assertTrue(rulesThatHadErrors.remove("Missing int range 5b, warning"));
+		assertTrue(rulesThatHadErrors
+				.remove("Missing not int range 11b, warning"));
+
+		if (!rulesThatHadErrors.isEmpty()) {
+			for (String string : rulesThatHadErrors) {
+				fail("Rule " + string + " fired.");
+			}
+		}
+	}
+
+	public void testEqualAndSmallerThan() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("RangeCheckIntegers.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Range check for integers, equal and smaller than"));
+
+		Collection<Object> data = getTestData(this.getClass()
+				.getResourceAsStream("MissingRangesForInts.drl"));
+
+		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
+		session.setGlobal("result", analysisResult);
+
+		StatelessSessionResult sessionResult = session.executeWithResults(data);
+
+		Iterator iter = sessionResult.iterateObjects();
+
+		Set<String> rulesThatHadErrors = new HashSet<String>();
+		while (iter.hasNext()) {
+			Object o = (Object) iter.next();
+			if (o instanceof Gap) {
+				rulesThatHadErrors.add(((Gap) o).getRuleName());
+			}
+			// System.out.println(o);
+		}
+		assertTrue(rulesThatHadErrors.remove("Missing int range 6b, warning"));
+		assertTrue(rulesThatHadErrors
+				.remove("Missing not int range 12b, warning"));
+
+		if (!rulesThatHadErrors.isEmpty()) {
+			for (String string : rulesThatHadErrors) {
+				fail("Rule " + string + " fired.");
+			}
+		}
+	}
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/RedundancyTest.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,470 @@
+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.AnalyticsRule;
+import org.drools.analytics.components.LiteralRestriction;
+import org.drools.analytics.components.Pattern;
+import org.drools.analytics.components.PatternPossibility;
+import org.drools.analytics.components.RulePossibility;
+import org.drools.analytics.result.AnalysisResultNormal;
+import org.drools.analytics.result.PartialRedundancy;
+import org.drools.analytics.result.Redundancy;
+import org.drools.analytics.result.Subsumption;
+import org.drools.base.RuleNameMatchesAgendaFilter;
+
+/**
+ * 
+ * @author Toni Rikkola
+ * 
+ */
+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"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Find part of redundant RulePossibility combination"));
+
+		Collection<Object> data = new ArrayList<Object>();
+
+		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
+		session.setGlobal("result", analysisResult);
+
+		String ruleName1 = "Rule 1";
+		String ruleName2 = "Rule 2";
+
+		AnalyticsRule r1 = new AnalyticsRule();
+		r1.setRuleName(ruleName1);
+		AnalyticsRule r2 = new AnalyticsRule();
+		r2.setRuleName(ruleName2);
+
+		PatternPossibility pp1 = new PatternPossibility();
+		pp1.setRuleName(ruleName1);
+		PatternPossibility pp2 = new PatternPossibility();
+		pp2.setRuleName(ruleName2);
+
+		RulePossibility rp1 = new RulePossibility();
+		rp1.setRuleId(r1.getId());
+		rp1.setRuleName(ruleName1);
+		rp1.add(pp1);
+
+		RulePossibility rp2 = new RulePossibility();
+		rp2.setRuleId(r2.getId());
+		rp2.setRuleName(ruleName2);
+		rp2.add(pp2);
+
+		Redundancy redundancy1 = new Redundancy(pp1, pp2);
+		Redundancy redundancy2 = new Redundancy(r1, r2);
+
+		data.add(r1);
+		data.add(r2);
+		data.add(rp1);
+		data.add(rp2);
+		data.add(pp1);
+		data.add(pp2);
+		data.add(redundancy1);
+		data.add(redundancy2);
+
+		StatelessSessionResult sessionResult = session.executeWithResults(data);
+
+		Map<String, Set<Redundancy>> map = new HashMap<String, Set<Redundancy>>();
+
+		Iterator iter = sessionResult.iterateObjects();
+		while (iter.hasNext()) {
+			Object o = (Object) iter.next();
+			if (o instanceof PartialRedundancy) {
+				PartialRedundancy pr = (PartialRedundancy) o;
+				String key = pr.getLeft().getRuleName() + ":"
+						+ pr.getRight().getRuleName();
+				if (map.containsKey(key)) {
+					Set<Redundancy> set = map.get(key);
+					set.add(pr.getRedundancy());
+				} else {
+					Set<Redundancy> set = new HashSet<Redundancy>();
+					set.add(pr.getRedundancy());
+					map.put(key, set);
+				}
+			}
+		}
+
+		assertTrue(mapContains(map, ruleName1 + ":" + ruleName2, redundancy1));
+
+		if (!map.isEmpty()) {
+			fail("More redundancies than was expected.");
+		}
+	}
+
+	public void testPartOfPatternPossibilityRedundancy() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("Redundancy.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Find part of redundant PatternPossibility combination"));
+
+		Collection<Object> data = new ArrayList<Object>();
+
+		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
+		session.setGlobal("result", analysisResult);
+
+		String ruleName1 = "Rule 1";
+		String ruleName2 = "Rule 2";
+
+		Pattern p1 = new Pattern();
+		p1.setRuleName(ruleName1);
+		Pattern p2 = new Pattern();
+		p2.setRuleName(ruleName2);
+
+		LiteralRestriction lr1 = new LiteralRestriction();
+		lr1.setRuleName(ruleName1);
+		LiteralRestriction lr2 = new LiteralRestriction();
+		lr2.setRuleName(ruleName2);
+
+		PatternPossibility pp1 = new PatternPossibility();
+		pp1.setPatternId(p1.getId());
+		pp1.setRuleName(ruleName1);
+		pp1.add(lr1);
+
+		PatternPossibility pp2 = new PatternPossibility();
+		pp2.setPatternId(p2.getId());
+		pp2.setRuleName(ruleName2);
+		pp2.add(lr2);
+
+		Redundancy r1 = new Redundancy(lr1, lr2);
+		Redundancy r2 = new Redundancy(p1, p2);
+
+		data.add(p1);
+		data.add(p2);
+		data.add(lr1);
+		data.add(lr2);
+		data.add(pp1);
+		data.add(pp2);
+		data.add(r1);
+		data.add(r2);
+
+		StatelessSessionResult sessionResult = session.executeWithResults(data);
+
+		Map<String, Set<Redundancy>> map = new HashMap<String, Set<Redundancy>>();
+
+		Iterator iter = sessionResult.iterateObjects();
+		while (iter.hasNext()) {
+			Object o = (Object) iter.next();
+			if (o instanceof PartialRedundancy) {
+				PartialRedundancy pr = (PartialRedundancy) o;
+				String key = pr.getLeft().getRuleName() + ":"
+						+ pr.getRight().getRuleName();
+				if (map.containsKey(key)) {
+					Set<Redundancy> set = map.get(key);
+					set.add(pr.getRedundancy());
+				} else {
+					Set<Redundancy> set = new HashSet<Redundancy>();
+					set.add(pr.getRedundancy());
+					map.put(key, set);
+				}
+			}
+		}
+
+		assertTrue(mapContains(map, ruleName1 + ":" + ruleName2, r1));
+
+		if (!map.isEmpty()) {
+			fail("More redundancies than was expected.");
+		}
+	}
+
+	/*
+	 * Not enough data to test this right now.
+	 */
+	/*
+	 * public void testRuleRedundancy() throws Exception { StatelessSession
+	 * session = getStatelessSession(this.getClass()
+	 * .getResourceAsStream("Redundancy.drl"));
+	 * 
+	 * session.setAgendaFilter(new RuleNameMatchesAgendaFilter( "Find redundant
+	 * Rule shells"));
+	 * 
+	 * Collection<Object> data = getTestData(this.getClass()
+	 * .getResourceAsStream("RuleRedundancyTest.drl"));
+	 * 
+	 * AnalysisResultNormal analysisResult = new AnalysisResultNormal();
+	 * session.setGlobal("result", analysisResult);
+	 * 
+	 * StatelessSessionResult sessionResult = session.executeWithResults(data);
+	 * 
+	 * Map<String, Set<String>> map = createRedundancyMap(sessionResult
+	 * .iterateObjects());
+	 * 
+	 * assertTrue(mapContains(map, "Rule redundancy 1a", "Rule redundancy 1b"));
+	 * assertTrue(mapContains(map, "Rule redundancy 1b", "Rule redundancy 1a"));
+	 * assertTrue(mapContains(map, "Rule redundancy 2a", "Rule redundancy 2b"));
+	 * assertTrue(mapContains(map, "Rule redundancy 2b", "Rule redundancy 2a"));
+	 * assertTrue(mapContains(map, "Rule redundancy 3a", "Rule redundancy 3b"));
+	 * assertTrue(mapContains(map, "Rule redundancy 3b", "Rule redundancy 3a"));
+	 * assertTrue(mapContains(map, "Rule redundancy 4a", "Rule redundancy 4b"));
+	 * assertTrue(mapContains(map, "Rule redundancy 4b", "Rule redundancy 4a"));
+	 * 
+	 * if (!map.isEmpty()) { fail("More redundancies than was expected."); } }
+	 */
+
+	public void testPatternRedundancy() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("Redundancy.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Find redundant Pattern shells"));
+
+		Collection<Object> data = getTestData(this.getClass()
+				.getResourceAsStream("PatternRedundancyTest.drl"));
+
+		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
+		session.setGlobal("result", analysisResult);
+
+		StatelessSessionResult sessionResult = session.executeWithResults(data);
+
+		Map<String, Set<String>> map = createRedundancyMap(sessionResult
+				.iterateObjects());
+
+		assertTrue(mapContains(map, "Pattern redundancy 1a",
+				"Pattern redundancy 1b"));
+		assertTrue(mapContains(map, "Pattern redundancy 1b",
+				"Pattern redundancy 1a"));
+		assertTrue(mapContains(map, "Pattern redundancy 2a",
+				"Pattern redundancy 2b"));
+		assertTrue(mapContains(map, "Pattern redundancy 2b",
+				"Pattern redundancy 2a"));
+		assertTrue(mapContains(map, "Pattern redundancy 3a",
+				"Pattern redundancy 3b"));
+		assertTrue(mapContains(map, "Pattern redundancy 3b",
+				"Pattern redundancy 3a"));
+		assertTrue(mapContains(map, "Pattern redundancy 4a",
+				"Pattern redundancy 4b"));
+		assertTrue(mapContains(map, "Pattern redundancy 4b",
+				"Pattern redundancy 4a"));
+
+		if (!map.isEmpty()) {
+			fail("More redundancies than was expected.");
+		}
+	}
+
+	public void testAnalyticsLiteralRestrictionRedundancy() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("Redundancy.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Find redundant LiteralRestriction"));
+
+		Collection<Object> data = getTestData(this.getClass()
+				.getResourceAsStream("RedundancyLiteralRestrictionTest.drl"));
+
+		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
+		session.setGlobal("result", analysisResult);
+
+		StatelessSessionResult sessionResult = session.executeWithResults(data);
+
+		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"));
+
+		if (!map.isEmpty()) {
+			fail("More redundancies than was expected.");
+		}
+	}
+
+	public void testAnalyticsVariableRestrictionRedundancy() throws Exception {
+		StatelessSession session = getStatelessSession(this.getClass()
+				.getResourceAsStream("Redundancy.drl"));
+
+		session.setAgendaFilter(new RuleNameMatchesAgendaFilter(
+				"Find redundant VariableRestriction"));
+
+		Collection<Object> data = getTestData(this.getClass()
+				.getResourceAsStream("SubsumptionVariableRestrictionTest.drl"));
+
+		AnalysisResultNormal analysisResult = new AnalysisResultNormal();
+		session.setGlobal("result", analysisResult);
+
+		StatelessSessionResult sessionResult = session.executeWithResults(data);
+
+		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"));
+
+		if (!map.isEmpty()) {
+			fail("More redundancies than was expected.");
+		}
+	}
+
+	/**
+	 * Creates redundancy map from Redundancy objects, one rule may have several
+	 * redundancy dependencies.
+	 * 
+	 * @param iter
+	 * @return
+	 */
+	private Map<String, Set<String>> createRedundancyMap(Iterator iter) {
+
+		Map<String, Set<String>> map = new HashMap<String, Set<String>>();
+		while (iter.hasNext()) {
+			Object o = (Object) iter.next();
+			if (o instanceof Redundancy) {
+				Redundancy r = (Redundancy) o;
+				if (map.containsKey(r.getLeft().getRuleName())) {
+					Set<String> set = map.get(r.getLeft().getRuleName());
+					set.add(r.getRight().getRuleName());
+				} else {
+					Set<String> set = new HashSet<String>();
+					set.add(r.getRight().getRuleName());
+					map.put(r.getLeft().getRuleName(), set);
+				}
+			}
+		}
+
+		return map;
+	}
+
+	/**
+	 * 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
+	 * @param key
+	 * @param value
+	 * @return True if redundancy exists.
+	 */
+	private 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);
+
+			// If set is empty remove key from map.
+			if (set.isEmpty()) {
+				map.remove(key);
+			}
+			return exists;
+		}
+		return false;
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/SolversTest.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/SolversTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/SolversTest.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,142 @@
+package org.drools.analytics;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.drools.analytics.components.AnalyticsRule;
+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.Restriction;
+import org.drools.analytics.components.RulePossibility;
+import org.drools.analytics.result.Cause;
+
+import junit.framework.TestCase;
+
+/**
+ * 
+ * @author Toni Rikkola
+ * 
+ */
+public class SolversTest extends TestCase {
+
+	/**
+	 * <pre>
+	 * when 
+	 * 		Foo( r &amp;&amp; r2 )
+	 * 		and
+	 * 		not Foo( r3 &amp;&amp; r4 )
+	 * </pre>
+	 * 
+	 * result:<br>
+	 * r && r2<br>
+	 * r3 && r4
+	 */
+	public void testNotAnd() {
+		AnalyticsRule rule = new AnalyticsRule();
+		Pattern pattern = new Pattern();
+
+		Restriction r = new LiteralRestriction();
+		Restriction r2 = new LiteralRestriction();
+		Restriction r3 = new LiteralRestriction();
+		Restriction r4 = new LiteralRestriction();
+
+		OperatorDescr andDescr = OperatorDescr.valueOf(OperatorDescr.Type.AND);
+		Solvers solvers = new Solvers();
+
+		solvers.startRuleSolver(rule);
+
+		solvers.startOperator(andDescr);
+		solvers.startPatternSolver(pattern);
+		solvers.startOperator(andDescr);
+		solvers.addRestriction(r);
+		solvers.addRestriction(r2);
+		solvers.endOperator();
+		solvers.endPatternSolver();
+
+		solvers.startNot();
+		solvers.startPatternSolver(pattern);
+		solvers.startOperator(andDescr);
+		solvers.addRestriction(r3);
+		solvers.addRestriction(r4);
+		solvers.endOperator();
+		solvers.endPatternSolver();
+		solvers.endNot();
+
+		solvers.endOperator();
+
+		solvers.endRuleSolver();
+
+		List<RulePossibility> list = solvers.getRulePossibilities();
+		assertEquals(1, list.size());
+		assertEquals(2, list.get(0).getItems().size());
+
+		List<Restriction> result = new ArrayList<Restriction>();
+		result.add(r);
+		result.add(r2);
+
+		List<Restriction> result2 = new ArrayList<Restriction>();
+		result2.add(r3);
+		result2.add(r4);
+
+		Object[] possibilies = list.get(0).getItems().toArray();
+		PatternPossibility p1 = (PatternPossibility) possibilies[0];
+		PatternPossibility p2 = (PatternPossibility) possibilies[1];
+
+		/*
+		 * Order may change but it doesn't matter.
+		 */
+		if (p1.getItems().containsAll(result)) {
+			assertTrue(p2.getItems().containsAll(result2));
+		} else if (p1.getItems().containsAll(result2)) {
+			assertTrue(p2.getItems().containsAll(result));
+		} else {
+			fail("No items found.");
+		}
+	}
+
+	/**
+	 * <pre>
+	 * when 
+	 * 		Foo( descr &amp;&amp; descr2 )
+	 * </pre>
+	 * 
+	 * result:<br>
+	 * descr && descr2
+	 */
+	public void testBasicAnd() {
+		AnalyticsRule rule = new AnalyticsRule();
+		Pattern pattern = new Pattern();
+
+		Restriction r = new LiteralRestriction();
+		Restriction r2 = new LiteralRestriction();
+
+		OperatorDescr andDescr = OperatorDescr.valueOf(OperatorDescr.Type.AND);
+		Solvers solvers = new Solvers();
+
+		solvers.startRuleSolver(rule);
+		solvers.startPatternSolver(pattern);
+		solvers.startOperator(andDescr);
+		solvers.addRestriction(r);
+		solvers.addRestriction(r2);
+		solvers.endOperator();
+		solvers.endPatternSolver();
+		solvers.endRuleSolver();
+
+		List<RulePossibility> list = solvers.getRulePossibilities();
+		assertEquals(1, list.size());
+		assertEquals(1, list.get(0).getItems().size());
+
+		List<Restriction> result = new ArrayList<Restriction>();
+		result.add(r);
+		result.add(r2);
+
+		Set<Cause> set = list.get(0).getItems();
+		for (Cause cause : set) {
+			PatternPossibility possibility = (PatternPossibility) cause;
+			assertTrue(possibility.getItems().containsAll(result));
+		}
+	}
+}

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/TestBase.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,62 @@
+package org.drools.analytics;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.Collection;
+
+import junit.framework.TestCase;
+
+import org.drools.RuleBase;
+import org.drools.RuleBaseFactory;
+import org.drools.StatelessSession;
+import org.drools.compiler.DrlParser;
+import org.drools.compiler.PackageBuilder;
+import org.drools.lang.descr.PackageDescr;
+import org.drools.rule.Package;
+
+/**
+ * 
+ * @author Toni Rikkola
+ *
+ */
+abstract class TestBase extends TestCase {
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+
+		System.setProperty("drools.accumulate.function.validatePattern",
+				"com.analytics.accumulateFunction.ValidatePattern");
+
+	}
+
+	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
+		Reader source = new InputStreamReader(stream);
+
+		PackageBuilder builder = new PackageBuilder();
+
+		builder.addPackageFromDrl(source);
+
+		Package pkg = builder.getPackage();
+
+		RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+		ruleBase.addPackage(pkg);
+
+		return ruleBase.newStatelessSession();
+	}
+}

Added: labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/accumulateFunction/ValidatePatternTest.java
===================================================================
--- labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/accumulateFunction/ValidatePatternTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/experimental/drools-analytics/src/test/java/org/drools/analytics/accumulateFunction/ValidatePatternTest.java	2007-08-27 16:08:25 UTC (rev 14650)
@@ -0,0 +1,133 @@
+package org.drools.analytics.accumulateFunction;
+
+import java.math.BigDecimal;
+
+import org.drools.analytics.accumulateFunction.ValidatePattern;
+
+
+
+import junit.framework.TestCase;
+
+public class ValidatePatternTest extends TestCase {
+
+	public void testfindSumPattern() {
+		// Sum +2 missing number 4
+		assertTrue(ValidatePattern.findSumPattern(
+				new BigDecimal[] { BigDecimal.valueOf(2),
+						BigDecimal.valueOf(6), BigDecimal.valueOf(8),
+						BigDecimal.valueOf(10) }).doubleValue() == 4);
+		// +10 missing number 50
+		assertTrue(ValidatePattern.findSumPattern(
+				new BigDecimal[] { BigDecimal.valueOf(10),
+						BigDecimal.valueOf(20), BigDecimal.valueOf(30),
+						BigDecimal.valueOf(40), BigDecimal.valueOf(60),
+						BigDecimal.valueOf(70) }).doubleValue() == 50);
+		// +66 missing number 308
+		assertTrue(ValidatePattern.findSumPattern(
+				new BigDecimal[] { BigDecimal.valueOf(110),
+						BigDecimal.valueOf(176), BigDecimal.valueOf(242),
+						BigDecimal.valueOf(374) }).doubleValue() == 308);
+
+		// Deduction -2 missing number 8
+		assertTrue(ValidatePattern.findSumPattern(
+				new BigDecimal[] { BigDecimal.valueOf(10),
+						BigDecimal.valueOf(6), BigDecimal.valueOf(4),
+						BigDecimal.valueOf(2) }).doubleValue() == 8);
+		// -337 missing number -11
+		assertTrue(ValidatePattern.findSumPattern(
+				new BigDecimal[] { BigDecimal.valueOf(663),
+						BigDecimal.valueOf(326), BigDecimal.valueOf(-348),
+						BigDecimal.valueOf(-685) }).doubleValue() == -11);
+		// -31 missing number 4350
+		assertTrue(ValidatePattern.findSumPattern(
+				new BigDecimal[] { BigDecimal.valueOf(4443),
+						BigDecimal.valueOf(4412), BigDecimal.valueOf(4381),
+						BigDecimal.valueOf(4319) }).doubleValue() == 4350);
+
+		// Not valid
+		// Not in pattern.
+		assertTrue(ValidatePattern.findSumPattern(new BigDecimal[] {
+				BigDecimal.valueOf(1), BigDecimal.valueOf(2),
+				BigDecimal.valueOf(4), BigDecimal.valueOf(6),
+				BigDecimal.valueOf(8), BigDecimal.valueOf(11) }) == null);
+		assertTrue(ValidatePattern.findSumPattern(new BigDecimal[] {
+				BigDecimal.valueOf(5), BigDecimal.valueOf(3),
+				BigDecimal.valueOf(54353), BigDecimal.valueOf(54554),
+				BigDecimal.valueOf(232), BigDecimal.valueOf(123) }) == null);
+		// No missing values.
+		assertTrue(ValidatePattern.findSumPattern(new BigDecimal[] {
+				BigDecimal.valueOf(2), BigDecimal.valueOf(4),
+				BigDecimal.valueOf(6), BigDecimal.valueOf(8),
+				BigDecimal.valueOf(10), BigDecimal.valueOf(12),
+				BigDecimal.valueOf(14) }) == null);
+		assertTrue(ValidatePattern.findSumPattern(new BigDecimal[] {
+				BigDecimal.valueOf(10), BigDecimal.valueOf(20),
+				BigDecimal.valueOf(30), BigDecimal.valueOf(40),
+				BigDecimal.valueOf(50), BigDecimal.valueOf(60) }) == null);
+		assertTrue(ValidatePattern.findSumPattern(new BigDecimal[] {
+				BigDecimal.valueOf(-15), BigDecimal.valueOf(-10),
+				BigDecimal.valueOf(-5), BigDecimal.valueOf(0),
+				BigDecimal.valueOf(5), BigDecimal.valueOf(10),
+				BigDecimal.valueOf(15) }) == null);
+		// Under 4 values always returns null.
+		assertTrue(ValidatePattern.findSumPattern(new BigDecimal[] {
+				BigDecimal.valueOf(2), BigDecimal.valueOf(4),
+				BigDecimal.valueOf(6) }) == null);
+		assertTrue(ValidatePattern.findSumPattern(new BigDecimal[] {
+				BigDecimal.valueOf(2), BigDecimal.valueOf(4) }) == null);
+		assertTrue(ValidatePattern.findSumPattern(new BigDecimal[] { BigDecimal
+				.valueOf(2) }) == null);
+	}
+
+	public void testFindMultiplicationPattern() {
+
+		// Multiplication
+		// *2 missing number 4
+		assertTrue(ValidatePattern.findMultiplicationPattern(
+				new BigDecimal[] { BigDecimal.valueOf(2),
+						BigDecimal.valueOf(8), BigDecimal.valueOf(16),
+						BigDecimal.valueOf(32), BigDecimal.valueOf(64) })
+				.doubleValue() == 4);
+		// *17 missing number 383214
+		assertTrue(ValidatePattern.findMultiplicationPattern(
+				new BigDecimal[] { BigDecimal.valueOf(78),
+						BigDecimal.valueOf(1326), BigDecimal.valueOf(22542),
+						BigDecimal.valueOf(6514638) }).doubleValue() == 383214);
+		// *1,23 missing number 2016.6957
+		assertTrue(ValidatePattern.findMultiplicationPattern(
+				new BigDecimal[] { BigDecimal.valueOf(1333),
+						BigDecimal.valueOf(1639.59),
+						BigDecimal.valueOf(2480.535711),
+						BigDecimal.valueOf(3051.05892453) }).doubleValue() == 2016.6957);
+
+		// Division
+		// /2 (*0.5) missing number 128
+		assertTrue(ValidatePattern.findMultiplicationPattern(
+				new BigDecimal[] { BigDecimal.valueOf(256),
+						BigDecimal.valueOf(64), BigDecimal.valueOf(32),
+						BigDecimal.valueOf(16), BigDecimal.valueOf(8),
+						BigDecimal.valueOf(4), BigDecimal.valueOf(2) })
+				.doubleValue() == 128);
+		// /10 (*0.1) missing number 1
+		assertTrue(ValidatePattern.findMultiplicationPattern(
+				new BigDecimal[] { BigDecimal.valueOf(10000),
+						BigDecimal.valueOf(1000), BigDecimal.valueOf(100),
+						BigDecimal.valueOf(10), BigDecimal.valueOf(0.1),
+						BigDecimal.valueOf(0.01) }).doubleValue() == 1);
+
+		// Not valid
+		// Not in pattern.
+		assertTrue(ValidatePattern.findMultiplicationPattern(new BigDecimal[] {
+				BigDecimal.valueOf(111.2), BigDecimal.valueOf(3323),
+				BigDecimal.valueOf(234.434), BigDecimal.valueOf(44343),
+				BigDecimal.valueOf(434) }) == null);
+		assertTrue(ValidatePattern.findMultiplicationPattern(new BigDecimal[] {
+				BigDecimal.valueOf(1), BigDecimal.valueOf(2),
+				BigDecimal.valueOf(3), BigDecimal.valueOf(4),
+				BigDecimal.valueOf(5), BigDecimal.valueOf(6),
+				BigDecimal.valueOf(7), BigDecimal.valueOf(5),
+				BigDecimal.valueOf(4), BigDecimal.valueOf(3),
+				BigDecimal.valueOf(2), BigDecimal.valueOf(1),
+				BigDecimal.valueOf(1), BigDecimal.valueOf(1) }) == null);
+	}
+}




More information about the jboss-svn-commits mailing list