[jboss-svn-commits] JBL Code SVN: r8218 - in labs/jbossrules/trunk: drools-compiler/src/main/java/org/drools/semantics/java drools-compiler/src/test/java/org/drools/compiler drools-core/src/main/java/org/drools/reteoo drools-core/src/main/java/org/drools/rule drools-core/src/test/java/org/drools/examples/manners drools-core/src/test/java/org/drools/rule drools-core/src/test/resources
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Dec 11 06:58:13 EST 2006
Author: tirelli
Date: 2006-12-11 06:57:51 -0500 (Mon, 11 Dec 2006)
New Revision: 8218
Added:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElementFactory.java
Removed:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/And.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Exists.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Not.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Or.java
Modified:
labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/RuleBuilder.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooBuilder.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Column.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElement.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/LogicTransformer.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/BaseMannersTest.java
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/GroupElementTest.java
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/LogicTransformerTest.java
labs/jbossrules/trunk/drools-core/src/test/resources/correct_processTree1.dat
labs/jbossrules/trunk/drools-core/src/test/resources/correct_transform1.dat
Log:
JBRULES-218: refactoring logical transformation to allow future development of forall
Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/RuleBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/RuleBuilder.java 2006-12-11 05:19:32 UTC (rev 8217)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/RuleBuilder.java 2006-12-11 11:57:51 UTC (rev 8218)
@@ -28,16 +28,13 @@
import java.util.Map;
import java.util.Set;
-import org.antlr.runtime.ANTLRReaderStream;
import org.antlr.runtime.ANTLRStringStream;
-import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.TokenStream;
import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.language.AngleBracketTemplateLexer;
import org.codehaus.jfdi.interpreter.TypeResolver;
-import org.codehaus.jfdi.interpreter.operations.Expr;
import org.codehaus.jfdi.parser.JFDILexer;
import org.codehaus.jfdi.parser.JFDIParser;
import org.drools.RuntimeDroolsException;
@@ -49,12 +46,6 @@
import org.drools.base.ValueType;
import org.drools.base.dataproviders.JFDIDataProvider;
import org.drools.base.evaluators.Operator;
-import org.drools.base.resolvers.DeclarationVariable;
-import org.drools.base.resolvers.GlobalVariable;
-import org.drools.base.resolvers.ListValue;
-import org.drools.base.resolvers.LiteralValue;
-import org.drools.base.resolvers.MapValue;
-import org.drools.base.resolvers.ValueHandler;
import org.drools.compiler.RuleError;
import org.drools.facttemplates.FactTemplate;
import org.drools.facttemplates.FactTemplateFieldExtractor;
@@ -83,20 +74,17 @@
import org.drools.lang.descr.RuleDescr;
import org.drools.lang.descr.VariableRestrictionDescr;
import org.drools.rule.Accumulate;
-import org.drools.rule.And;
import org.drools.rule.AndCompositeRestriction;
import org.drools.rule.Collect;
import org.drools.rule.Column;
import org.drools.rule.Declaration;
import org.drools.rule.EvalCondition;
-import org.drools.rule.Exists;
import org.drools.rule.From;
import org.drools.rule.GroupElement;
+import org.drools.rule.GroupElementFactory;
import org.drools.rule.LiteralConstraint;
import org.drools.rule.LiteralRestriction;
import org.drools.rule.MultiRestrictionFieldConstraint;
-import org.drools.rule.Not;
-import org.drools.rule.Or;
import org.drools.rule.OrCompositeRestriction;
import org.drools.rule.Package;
import org.drools.rule.PredicateConstraint;
@@ -270,7 +258,7 @@
final Object object = it.next();
if ( object instanceof ConditionalElementDescr ) {
if ( object.getClass() == AndDescr.class ) {
- final And and = new And();
+ final GroupElement and = GroupElementFactory.newAndInstance();
build( this.rule,
(ConditionalElementDescr) object,
and,
@@ -278,7 +266,7 @@
false ); // do not decrement first offset
this.rule.addPattern( and );
} else if ( object.getClass() == OrDescr.class ) {
- final Or or = new Or();
+ final GroupElement or = GroupElementFactory.newOrInstance();
build( this.rule,
(ConditionalElementDescr) object,
or,
@@ -288,7 +276,7 @@
} else if ( object.getClass() == NotDescr.class ) {
// We cannot have declarations created inside a not visible outside it, so track no declarations so they can be removed
this.innerDeclarations = new HashMap();
- final Not not = new Not();
+ final GroupElement not = GroupElementFactory.newNotInstance();
build( this.rule,
(ConditionalElementDescr) object,
not,
@@ -306,7 +294,7 @@
// We cannot have declarations created inside exists visible outside it,
// so track declarations in a way they can be removed
this.innerDeclarations = new HashMap();
- final Exists exists = new Exists();
+ final GroupElement exists = GroupElementFactory.newExistsInstance();
build( this.rule,
(ConditionalElementDescr) object,
exists,
@@ -360,7 +348,7 @@
final Object object = it.next();
if ( object instanceof ConditionalElementDescr ) {
if ( object.getClass() == AndDescr.class ) {
- final And and = new And();
+ final GroupElement and = GroupElementFactory.newAndInstance();
build( rule,
(ConditionalElementDescr) object,
and,
@@ -368,7 +356,7 @@
false ); // do not decrement first offset
ce.addChild( and );
} else if ( object.getClass() == OrDescr.class ) {
- final Or or = new Or();
+ final GroupElement or = GroupElementFactory.newOrInstance();
build( rule,
(ConditionalElementDescr) object,
or,
@@ -376,7 +364,7 @@
false ); // do not decrement first offset
ce.addChild( or );
} else if ( object.getClass() == NotDescr.class ) {
- final Not not = new Not();
+ final GroupElement not = GroupElementFactory.newNotInstance();
build( rule,
(ConditionalElementDescr) object,
not,
@@ -384,7 +372,7 @@
true ); // when NOT is used, offset MUST be decremented for first column
ce.addChild( not );
} else if ( object.getClass() == ExistsDescr.class ) {
- final Exists exists = new Exists();
+ final GroupElement exists = GroupElementFactory.newExistsInstance();
build( rule,
(ConditionalElementDescr) object,
exists,
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java 2006-12-11 05:19:32 UTC (rev 8217)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java 2006-12-11 11:57:51 UTC (rev 8218)
@@ -62,14 +62,11 @@
import org.drools.lang.descr.ReturnValueRestrictionDescr;
import org.drools.lang.descr.RuleDescr;
import org.drools.reteoo.ReteooRuleBase;
-import org.drools.rule.And;
import org.drools.rule.Column;
import org.drools.rule.Declaration;
import org.drools.rule.EvalCondition;
-import org.drools.rule.Exists;
+import org.drools.rule.GroupElement;
import org.drools.rule.LiteralConstraint;
-import org.drools.rule.Not;
-import org.drools.rule.Or;
import org.drools.rule.Package;
import org.drools.rule.PredicateConstraint;
import org.drools.rule.ReturnValueConstraint;
@@ -569,11 +566,11 @@
assertLength( 0,
builder.getErrors() );
- final And lhs = rule.getLhs();
+ final GroupElement lhs = rule.getLhs();
assertLength( 1,
lhs.getChildren() );
- final Or or = (Or) lhs.getChildren().get( 0 );
+ final GroupElement or = (GroupElement) lhs.getChildren().get( 0 );
assertLength( 1,
or.getChildren() );
final Column column = (Column) or.getChildren().get( 0 );
@@ -589,11 +586,11 @@
assertLength( 0,
builder.getErrors() );
- final And lhs = rule.getLhs();
+ final GroupElement lhs = rule.getLhs();
assertLength( 1,
lhs.getChildren() );
- final And and = (And) lhs.getChildren().get( 0 );
+ final GroupElement and = (GroupElement) lhs.getChildren().get( 0 );
assertLength( 1,
and.getChildren() );
final Column column = (Column) and.getChildren().get( 0 );
@@ -618,11 +615,11 @@
assertEquals( 0,
builder.getErrors().length );
- final And lhs = rule.getLhs();
+ final GroupElement lhs = rule.getLhs();
assertLength( 1,
lhs.getChildren() );
- final Not not = (Not) lhs.getChildren().get( 0 );
+ final GroupElement not = (GroupElement) lhs.getChildren().get( 0 );
assertLength( 1,
not.getChildren() );
final Column column = (Column) not.getChildren().get( 0 );
@@ -647,11 +644,11 @@
assertEquals( 0,
builder.getErrors().length );
- final And lhs = rule.getLhs();
+ final GroupElement lhs = rule.getLhs();
assertLength( 1,
lhs.getChildren() );
- final Exists exists = (Exists) lhs.getChildren().get( 0 );
+ final GroupElement exists = (GroupElement) lhs.getChildren().get( 0 );
assertLength( 1,
exists.getChildren() );
final Column column = (Column) exists.getChildren().get( 0 );
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooBuilder.java 2006-12-11 05:19:32 UTC (rev 8217)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooBuilder.java 2006-12-11 11:57:51 UTC (rev 8218)
@@ -43,17 +43,14 @@
import org.drools.common.SingleBetaConstraints;
import org.drools.common.TripleBetaConstraints;
import org.drools.rule.Accumulate;
-import org.drools.rule.And;
import org.drools.rule.Collect;
import org.drools.rule.Column;
import org.drools.rule.Declaration;
import org.drools.rule.EvalCondition;
-import org.drools.rule.Exists;
import org.drools.rule.From;
import org.drools.rule.GroupElement;
import org.drools.rule.InvalidPatternException;
import org.drools.rule.LiteralConstraint;
-import org.drools.rule.Not;
import org.drools.rule.Query;
import org.drools.rule.Rule;
import org.drools.spi.AlphaNodeFieldConstraint;
@@ -165,7 +162,7 @@
this.currentOffsetAdjustment = 0;
final List nodes = new ArrayList();
- final And[] and = rule.getTransformedLhs();
+ final GroupElement[] and = rule.getTransformedLhs();
for ( int i = 0; i < and.length; i++ ) {
if ( !hasColumns( and[i] ) ) {
@@ -216,12 +213,12 @@
return false;
}
- private void addInitialFactMatch(final And and) {
- And temp = null;
+ private void addInitialFactMatch(final GroupElement and) {
+ GroupElement temp = null;
// If we have children we know there are no columns but we need to make sure that InitialFact is first
if ( !and.getChildren().isEmpty() ) {
- temp = (And) and.clone();
+ temp = (GroupElement) and.clone();
and.getChildren().clear();
}
final Column column = new Column( 0,
@@ -235,7 +232,7 @@
this.currentOffsetAdjustment = 1;
}
- private void addRule(final And and,
+ private void addRule(final GroupElement and,
final Rule rule) throws InvalidPatternException {
this.objectSource = null;
this.tupleSource = null;
@@ -317,16 +314,16 @@
this.removeIdentities );
}
- if ( object.getClass() == Not.class ) {
+ if (( object instanceof GroupElement ) && (((GroupElement)object).isNot())) {
attachNot( this.tupleSource,
- (Not) object,
+ (GroupElement) object,
this.objectSource,
binder,
column );
binder = null;
- } else if ( object.getClass() == Exists.class ) {
+ } else if (( object instanceof GroupElement ) && (((GroupElement)object).isExists())) {
attachExists( this.tupleSource,
- (Exists) object,
+ (GroupElement) object,
this.objectSource,
binder,
column );
@@ -470,7 +467,7 @@
}
private void attachNot(final TupleSource tupleSource,
- final Not not,
+ final GroupElement not,
final ObjectSource ObjectSource,
final BetaConstraints binder,
final Column column) {
@@ -482,7 +479,7 @@
}
private void attachExists(final TupleSource tupleSource,
- final Exists exists,
+ final GroupElement exists,
final ObjectSource ObjectSource,
final BetaConstraints binder,
final Column column) {
@@ -597,7 +594,7 @@
}
private void attachAccumulate(final TupleSource tupleSource,
- final And parent,
+ final GroupElement parent,
final Accumulate accumulate) {
// If a tupleSource does not exist then we need to adapt an
// InitialFact into a a TupleSource using LeftInputAdapterNode
@@ -668,7 +665,7 @@
}
private void attachCollect(final TupleSource tupleSource,
- final And parent,
+ final GroupElement parent,
final Collect collect) {
// If a tupleSource does not exist then we need to adapt an
// InitialFact into a a TupleSource using LeftInputAdapterNode
Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/And.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/And.java 2006-12-11 05:19:32 UTC (rev 8217)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/And.java 2006-12-11 11:57:51 UTC (rev 8218)
@@ -1,26 +0,0 @@
-package org.drools.rule;
-
-/*
- * Copyright 2005 JBoss Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-public class And extends GroupElement {
-
- /**
- *
- */
- private static final long serialVersionUID = -218170444675103882L;
-
-}
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Column.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Column.java 2006-12-11 05:19:32 UTC (rev 8217)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Column.java 2006-12-11 11:57:51 UTC (rev 8218)
@@ -146,7 +146,7 @@
}
public String toString() {
- return "Column type='" + this.objectType + "', index='" + this.index + "', offset='" + this.getOffset() + "', identifer='" + this.declaration.getIdentifier() + "'";
+ return "Column type='" + ((this.objectType == null) ? "null" : this.objectType.toString()) + "', index='" + this.index + "', offset='" + this.getOffset() + "', identifer='" + ((this.declaration == null) ? "" : this.declaration.toString()) + "'";
}
public int hashCode() {
@@ -155,7 +155,7 @@
result = PRIME * result + this.constraints.hashCode();
result = PRIME * result + ((this.declaration == null) ? 0 : this.declaration.hashCode());
result = PRIME * result + this.index;
- result = PRIME * result + this.objectType.hashCode();
+ result = PRIME * result + ((this.objectType == null) ? 0 : this.objectType.hashCode());
result = PRIME * result + this.offset;
return result;
}
Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Exists.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Exists.java 2006-12-11 05:19:32 UTC (rev 8217)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Exists.java 2006-12-11 11:57:51 UTC (rev 8218)
@@ -1,28 +0,0 @@
-package org.drools.rule;
-
-/*
- * Copyright 2005 JBoss Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-public class Exists extends GroupElement {
- /**
- *
- */
- private static final long serialVersionUID = 320;
-
- public Object getChild() {
- return getChildren().get( 0 );
- }
-}
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElement.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElement.java 2006-12-11 05:19:32 UTC (rev 8217)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElement.java 2006-12-11 11:57:51 UTC (rev 8218)
@@ -16,77 +16,46 @@
* limitations under the License.
*/
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-public abstract class GroupElement extends ConditionalElement {
- private final List children = new ArrayList();
+import org.drools.RuntimeDroolsException;
+public class GroupElement extends ConditionalElement {
+
+ private static final long serialVersionUID = 125354210439500614L;
+
+ public static final Type AND = new AndType();
+ public static final Type OR = new OrType();
+ public static final Type EXISTS = new ExistsType();
+ public static final Type NOT = new NotType();
+
+ private Type type = null;
+ private final List children = new ArrayList();
+
+ public GroupElement() {
+ this( AND );
+ }
+
+ public GroupElement(Type type) {
+ this.type = type;
+ }
+
/**
- * This removes single branch 'and' and 'or'
- * It also does basic nested removal, where an 'and' is
- * nested inside an 'and' and when an 'or' is nested inside an 'or'
+ * Adds a child to the current GroupElement.
*
- * LogicTransformer does further, more complicated, transformations
+ * Restrictions are:
+ * NOT/EXISTS: can have only one child, either a single Pattern or another CE
+ *
* @param child
*/
public void addChild(final Object child) {
- // @todo : I've commented this out for 3.0, but we want this working for 3.1
- // if ( child instanceof Not ) {
- // Not not = ( Not ) child;
- // Object notChild = not.getChild();
- // if ( notChild instanceof Or ) {
- // Or or = (Or) notChild;
- // And and = new And();
- // for ( Iterator it = or.getChildren().iterator(); it.hasNext(); ) {
- // Not newNot = new Not();
- // newNot.addChild( it.next() );
- // and.addChild( newNot );
- // }
- // child = and;
- // } else if ( notChild instanceof And ) {
- //
- // }
- // }
-
- //@todo make this work for 3.1
- // if ( child instanceof GroupElement && ( child instanceof And || child instanceof Or ) ) {
- // GroupElement group = ( GroupElement ) child;
- //
- // // Removal single branch group elements
- // // If the child is a GroupElement iterate down until we either
- // // find a GroupElement that has more than one children, or its not a GroupElement
- // if ( group.getChildren().size() == 1 ) {
- // child = group.getChildren().get( 0 );
- // }
- // }
- //
- // if ( child instanceof GroupElement && ( child instanceof And || child instanceof Or ) ) {
- // GroupElement group = ( GroupElement ) child;
- //
- // // Remove nested Ands/Ors
- // if ( group.getClass() == this.getClass() ) {
- //
- // GroupElement newGroup = null;
- // if ( group instanceof And) {
- // newGroup = new And();
- // } else {
- // newGroup = new Or();
- // }
- //
- // for ( Iterator it = group.getChildren().iterator(); it.hasNext(); ) {
- // this.children.add( it.next() );
- // }
- // } else {
- // this.children.add( child );
- // }
- // } else {
- // this.children.add( child );
- // }
-
+ if ( (this.isNot() || this.isExists()) && (this.children.size() > 0) ) {
+ throw new RuntimeDroolsException( this.type.toString() + " can have only a single child element. Either a single Pattern or another CE." );
+ }
this.children.add( child );
-
}
public List getChildren() {
@@ -94,6 +63,84 @@
}
/**
+ * Optimize the group element subtree by removing redundancies
+ * like an AND inside another AND, OR inside OR, single branches
+ * AND/OR, etc.
+ *
+ * LogicTransformer does further, more complicated, transformations
+ */
+ public void pack() {
+ Object[] clone = this.children.toArray();
+ for ( int i = 0; i < clone.length; i++ ) {
+ // if child is also a group element, there may be
+ // some possible clean up / optimizations to be done
+ if ( clone[i] instanceof GroupElement ) {
+ GroupElement childGroup = (GroupElement) clone[i];
+ childGroup.pack( this );
+ }
+ }
+
+ // if after packing, this is an AND or OR GE with a single
+ // child GE, then clone child into current node eliminating child
+ if ( (this.isAnd() || this.isOr()) && (this.children.size() == 1) ) {
+ Object child = this.getChildren().get( 0 );
+ if( child instanceof GroupElement ) {
+ GroupElement group = (GroupElement) child;
+ this.type = group.getType();
+ this.children.clear();
+ this.children.addAll( group.getChildren() );
+ }
+ }
+ }
+
+ /**
+ * @param parent
+ */
+ private void pack(GroupElement parent) {
+ if( this.children.size() == 0 ) {
+ // if there is no child, just remove this node
+ parent.children.remove( this );
+ return;
+ }
+
+ // If this is an AND or OR or EXISTS, there are some possible merges
+ if ( this.isAnd() || this.isOr() || this.isExists()) {
+
+ // if parent is of the same type as current node,
+ // then merge this childs with parent childs
+ if ( parent.getType() == this.getType() ) {
+
+ parent.getChildren().remove( this );
+ // for each child, pack it and add it to parent
+ for ( Iterator childIt = this.children.iterator(); childIt.hasNext(); ) {
+ Object child = childIt.next();
+ parent.addChild( child );
+ if ( child instanceof GroupElement ) {
+ ((GroupElement) child).pack( parent );
+ }
+ }
+
+ // if current node has a single child, then move it to parent and pack it
+ } else if ( ( ! this.isExists() ) && ( this.children.size() == 1 ) ) {
+ Object child = this.children.get( 0 );
+ parent.addChild( child );
+ parent.getChildren().remove( this );
+ if ( child instanceof GroupElement ) {
+ ((GroupElement) child).pack( parent );
+ }
+
+ // otherwise pack itself
+ } else {
+ this.pack();
+ }
+
+ // also pack itself if it is a NOT
+ } else {
+ this.pack();
+ }
+ }
+
+ /**
* Traverses two trees and checks that they are structurally equal at all
* levels
*
@@ -114,6 +161,10 @@
// Now try a recurse manual check
final GroupElement e2 = (GroupElement) object;
+ if ( ! this.type.equals( e2.type ) ) {
+ return false;
+ }
+
final List e1Children = this.getChildren();
final List e2Children = e2.getChildren();
if ( e1Children.size() != e2Children.size() ) {
@@ -126,20 +177,20 @@
if ( e1Object1 instanceof GroupElement ) {
if ( e1Object1.getClass().isInstance( e2Object1 ) ) {
if ( !e1Object1.equals( e2Object1 ) ) {
- System.out.println( e1Object1.getClass().getName() + " did not have identical children" );
+ //System.out.println( e1Object1.getClass().getName() + " did not have identical children" );
return false;
}
} else {
- System.out.println( "Should be the equal Conditionalelements but instead was '" + e1Object1.getClass().getName() + "', '" + e2Object1.getClass().getName() + "'" );
+ //System.out.println( "Should be the equal Conditionalelements but instead was '" + e1Object1.getClass().getName() + "', '" + e2Object1.getClass().getName() + "'" );
return false;
}
} else if ( e1Object1 instanceof String ) {
if ( !e1Object1.equals( e2Object1 ) ) {
- System.out.println( "Should be the equal Strings but instead was '" + e1Object1 + "', '" + e2Object1 + "'" );
+ //System.out.println( "Should be the equal Strings but instead was '" + e1Object1 + "', '" + e2Object1 + "'" );
return false;
}
} else {
- System.out.println( "Objects are neither instances of ConditionalElement or String" );
+ //System.out.println( "Objects are neither instances of ConditionalElement or String" );
return false;
}
}
@@ -148,7 +199,7 @@
}
public int hashCode() {
- return this.children.hashCode();
+ return this.type.hashCode() + this.children.hashCode();
}
/**
@@ -169,6 +220,8 @@
} catch ( final IllegalAccessException e ) {
throw new RuntimeException( "Could not clone '" + this.getClass().getName() + "'" );
}
+
+ cloned.setType( this.getType() );
for ( final Iterator it = this.children.iterator(); it.hasNext(); ) {
Object object = it.next();
@@ -182,4 +235,235 @@
return cloned;
}
+ public Type getType() {
+ return type;
+ }
+
+ public void setType(Type type) {
+ this.type = type;
+ }
+
+ public boolean isAnd() {
+ return this.type.isAnd();
+ }
+
+ public boolean isOr() {
+ return this.type.isOr();
+ }
+
+ public boolean isNot() {
+ return this.type.isNot();
+ }
+
+ public boolean isExists() {
+ return this.type.isExists();
+ }
+
+ public String toString() {
+ return this.type.toString()+this.children.toString();
+ }
+
+ /**
+ * A public interface for CE types
+ */
+ public static interface Type extends Serializable {
+
+ /**
+ * Returns true if this CE type is an AND
+ */
+ public boolean isAnd();
+
+ /**
+ * Returns true if this CE type is an OR
+ */
+ public boolean isOr();
+
+ /**
+ * Returns true if this CE type is an NOT
+ */
+ public boolean isNot();
+
+ /**
+ * Returns true if this CE type is an EXISTS
+ */
+ public boolean isExists();
+ }
+
+ /**
+ * An AND CE type
+ */
+ private static class AndType
+ implements
+ Type {
+
+ private static final long serialVersionUID = -669797012452495460L;
+
+ AndType() {
+ }
+
+ public boolean isAnd() {
+ return true;
+ }
+
+ public boolean isExists() {
+ return false;
+ }
+
+ public boolean isNot() {
+ return false;
+ }
+
+ public boolean isOr() {
+ return false;
+ }
+
+ public boolean equals(Object obj) {
+ if ( !(obj instanceof AndType) ) {
+ return false;
+ }
+ return true;
+ }
+
+ public int hashCode() {
+ return 11;
+ }
+
+ public String toString() {
+ return "AND";
+ }
+ }
+
+ /**
+ * An OR CE type
+ */
+ private static class OrType
+ implements
+ Type {
+
+ private static final long serialVersionUID = 8108203371968455372L;
+
+ OrType() {
+ }
+
+ public boolean isAnd() {
+ return false;
+ }
+
+ public boolean isExists() {
+ return false;
+ }
+
+ public boolean isNot() {
+ return false;
+ }
+
+ public boolean isOr() {
+ return true;
+ }
+
+ public boolean equals(Object obj) {
+ if ( !(obj instanceof OrType) ) {
+ return false;
+ }
+ return true;
+ }
+
+ public int hashCode() {
+ return 17;
+ }
+
+ public String toString() {
+ return "OR";
+ }
+ }
+
+ /**
+ * A NOT CE type
+ */
+ private static class NotType
+ implements
+ Type {
+
+ private static final long serialVersionUID = -7873159668081968617L;
+
+ NotType() {
+ }
+
+ public boolean isAnd() {
+ return false;
+ }
+
+ public boolean isExists() {
+ return false;
+ }
+
+ public boolean isNot() {
+ return true;
+ }
+
+ public boolean isOr() {
+ return false;
+ }
+
+ public boolean equals(Object obj) {
+ if ( !(obj instanceof NotType) ) {
+ return false;
+ }
+ return true;
+ }
+
+ public int hashCode() {
+ return 23;
+ }
+
+ public String toString() {
+ return "NOT";
+ }
+
+ }
+
+ /**
+ * An EXISTS CE type
+ */
+ private static class ExistsType
+ implements
+ Type {
+
+ private static final long serialVersionUID = -1528071451996382861L;
+
+ ExistsType() {
+ }
+
+ public boolean isAnd() {
+ return false;
+ }
+
+ public boolean isExists() {
+ return true;
+ }
+
+ public boolean isNot() {
+ return false;
+ }
+
+ public boolean isOr() {
+ return false;
+ }
+
+ public boolean equals(Object obj) {
+ if ( !(obj instanceof ExistsType) ) {
+ return false;
+ }
+ return true;
+ }
+
+ public int hashCode() {
+ return 31;
+ }
+
+ public String toString() {
+ return "EXISTS";
+ }
+ }
+
}
\ No newline at end of file
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElementFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElementFactory.java 2006-12-11 05:19:32 UTC (rev 8217)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElementFactory.java 2006-12-11 11:57:51 UTC (rev 8218)
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2006 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.rule;
+
+/**
+ * A simple factory for GroupElements
+ *
+ * @author etirelli
+ */
+public class GroupElementFactory {
+
+ private GroupElementFactory() {}
+
+ public static GroupElement newAndInstance() {
+ return new GroupElement( GroupElement.AND );
+ }
+
+ public static GroupElement newOrInstance() {
+ return new GroupElement( GroupElement.OR );
+ }
+
+ public static GroupElement newNotInstance() {
+ return new GroupElement( GroupElement.NOT );
+ }
+
+ public static GroupElement newExistsInstance() {
+ return new GroupElement( GroupElement.EXISTS );
+ }
+
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElementFactory.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/LogicTransformer.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/LogicTransformer.java 2006-12-11 05:19:32 UTC (rev 8217)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/LogicTransformer.java 2006-12-11 11:57:51 UTC (rev 8218)
@@ -18,12 +18,10 @@
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
-import java.util.Set;
/**
* LogicTransformation is reponsible for removing redundant nodes and move Or
@@ -36,10 +34,9 @@
*
*/
class LogicTransformer {
- private final Map duplicateTransformations = new HashMap();
- private final Map orTransformations = new HashMap();
+ private final Map orTransformations = new HashMap();
- private static LogicTransformer INSTANCE = null;
+ private static LogicTransformer INSTANCE = null;
static LogicTransformer getInstance() {
if ( LogicTransformer.INSTANCE == null ) {
@@ -58,92 +55,35 @@
*
*/
private void initialize() {
- // these pairs will have their duplciates removed
- addTransformationPair( And.class,
- And.class );
- addTransformationPair( Or.class,
- Or.class );
- addTransformationPair( Exists.class,
- Exists.class );
-
// these pairs will be transformed
- addTransformationPair( Not.class,
- Or.class,
+ addTransformationPair( GroupElement.NOT,
new NotOrTransformation() );
- addTransformationPair( Exists.class,
- Or.class,
+ addTransformationPair( GroupElement.EXISTS,
new ExistOrTransformation() );
- addTransformationPair( And.class,
- Or.class,
+ addTransformationPair( GroupElement.AND,
new AndOrTransformation() );
}
- private void addTransformationPair(final Class parent,
- final Class child) {
- final Map map = this.duplicateTransformations;
- Set childSet = (Set) map.get( child );
- if ( childSet == null ) {
- childSet = new HashSet();
- map.put( parent,
- childSet );
- }
- childSet.add( child );
+ private void addTransformationPair(final GroupElement.Type parent,
+ final Transformation method) {
+ this.orTransformations.put( parent,
+ method );
}
- private void addTransformationPair(final Class parent,
- final Class child,
- final Object method) {
- final Map map = this.orTransformations;
- Map childMap = (Map) map.get( parent );
- if ( childMap == null ) {
- childMap = new HashMap();
- map.put( parent,
- childMap );
- }
- childMap.put( child,
- method );
- }
+ public GroupElement[] transform(final GroupElement and) throws InvalidPatternException {
+ GroupElement cloned = (GroupElement) and.clone();
- And[] transform(final And and) throws InvalidPatternException {
- final And cloned = (And) and.clone();
-
processTree( cloned );
+ cloned.pack();
- // Scan for any Child Ors, if found we need apply the
- // AndOrTransformation
- // And assign the result to the null declared or
- Or or = null;
- for ( final Iterator it = cloned.getChildren().iterator(); it.hasNext(); ) {
- final Object object = it.next();
- if ( object instanceof Or ) {
- or = (Or) applyOrTransformation( cloned,
- (GroupElement) object );
- break;
- }
- }
-
- And[] ands = null;
- // Or will be null if there are no Ors in our tree
- if ( or == null ) {
- // No or so just assign
- ands = new And[]{cloned};
- checkForAndRemoveDuplicates( ands[0] );
+ GroupElement[] ands = null;
+ // is top element an AND?
+ if ( cloned.getType() == GroupElement.AND ) {
+ // Yes, so just return it
+ ands = new GroupElement[]{cloned};
} else {
- ands = new And[or.getChildren().size()];
- int i = 0;
- for ( final Iterator it = or.getChildren().iterator(); it.hasNext(); ) {
- final Object object = it.next();
- if ( object.getClass() == And.class ) {
- ands[i] = (And) object;
- } else {
- final And newAnd = new And();
- newAnd.addChild( and );
- ands[i] = newAnd;
- }
-
- checkForAndRemoveDuplicates( ands[i++] );
- }
-
+ // No, so each child is an AND branch
+ ands = (GroupElement[]) cloned.getChildren().toArray( new GroupElement[cloned.getChildren().size()] );
}
return ands;
}
@@ -163,90 +103,39 @@
*/
void processTree(final GroupElement ce) throws InvalidPatternException {
+ boolean hasChildOr = false;
+
+ // first we eliminicate any redundancy
+ ce.pack();
+
for ( final ListIterator it = ce.getChildren().listIterator(); it.hasNext(); ) {
final Object object = it.next();
if ( object instanceof GroupElement ) {
- final GroupElement parent = (GroupElement) object;
+ final GroupElement child = (GroupElement) object;
- processTree( parent );
+ processTree( child );
- checkForAndRemoveDuplicates( parent );
-
- // Scan for any Child Ors, if found we need to move the Or
- // upwards
- for ( final Iterator orIter = parent.getChildren().iterator(); orIter.hasNext(); ) {
- final Object object2 = orIter.next();
- if ( object2 instanceof Or ) {
- it.remove();
- it.add( applyOrTransformation( parent,
- (GroupElement) object2 ) );
- break;
- }
+ if ( child.isOr() ) {
+ hasChildOr = true;
}
-
}
}
- }
-
- /**
- * Given a parent and child checks if they are duplicates and that they set
- * to have duplicates removed
- *
- * @param parent
- * @param child
- * @return
- */
- boolean removeDuplicate(final GroupElement parent,
- final GroupElement child) {
- if ( this.duplicateTransformations.get( parent.getClass() ) != null ) {
- return ((HashSet) this.duplicateTransformations.get( parent.getClass() )).contains( child.getClass() );
+ if ( hasChildOr ) {
+ applyOrTransformation( ce );
}
-
- return false;
}
- /**
- * Removes duplicates, children of the duplicate added to the parent and the
- * duplicate child is removed by the parent method.
- *
- */
- void checkForAndRemoveDuplicates(final GroupElement parent) {
- for ( final ListIterator it = parent.getChildren().listIterator(); it.hasNext(); ) {
- final Object object = it.next();
- // Remove the duplicate if the classes are the same and
- // removeDuplicate method returns true
- if ( parent.getClass().isInstance( object ) && removeDuplicate( parent,
- (GroupElement) object ) ) {
- final List newList = new ArrayList();
- final GroupElement child = (GroupElement) object;
- for ( final Iterator childIter = child.getChildren().iterator(); childIter.hasNext(); ) {
- newList.add( childIter.next() );
- }
- it.remove();
- for ( final Iterator childIter = newList.iterator(); childIter.hasNext(); ) {
- it.add( childIter.next() );
- }
- }
- }
- }
+ void applyOrTransformation(final GroupElement parent) throws InvalidPatternException {
+ Transformation transformation = (Transformation) this.orTransformations.get( parent.getType() );
- GroupElement applyOrTransformation(final GroupElement parent,
- final GroupElement child) throws InvalidPatternException {
- Transformation transformation = null;
- final Map map = (HashMap) this.orTransformations.get( parent.getClass() );
- if ( map != null ) {
- transformation = (Transformation) map.get( child.getClass() );
- }
-
if ( transformation == null ) {
- throw new RuntimeException( "applyOrTransformation could not find transformation for parent '" + parent.getClass().getName() + "' and child '" + child.getClass().getName() + "'" );
+ throw new RuntimeException( "applyOrTransformation could not find transformation for parent '" + parent.getType() + "' and child 'OR'" );
}
-
- return transformation.transform( parent );
+ transformation.transform( parent );
}
interface Transformation {
- GroupElement transform(GroupElement element) throws InvalidPatternException;
+ void transform(GroupElement element) throws InvalidPatternException;
}
/**
@@ -280,94 +169,52 @@
implements
Transformation {
- public GroupElement transform(final GroupElement and) throws InvalidPatternException {
- final Or or = new Or();
- determinePermutations( 0,
- (And) and,
- null,
- or );
- return or;
- }
+ public void transform(final GroupElement parent) throws InvalidPatternException {
+ List orsList = new ArrayList();
+ List others = new ArrayList();
- /**
- * Recursive method that determins all unique combinations of children
- * for the given parent and.
- *
- * @param currentLevel
- * @param and
- * @param combination
- * @param or
- */
- private void determinePermutations(final int currentLevel,
- final And and,
- And combination,
- final Or or) {
- final Object entry = and.getChildren().get( currentLevel );
- if ( entry instanceof Or ) {
- // Only OR nodes need to be iterated over
- final Or childOr = (Or) entry;
- for ( final Iterator it = childOr.getChildren().iterator(); it.hasNext(); ) {
- // Make a temp copy of combinations+new entry which will be
- // sent forward
- final And temp = new And();
- if ( currentLevel == 0 ) {
- // Always start with a clean combination
- combination = new And();
- } else {
- temp.getChildren().addAll( combination.getChildren() );
- }
+ // first we split children as OR or not OR
+ int permutations = 1;
+ for ( Iterator it = parent.getChildren().iterator(); it.hasNext(); ) {
+ Object child = it.next();
+ if ( (child instanceof GroupElement) && ((GroupElement) child).isOr() ) {
+ permutations *= ((GroupElement) child).getChildren().size();
+ orsList.add( child );
+ } else {
+ others.add( child );
+ }
+ }
- // now check for and remove duplicates
- final Object object = it.next();
- if ( object instanceof And ) {
- // Can't have duplicate Ands so move up the children
- final And childAnd = (And) object;
- for ( final Iterator childIter = childAnd.getChildren().iterator(); childIter.hasNext(); ) {
- temp.addChild( childIter.next() );
- }
- } else {
- // no duplicates so just add
- temp.addChild( object );
- }
+ // transform parent into an OR
+ parent.setType( GroupElement.OR );
+ parent.getChildren().clear();
- if ( currentLevel < and.getChildren().size() - 1 ) {
- // keep recursing to build up the combination until we
- // are at the end where it will be added to or
- determinePermutations( currentLevel + 1,
- and,
- temp,
- or );
- } else {
- // we are at the end so just attach the combination to
- // the or node
- or.addChild( temp );
+ // prepare arrays and indexes to calculate permutation
+ GroupElement[] ors = (GroupElement[]) orsList.toArray( new GroupElement[orsList.size()] );
+ int[] indexes = new int[ors.length];
+
+ // now we know how many permutations we will have, so create it
+ for ( int i = 1; i <= permutations; i++ ) {
+ GroupElement and = GroupElementFactory.newAndInstance();
+
+ // elements originally outside OR will be in every permutation, so add them
+ and.getChildren().addAll( others );
+
+ // create the actual permutations
+ int mod = 1;
+ for ( int j = ors.length - 1; j >= 0; j-- ) {
+ and.addChild( ors[j].getChildren().get( indexes[j] ) );
+ if ( (i % mod) == 0 ) {
+ indexes[j] = (indexes[j] + 1) % ors[j].getChildren().size();
}
+ mod *= ors[j].getChildren().size();
}
- } else {
- // Make a temp copy of combinations+new entry which will be sent
- // forward
- final And temp = new And();
- if ( currentLevel == 0 ) {
- // Always start with a clean combination
- combination = new And();
- } else {
- temp.getChildren().addAll( combination.getChildren() );
- }
- temp.addChild( entry );
- if ( currentLevel < and.getChildren().size() - 1 ) {
- // keep recursing to build up the combination until we are
- // at the end where it will be added to or
- determinePermutations( currentLevel + 1,
- and,
- temp,
- or );
- } else {
- // we are at the end so just attach the combination to the
- // or node
- or.addChild( temp );
- }
+ parent.addChild( and );
}
+
+ // remove duplications
+ parent.pack();
}
}
@@ -385,35 +232,35 @@
* (Exist ( Not (a) Not (b)) )
*
* <pre>
- * Exist
+ * Or
* / \
- * Not Not
- * | |
- * a b
+ * Exists Exists
+ * | |
+ * a b
* </pre>
*/
class ExistOrTransformation
implements
Transformation {
- public GroupElement transform(final GroupElement exist) throws InvalidPatternException {
- throw new InvalidPatternException( "You cannot nest an OR within an Exists" );
- // if ( !(exist.getChildren().get( 0 ) instanceof Or) ) {
- // throw new RuntimeException( "ExistOrTransformation expected '" + Or.class.getName() + "' but instead found '" + exist.getChildren().get( 0 ).getClass().getName() + "'" );
- // }
- //
- // /*
- // * we know a Not only ever has one child, and the previous algorithm
- // * has confirmed the child is an OR
- // */
- // Or or = (Or) exist.getChildren().get( 0 );
- // And and = new And();
- // for ( Iterator it = or.getChildren().iterator(); it.hasNext(); ) {
- // Exists newExist = new Exists();
- // newExist.addChild( it.next() );
- // and.addChild( newExist );
- // }
- // return and;
+ public void transform(final GroupElement parent) throws InvalidPatternException {
+ if ( (!(parent.getChildren().get( 0 ) instanceof GroupElement)) && (((GroupElement) parent.getChildren().get( 0 )).isExists()) ) {
+ throw new RuntimeException( "ExistOrTransformation expected 'OR' but instead found '" + parent.getChildren().get( 0 ).getClass().getName() + "'" );
+ }
+
+ /*
+ * we know an Exists only ever has one child, and the previous algorithm
+ * has confirmed the child is an OR
+ */
+ GroupElement or = (GroupElement) parent.getChildren().get( 0 );
+ parent.setType( GroupElement.OR );
+ parent.getChildren().clear();
+ for ( Iterator it = or.getChildren().iterator(); it.hasNext(); ) {
+ GroupElement newExists = GroupElementFactory.newExistsInstance();
+ newExists.addChild( it.next() );
+ parent.addChild( newExists );
+ }
+ parent.pack();
}
}
@@ -442,26 +289,25 @@
implements
Transformation {
- public GroupElement transform(final GroupElement not) throws InvalidPatternException {
+ public void transform(final GroupElement parent) throws InvalidPatternException {
- throw new InvalidPatternException( "You cannot nest an OR within an Not" );
- // @todo for 3.1
- // if ( !(not.getChildren().get( 0 ) instanceof Or) ) {
- // throw new RuntimeException( "NotOrTransformation expected '" + Or.class.getName() + "' but instead found '" + not.getChildren().get( 0 ).getClass().getName() + "'" );
- // }
- //
- // /*
- // * we know a Not only ever has one child, and the previous algorithm
- // * has confirmed the child is an OR
- // */
- // Or or = (Or) not.getChildren().get( 0 );
- // And and = new And();
- // for ( Iterator it = or.getChildren().iterator(); it.hasNext(); ) {
- // Not newNot = new Not();
- // newNot.addChild( it.next() );
- // and.addChild( newNot );
- // }
- // return and;
+ if ( (!(parent.getChildren().get( 0 ) instanceof GroupElement)) && (((GroupElement) parent.getChildren().get( 0 )).isOr()) ) {
+ throw new RuntimeException( "NotOrTransformation expected 'OR' but instead found '" + parent.getChildren().get( 0 ).getClass().getName() + "'" );
+ }
+
+ /*
+ * we know a Not only ever has one child, and the previous algorithm
+ * has confirmed the child is an OR
+ */
+ GroupElement or = (GroupElement) parent.getChildren().get( 0 );
+ parent.setType( GroupElement.AND );
+ parent.getChildren().clear();
+ for ( Iterator it = or.getChildren().iterator(); it.hasNext(); ) {
+ GroupElement newNot = GroupElementFactory.newNotInstance();
+ newNot.addChild( it.next() );
+ parent.addChild( newNot );
+ }
+ parent.pack();
}
}
Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Not.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Not.java 2006-12-11 05:19:32 UTC (rev 8217)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Not.java 2006-12-11 11:57:51 UTC (rev 8218)
@@ -1,29 +0,0 @@
-package org.drools.rule;
-
-/*
- * Copyright 2005 JBoss Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-public class Not extends GroupElement {
- /**
- *
- */
- private static final long serialVersionUID = 8315240872099444225L;
-
- public Object getChild() {
- return getChildren().get( 0 );
- }
-
-}
\ No newline at end of file
Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Or.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Or.java 2006-12-11 05:19:32 UTC (rev 8217)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Or.java 2006-12-11 11:57:51 UTC (rev 8218)
@@ -1,26 +0,0 @@
-package org.drools.rule;
-
-/*
- * Copyright 2005 JBoss Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-public class Or extends GroupElement {
-
- /**
- *
- */
- private static final long serialVersionUID = 1519832383109314339L;
-
-}
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java 2006-12-11 05:19:32 UTC (rev 8217)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java 2006-12-11 11:57:51 UTC (rev 8218)
@@ -64,7 +64,7 @@
private Declaration[] declarationArray;
- private final And lhsRoot = new And();
+ private final GroupElement lhsRoot = new GroupElement( GroupElement.AND );
private String agendaGroup;
@@ -347,7 +347,7 @@
*
* @return The <code>List</code> of <code>Conditions</code>.
*/
- public And getLhs() {
+ public GroupElement getLhs() {
return this.lhsRoot;
}
@@ -361,7 +361,7 @@
* @return
* @throws InvalidPatternException
*/
- public And[] getTransformedLhs() throws InvalidPatternException {
+ public GroupElement[] getTransformedLhs() throws InvalidPatternException {
return LogicTransformer.getInstance().transform( this.lhsRoot );
}
Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/BaseMannersTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/BaseMannersTest.java 2006-12-11 05:19:32 UTC (rev 8217)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/BaseMannersTest.java 2006-12-11 11:57:51 UTC (rev 8218)
@@ -42,9 +42,10 @@
import org.drools.base.field.LongFieldImpl;
import org.drools.rule.Column;
import org.drools.rule.Declaration;
+import org.drools.rule.GroupElement;
+import org.drools.rule.GroupElementFactory;
import org.drools.rule.InvalidRuleException;
import org.drools.rule.LiteralConstraint;
-import org.drools.rule.Not;
import org.drools.rule.Package;
import org.drools.rule.Rule;
import org.drools.rule.VariableConstraint;
@@ -425,7 +426,7 @@
"guestName",
leftGuestNameDeclaration,
this.objectEqualEvaluator ) );
- final Not notPath = new Not();
+ final GroupElement notPath = GroupElementFactory.newNotInstance();
notPath.addChild( notPathColumn );
rule.addPattern( notPath );
// ------------
@@ -450,7 +451,7 @@
rightGuestHobbyDeclaration,
this.objectEqualEvaluator ) );
- final Not notChosen = new Not();
+ final GroupElement notChosen = GroupElementFactory.newNotInstance();
notChosen.addChild( notChosenColumn );
rule.addPattern( notChosen );
@@ -640,7 +641,7 @@
pathGuestNameDeclaration,
this.objectEqualEvaluator ) );
- final Not not = new Not();
+ final GroupElement not = GroupElementFactory.newNotInstance();
not.addChild( notPathColumn );
Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/GroupElementTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/GroupElementTest.java 2006-12-11 05:19:32 UTC (rev 8217)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/GroupElementTest.java 2006-12-11 11:57:51 UTC (rev 8218)
@@ -1,98 +1,336 @@
package org.drools.rule;
+import org.drools.RuntimeDroolsException;
+
+import junit.framework.Assert;
import junit.framework.TestCase;
public class GroupElementTest extends TestCase {
- public void test1() {
- //dummy test
- assertTrue( true );
+
+ public void testPackNestedAnd() {
+ GroupElement and1 = GroupElementFactory.newAndInstance();
+ Column column1 = new Column( 0,
+ null );
+ and1.addChild( column1 );
+
+ Column column2 = new Column( 0,
+ null );
+ and1.addChild( column2 );
+
+ assertEquals( 2,
+ and1.getChildren().size() );
+ assertSame( column1,
+ and1.getChildren().get( 0 ) );
+ assertSame( column2,
+ and1.getChildren().get( 1 ) );
+
+ GroupElement and2 = GroupElementFactory.newAndInstance();
+ and2.addChild( and1 );
+
+ and2.pack();
+ assertEquals( 2,
+ and2.getChildren().size() );
+ assertSame( column1,
+ and2.getChildren().get( 0 ) );
+ assertSame( column2,
+ and2.getChildren().get( 1 ) );
}
- // public void testAddNestedAnd() {
- // And and1 = new And();
- // Column column1 = new Column(0, null);
- // and1.addChild( column1 );
- //
- // Column column2 = new Column(0, null);
- // and1.addChild( column2 );
- //
- // assertEquals( 2, and1.getChildren().size() );
- // assertSame( column1, and1.getChildren().get( 0 ) );
- // assertSame( column2, and1.getChildren().get( 1 ) );
- //
- // And and2 = new And();
- // and2.addChild( and1 );
- // assertEquals( 2, and2.getChildren().size() );
- // assertSame( column1, and2.getChildren().get( 0 ) );
- // assertSame( column2, and2.getChildren().get( 1 ) );
- // }
- //
- // public void testAddNestedOr() {
- // Or or1 = new Or();
- // Column column1 = new Column(0, null);
- // or1.addChild( column1 );
- //
- // Column column2 = new Column(0, null);
- // or1.addChild( column2 );
- //
- // assertEquals( 2, or1.getChildren().size() );
- // assertSame( column1, or1.getChildren().get( 0 ) );
- // assertSame( column2, or1.getChildren().get( 1 ) );
- //
- // Or or2 = new Or();
- // or2.addChild( or1 );
- // assertEquals( 2, or2.getChildren().size() );
- // assertSame( column1, or2.getChildren().get( 0 ) );
- // assertSame( column2, or2.getChildren().get( 1 ) );
- // }
- //
- // public void testAddSingleBranchAnd() {
- // And and1 = new And();
- // Column column = new Column(0, null);
- // and1.addChild( column );
- // assertEquals( 1, and1.getChildren().size() );
- // assertSame( column, and1.getChildren().get( 0 ) );
- //
- // Or or1= new Or();
- // or1.addChild( and1 );
- // assertEquals( 1, or1.getChildren().size() );
- // assertSame( column, or1.getChildren().get( 0 ) );
- // }
- //
- // public void testAddSingleBranchOr() {
- // Or or1 = new Or();
- // Column column = new Column(0, null);
- // or1.addChild( column );
- // assertEquals( 1, or1.getChildren().size() );
- // assertSame( column, or1.getChildren().get( 0 ) );
- //
- // And and1= new And();
- // and1.addChild( or1 );
- // assertEquals( 1, and1.getChildren().size() );
- // assertSame( column, and1.getChildren().get( 0 ) );
- // }
- //
- // public void testX() {
- // Or or1 = new Or();
- // Column column1 = new Column(0, null);
- // or1.addChild( column1 );
- //
- // Column column2 = new Column(0, null);
- // or1.addChild( column2 );
- //
- // And and1 = new And();
- // and1.addChild( or1 );
- // assertEquals( 1, and1.getChildren().size() );
- // assertSame( or1, and1.getChildren().get( 0 ) );
- //
- // assertSame( column1, or1.getChildren().get( 0 ) );
- // assertSame( column2, or1.getChildren().get( 1 ) );
- //
- // Or or2 = new Or();
- // or2.addChild( and1 );
- //
- // assertEquals( 2, or1.getChildren().size() );
- // assertSame( column1, or1.getChildren().get( 0 ) );
- // assertSame( column2, or2.getChildren().get( 1 ) );
- //
- // }
+
+ public void testPackNestedOr() {
+ GroupElement or1 = GroupElementFactory.newOrInstance();
+ Column column1 = new Column( 0,
+ null );
+ or1.addChild( column1 );
+
+ Column column2 = new Column( 0,
+ null );
+ or1.addChild( column2 );
+
+ assertEquals( 2,
+ or1.getChildren().size() );
+ assertSame( column1,
+ or1.getChildren().get( 0 ) );
+ assertSame( column2,
+ or1.getChildren().get( 1 ) );
+
+ GroupElement or2 = GroupElementFactory.newOrInstance();
+ or2.addChild( or1 );
+
+ or2.pack();
+
+ assertEquals( 2,
+ or2.getChildren().size() );
+ assertSame( column1,
+ or2.getChildren().get( 0 ) );
+ assertSame( column2,
+ or2.getChildren().get( 1 ) );
+ }
+
+ public void testPackNestedExists() {
+ GroupElement exists1 = GroupElementFactory.newExistsInstance();
+ Column column1 = new Column( 0,
+ null );
+ exists1.addChild( column1 );
+
+ assertEquals( 1,
+ exists1.getChildren().size() );
+ assertSame( column1,
+ exists1.getChildren().get( 0 ) );
+
+ GroupElement exists2 = GroupElementFactory.newExistsInstance();
+ exists2.addChild( exists1 );
+
+ exists2.pack();
+
+ assertEquals( 1,
+ exists2.getChildren().size() );
+ assertSame( column1,
+ exists2.getChildren().get( 0 ) );
+ }
+
+ public void testAddMultipleChildsIntoNot() {
+ GroupElement not = GroupElementFactory.newNotInstance();
+
+ Column column1 = new Column( 0,
+ null );
+ try {
+ not.addChild( column1 );
+ } catch ( RuntimeDroolsException rde ) {
+ Assert.fail( "Adding a single child is not supposed to throw Exception for NOT GE: " + rde.getMessage() );
+ }
+
+ Column column2 = new Column( 0,
+ null );
+ try {
+ not.addChild( column2 );
+ Assert.fail( "Adding a second child into a NOT GE should throw Exception" );
+ } catch ( RuntimeDroolsException rde ) {
+ // everything is fine
+ }
+ }
+
+ public void testAddSingleBranchAnd() {
+ GroupElement and1 = GroupElementFactory.newAndInstance();
+ Column column = new Column( 0,
+ null );
+ and1.addChild( column );
+ assertEquals( 1,
+ and1.getChildren().size() );
+ assertSame( column,
+ and1.getChildren().get( 0 ) );
+
+ GroupElement or1 = GroupElementFactory.newOrInstance();
+ or1.addChild( and1 );
+
+ or1.pack();
+ assertEquals( 1,
+ or1.getChildren().size() );
+ assertSame( column,
+ or1.getChildren().get( 0 ) );
+ }
+
+ public void testAddSingleBranchOr() {
+ GroupElement or1 = GroupElementFactory.newOrInstance();
+ Column column = new Column( 0,
+ null );
+ or1.addChild( column );
+ assertEquals( 1,
+ or1.getChildren().size() );
+ assertSame( column,
+ or1.getChildren().get( 0 ) );
+
+ GroupElement and1 = GroupElementFactory.newAndInstance();
+ and1.addChild( or1 );
+
+ and1.pack();
+ assertEquals( 1,
+ and1.getChildren().size() );
+ assertSame( column,
+ and1.getChildren().get( 0 ) );
+ }
+
+ /**
+ * This test tests deep nested structures, and shall transform this:
+ *
+ * AND2
+ * |
+ * OR3
+ * |
+ * OR2
+ * |
+ * AND1
+ * |
+ * OR1
+ * / \
+ * C1 C2
+ *
+ * Into this:
+ *
+ * OR1
+ * / \
+ * C1 C2
+ *
+ */
+ public void testDeepNestedStructure() {
+ GroupElement or1 = GroupElementFactory.newOrInstance();
+ Column column1 = new Column( 0,
+ null );
+ or1.addChild( column1 );
+
+ Column column2 = new Column( 0,
+ null );
+ or1.addChild( column2 );
+
+ GroupElement and1 = GroupElementFactory.newAndInstance();
+ and1.addChild( or1 );
+ assertEquals( 1,
+ and1.getChildren().size() );
+ assertSame( or1,
+ and1.getChildren().get( 0 ) );
+
+ assertSame( column1,
+ or1.getChildren().get( 0 ) );
+ assertSame( column2,
+ or1.getChildren().get( 1 ) );
+
+ GroupElement or2 = GroupElementFactory.newOrInstance();
+ or2.addChild( and1 );
+
+ assertEquals( 1,
+ or2.getChildren().size() );
+ assertSame( and1,
+ or2.getChildren().get( 0 ) );
+
+ GroupElement or3 = GroupElementFactory.newOrInstance();
+ or3.addChild( or2 );
+
+ assertEquals( 1,
+ or2.getChildren().size() );
+ assertSame( or2,
+ or3.getChildren().get( 0 ) );
+
+ GroupElement and2 = GroupElementFactory.newAndInstance();
+ and2.addChild( or3 );
+
+ assertEquals( 1,
+ and2.getChildren().size() );
+ assertSame( or3,
+ and2.getChildren().get( 0 ) );
+
+ // Now pack the structure
+ and2.pack();
+
+ // and2 now is in fact transformed into an OR
+ assertEquals( GroupElement.OR, and2.getType() );
+
+ assertEquals( 2,
+ and2.getChildren().size() );
+
+ assertSame( column1,
+ and2.getChildren().get( 0 ) );
+ assertSame( column2,
+ and2.getChildren().get( 1 ) );
+
+ }
+
+ /**
+ * This test tests deep nested structures, and shall transform this:
+ *
+ * AND2
+ * / \
+ * OR3 C3
+ * |
+ * OR2
+ * |
+ * AND1
+ * |
+ * OR1
+ * / \
+ * C1 C2
+ *
+ * Into this:
+ *
+ * AND2
+ * / \
+ * OR1 C3
+ * / \
+ * C1 C2
+ *
+ */
+ public void testDeepNestedStructureWithMultipleElementsInRoot() {
+ GroupElement or1 = GroupElementFactory.newOrInstance();
+ Column column1 = new Column( 0,
+ null );
+ or1.addChild( column1 );
+
+ Column column2 = new Column( 0,
+ null );
+ or1.addChild( column2 );
+
+ GroupElement and1 = GroupElementFactory.newAndInstance();
+ and1.addChild( or1 );
+ assertEquals( 1,
+ and1.getChildren().size() );
+ assertSame( or1,
+ and1.getChildren().get( 0 ) );
+
+ assertSame( column1,
+ or1.getChildren().get( 0 ) );
+ assertSame( column2,
+ or1.getChildren().get( 1 ) );
+
+ GroupElement or2 = GroupElementFactory.newOrInstance();
+ or2.addChild( and1 );
+
+ assertEquals( 1,
+ or2.getChildren().size() );
+ assertSame( and1,
+ or2.getChildren().get( 0 ) );
+
+ GroupElement or3 = GroupElementFactory.newOrInstance();
+ or3.addChild( or2 );
+
+ assertEquals( 1,
+ or2.getChildren().size() );
+ assertSame( or2,
+ or3.getChildren().get( 0 ) );
+
+ GroupElement and2 = GroupElementFactory.newAndInstance();
+ and2.addChild( or3 );
+
+ Column column3 = new Column( 0,
+ null );
+ and2.addChild( column3 );
+
+ assertEquals( 2,
+ and2.getChildren().size() );
+ assertSame( or3,
+ and2.getChildren().get( 0 ) );
+ assertSame( column3,
+ and2.getChildren().get( 1 ) );
+
+ // Now pack the structure
+ and2.pack();
+
+ // and2 now is in fact transformed into an OR
+ assertEquals( GroupElement.AND, and2.getType() );
+
+ assertEquals( 2,
+ and2.getChildren().size() );
+
+ assertSame( column3,
+ and2.getChildren().get( 0 ) );
+ assertSame( or1,
+ and2.getChildren().get( 1 ) );
+
+
+ assertEquals( 2,
+ or1.getChildren().size() );
+ assertSame( column1,
+ or1.getChildren().get( 0 ) );
+ assertSame( column2,
+ or1.getChildren().get( 1 ) );
+
+ }
+
}
Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/LogicTransformerTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/LogicTransformerTest.java 2006-12-11 05:19:32 UTC (rev 8217)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/LogicTransformerTest.java 2006-12-11 11:57:51 UTC (rev 8218)
@@ -54,30 +54,29 @@
final String b = "b";
final String c = "c";
- final And and = new And();
- and.addChild( c );
- final Or or = new Or();
+ final GroupElement parent = GroupElementFactory.newAndInstance();
+ parent.addChild( c );
+ final GroupElement or = GroupElementFactory.newOrInstance();
or.addChild( a );
or.addChild( b );
- and.addChild( or );
+ parent.addChild( or );
- final Or newOr = (Or) LogicTransformer.getInstance().applyOrTransformation( and,
- or );
+ LogicTransformer.getInstance().applyOrTransformation( parent );
assertLength( 2,
- newOr.getChildren() );
- assertEquals( And.class,
- newOr.getChildren().get( 0 ).getClass() );
- assertEquals( And.class,
- newOr.getChildren().get( 1 ).getClass() );
+ parent.getChildren() );
+ assertEquals( GroupElement.class,
+ parent.getChildren().get( 0 ).getClass() );
+ assertEquals( GroupElement.class,
+ parent.getChildren().get( 1 ).getClass() );
- final And and1 = (And) newOr.getChildren().get( 0 );
+ final GroupElement and1 = (GroupElement) parent.getChildren().get( 0 );
assertContains( c,
and1.getChildren() );
assertContains( a,
and1.getChildren() );
- final And and2 = (And) newOr.getChildren().get( 1 );
+ final GroupElement and2 = (GroupElement) parent.getChildren().get( 1 );
assertContains( c,
and2.getChildren() );
assertContains( b,
@@ -123,38 +122,42 @@
final String e = "e";
final String f = "f";
- final And and = new And();
- final Or or = new Or();
+ final GroupElement parent = GroupElementFactory.newAndInstance();
+ final GroupElement or = GroupElementFactory.newOrInstance();
or.addChild( a );
or.addChild( b );
- and.addChild( or );
- and.addChild( c );
+ parent.addChild( or );
+ parent.addChild( c );
- final Or or2 = new Or();
+ final GroupElement or2 = GroupElementFactory.newOrInstance();
or2.addChild( d );
or2.addChild( e );
- and.addChild( or2 );
+ parent.addChild( or2 );
- final Not not = new Not();
+ final GroupElement not = GroupElementFactory.newNotInstance();
not.addChild( f );
- and.addChild( not );
+ parent.addChild( not );
- final Or newOr = (Or) LogicTransformer.getInstance().applyOrTransformation( and,
- or );
+ LogicTransformer.getInstance().applyOrTransformation( parent );
+ assertEquals( GroupElement.OR,
+ parent.getType() );
+
assertLength( 4,
- newOr.getChildren() );
- assertEquals( And.class,
- newOr.getChildren().get( 0 ).getClass() );
- assertEquals( And.class,
- newOr.getChildren().get( 1 ).getClass() );
- assertEquals( And.class,
- newOr.getChildren().get( 2 ).getClass() );
- assertEquals( And.class,
- newOr.getChildren().get( 3 ).getClass() );
+ parent.getChildren() );
+ assertEquals( GroupElement.class,
+ parent.getChildren().get( 0 ).getClass() );
+ assertEquals( GroupElement.class,
+ parent.getChildren().get( 1 ).getClass() );
+ assertEquals( GroupElement.class,
+ parent.getChildren().get( 2 ).getClass() );
+ assertEquals( GroupElement.class,
+ parent.getChildren().get( 3 ).getClass() );
- And and1 = (And) newOr.getChildren().get( 0 );
+ GroupElement and1 = (GroupElement) parent.getChildren().get( 0 );
+ assertEquals( GroupElement.AND,
+ and1.getType() );
assertLength( 4,
and1.getChildren() );
assertContains( a,
@@ -166,7 +169,9 @@
assertContains( not,
and1.getChildren() );
- and1 = (And) newOr.getChildren().get( 1 );
+ and1 = (GroupElement) parent.getChildren().get( 1 );
+ assertEquals( GroupElement.AND,
+ and1.getType() );
assertLength( 4,
and1.getChildren() );
assertContains( a,
@@ -178,7 +183,9 @@
assertContains( not,
and1.getChildren() );
- and1 = (And) newOr.getChildren().get( 2 );
+ and1 = (GroupElement) parent.getChildren().get( 2 );
+ assertEquals( GroupElement.AND,
+ and1.getType() );
assertLength( 4,
and1.getChildren() );
assertContains( b,
@@ -190,7 +197,9 @@
assertContains( not,
and1.getChildren() );
- and1 = (And) newOr.getChildren().get( 3 );
+ and1 = (GroupElement) parent.getChildren().get( 3 );
+ assertEquals( GroupElement.AND,
+ and1.getType() );
assertLength( 4,
and1.getChildren() );
assertContains( b,
@@ -206,7 +215,7 @@
/**
* This data structure is now valid
*
- * (Not (OR (A B)
+ * (Not (OR (A B) ) )
*
* <pre>
* Not
@@ -216,29 +225,53 @@
* a b
* </pre>
*
+ * Should become:
+ *
+ * <pre>
+ * And
+ * / \
+ * Not Not
+ * | |
+ * a b
+ * </pre>
+ *
+ *
*/
- public void xxxtestNotOrTransformation() throws InvalidPatternException {
+ public void testNotOrTransformation() throws InvalidPatternException {
final String a = "a";
final String b = "b";
- final Not not = new Not();
- final Or or = new Or();
- not.addChild( or );
+ final GroupElement parent = GroupElementFactory.newNotInstance();
+ final GroupElement or = GroupElementFactory.newOrInstance();
+ parent.addChild( or );
or.addChild( a );
or.addChild( b );
- try {
- final And newAnd = (And) LogicTransformer.getInstance().applyOrTransformation( not,
- or );
- fail( "This should fail as you cannot nest Ors under Nots" );
- } catch ( final InvalidPatternException e ) {
- //
- }
+ LogicTransformer.getInstance().applyOrTransformation( parent );
+
+ assertTrue( parent.isAnd() );
+ assertEquals( 2,
+ parent.getChildren().size() );
+
+ GroupElement b1 = (GroupElement) parent.getChildren().get( 0 );
+ GroupElement b2 = (GroupElement) parent.getChildren().get( 1 );
+ assertTrue( b1.isNot() );
+ assertTrue( b2.isNot() );
+
+ assertEquals( 1,
+ b1.getChildren().size() );
+ assertEquals( a,
+ b1.getChildren().get( 0 ) );
+
+ assertEquals( 1,
+ b2.getChildren().size() );
+ assertEquals( b,
+ b2.getChildren().get( 0 ) );
}
/**
- * This data structure is not valid (Exists (OR (A B)
+ * This data structure is now valid (Exists (OR (A B) ) )
*
* <pre>
* Exists
@@ -248,62 +281,83 @@
* a b
* </pre>
*
+ * Should become:
+ *
+ * <pre>
+ * Or
+ * / \
+ * Exists Exists
+ * | |
+ * a b
+ * </pre>
*/
- public void xxxtestExistOrTransformation() throws InvalidPatternException {
+ public void testExistOrTransformation() throws InvalidPatternException {
final String a = "a";
final String b = "b";
- final Exists exist = new Exists();
- final Or or = new Or();
- exist.addChild( or );
+ final GroupElement parent = GroupElementFactory.newExistsInstance();
+ final GroupElement or = GroupElementFactory.newOrInstance();
+ parent.addChild( or );
or.addChild( a );
or.addChild( b );
- try {
- final And newAnd = (And) LogicTransformer.getInstance().applyOrTransformation( exist,
- or );
+ LogicTransformer.getInstance().applyOrTransformation( parent );
- fail( "This should fail as you cannot nest Ors under Existss" );
- } catch ( final InvalidPatternException e ) {
- //
- }
+ assertTrue( parent.isOr() );
+ assertEquals( 2,
+ parent.getChildren().size() );
+ GroupElement b1 = (GroupElement) parent.getChildren().get( 0 );
+ GroupElement b2 = (GroupElement) parent.getChildren().get( 1 );
+ assertTrue( b1.isExists() );
+ assertTrue( b2.isExists() );
+
+ assertEquals( 1,
+ b1.getChildren().size() );
+ assertEquals( a,
+ b1.getChildren().get( 0 ) );
+
+ assertEquals( 1,
+ b2.getChildren().size() );
+ assertEquals( b,
+ b2.getChildren().get( 0 ) );
+
}
- public void testDuplicatTransformation() throws InvalidRuleException {
+ public void testEliminateEmptyBranchesAndDuplications() throws InvalidRuleException {
final String a = "a";
final String b = "b";
final String c = "c";
final String d = "d";
- final And and1 = new And();
+ final GroupElement and1 = GroupElementFactory.newAndInstance();
and1.addChild( a );
and1.addChild( b );
- final And and2 = new And();
+ final GroupElement and2 = GroupElementFactory.newAndInstance();
and2.addChild( c );
and2.addChild( d );
and1.addChild( and2 );
- final Or or = new Or();
+ final GroupElement or = GroupElementFactory.newOrInstance();
and1.addChild( or );
- LogicTransformer.getInstance().checkForAndRemoveDuplicates( and1 );
+ GroupElement[] result = LogicTransformer.getInstance().transform( and1 );
- assertLength( 5,
- and1.getChildren() );
+ assertLength( 1,
+ result );
+ assertLength( 4,
+ result[0].getChildren() );
assertContains( a,
- and1.getChildren() );
+ result[0].getChildren() );
assertContains( b,
- and1.getChildren() );
+ result[0].getChildren() );
assertContains( c,
- and1.getChildren() );
+ result[0].getChildren() );
assertContains( d,
- and1.getChildren() );
- assertContains( or,
- and1.getChildren() );
+ result[0].getChildren() );
}
@@ -316,29 +370,30 @@
* / | \
* And and Not
* / | \ / \ |
- * a And d e Or h
+ * a And d e Or i
* / \ / \
- * b Not f Exists
+ * b Not h Exists
* | |
* Not g
* |
* c
* </pre>
* <pre>
- * _/|\__
- * __/ | \___
- * / | \__
- * __/ | \__
- * / | \__
- * / | \__
- * | | \
- * And Or Not
- * / | | \ / \ |
- * a b d Not And And i
- * | / \ / |
- * Not e f e Exists
- * | |
- * c g
+ * Or
+ * _/ \__
+ * __/ \___
+ * / \__
+ * __/ \__
+ * / \__
+ * / \__
+ * | \
+ * And And
+ * /|||| \ \ /||| | \ \
+ * abdeh Not Not abde Not Not Exists
+ * | | | | |
+ * Not i Not i g
+ * | |
+ * c c
* </pre>
*
* @throws IOException
@@ -347,70 +402,52 @@
*
*
*/
- public void xTestProcessTree() throws IOException,
- ClassNotFoundException,
- InvalidPatternException {
+ public void testProcessTree() throws IOException,
+ ClassNotFoundException,
+ InvalidPatternException {
final String a = "a";
final String b = "b";
final String c = "c";
final String d = "d";
final String e = "e";
- final String f = "f";
+ //final String f = "f";
final String g = "g";
final String h = "h";
final String i = "i";
- final String j = "j";
- final String k = "notAssertObject";
+ //final String j = "j";
+ //final String k = "notAssertObject";
- final And and1 = new And();
- final And and2 = new And();
+ final GroupElement and1 = GroupElementFactory.newAndInstance();
+ final GroupElement and2 = GroupElementFactory.newAndInstance();
and1.addChild( a );
and1.addChild( and2 );
and2.addChild( b );
- final Not not1 = new Not();
- final Not not2 = new Not();
+ final GroupElement not1 = GroupElementFactory.newNotInstance();
+ final GroupElement not2 = GroupElementFactory.newNotInstance();
not1.addChild( not2 );
not2.addChild( c );
and2.addChild( not1 );
and1.addChild( d );
- final And and3 = new And();
+ final GroupElement and3 = GroupElementFactory.newAndInstance();
and3.addChild( e );
- final Or or1 = new Or();
+ final GroupElement or1 = GroupElementFactory.newOrInstance();
and3.addChild( or1 );
- final Exists exist1 = new Exists();
+ final GroupElement exist1 = GroupElementFactory.newExistsInstance();
exist1.addChild( g );
or1.addChild( exist1 );
or1.addChild( h );
- final Not not3 = new Not();
+ final GroupElement not3 = GroupElementFactory.newNotInstance();
not3.addChild( i );
- final And root = new And();
+ final GroupElement root = GroupElementFactory.newAndInstance();
root.addChild( and1 );
root.addChild( and3 );
root.addChild( not3 );
- LogicTransformer.getInstance().processTree( root );
+ GroupElement[] result = LogicTransformer.getInstance().transform( root );
- // --------------------------------------
- // Test that the treesEqual method works
- // --------------------------------------
-
- // Check against itself
- assertEquals( root,
- root );
-
- // Test against a known false tree
- final And testAnd1 = new And();
- testAnd1.addChild( a );
- testAnd1.addChild( b );
- final Or testOr2 = new Or();
- testOr2.addChild( c );
- testOr2.addChild( d );
- testAnd1.addChild( testOr2 );
- assertFalse( root.equals( testAnd1 ) );
-
// ----------------------------------------------------------------------------------
// Now construct the result tree so we can test root against what it
// should look like
@@ -421,17 +458,19 @@
// Uncomment this when you need to output a new known correct tree
// result
- // writeTree(root, "correct_processTree1.dat");
+ //writeTree(result, "correct_processTree1.dat");
final ObjectInputStream ois = new ObjectInputStream( this.getClass().getResourceAsStream( "/correct_processTree1.dat" ) );
- final And correctResultRoot = (And) ois.readObject();
+ final GroupElement[] correctResultRoot = (GroupElement[]) ois.readObject();
// Make sure they are equal
- assertEquals( correctResultRoot,
- root );
+ for ( int j = 0; j < correctResultRoot.length; j++ ) {
+ assertEquals( correctResultRoot[j],
+ result[j] );
+ }
}
- public void testCloneable() {
+ public void xxxtestCloneable() {
final String a = "a";
final String b = "b";
final String c = "c";
@@ -442,22 +481,22 @@
final String h = "h";
// Test against a known false tree
- final And and = new And();
+ final GroupElement and = GroupElementFactory.newAndInstance();
and.addChild( a );
and.addChild( b );
- final Or or = new Or();
+ final GroupElement or = GroupElementFactory.newOrInstance();
or.addChild( c );
or.addChild( d );
and.addChild( or );
- final And and2 = new And();
+ final GroupElement and2 = GroupElementFactory.newAndInstance();
and2.addChild( e );
and2.addChild( f );
or.addChild( and2 );
- final Not not = new Not();
+ final GroupElement not = GroupElementFactory.newNotInstance();
and.addChild( not );
- final Or or2 = new Or();
+ final GroupElement or2 = GroupElementFactory.newOrInstance();
not.addChild( or2 );
or2.addChild( g );
or2.addChild( h );
@@ -516,9 +555,9 @@
* @throws ClassNotFoundException
*
*/
- public void xTestTransform() throws IOException,
- ClassNotFoundException,
- InvalidPatternException {
+ public void xxxtestTransform() throws IOException,
+ ClassNotFoundException,
+ InvalidPatternException {
final String a = "a";
final String b = "b";
final String c = "c";
@@ -527,74 +566,48 @@
final String f = "f";
final String g = "g";
final String h = "h";
- final String i = "i";
- final And and = new And();
+ final GroupElement and = GroupElementFactory.newAndInstance();
- final And and1 = new And();
+ final GroupElement and1 = GroupElementFactory.newAndInstance();
and1.addChild( a );
- final Or or1 = new Or();
+ final GroupElement or1 = GroupElementFactory.newOrInstance();
or1.addChild( b );
or1.addChild( c );
and1.addChild( or1 );
and.addChild( and1 );
- final Or or2 = new Or();
+ final GroupElement or2 = GroupElementFactory.newOrInstance();
or2.addChild( d );
or2.addChild( e );
and.addChild( or2 );
- final And and2 = new And();
- final Not not1 = new Not();
+ final GroupElement and2 = GroupElementFactory.newAndInstance();
+ final GroupElement not1 = GroupElementFactory.newNotInstance();
not1.addChild( f );
- final Or or3 = new Or();
+ final GroupElement or3 = GroupElementFactory.newOrInstance();
or3.addChild( g );
- final Not not2 = new Not();
+ final GroupElement not2 = GroupElementFactory.newNotInstance();
not2.addChild( h );
or3.addChild( not2 );
- // ---------------------------------------
- // Check a simple case no just one branch
- // ---------------------------------------
- And[] ands = LogicTransformer.getInstance().transform( and1 );
- assertLength( 2,
- ands );
- assertTrue( ands[0] instanceof And );
- assertLength( 2,
- ands[0].getChildren() );
+ and2.addChild( not1 );
+ and2.addChild( or3 );
+ and.addChild( and2 );
- assertLength( 2,
- ands[0].getChildren() );
- assertEquals( And.class,
- ands[0].getClass() );
- assertEquals( And.class,
- ands[0].getClass() );
+ GroupElement[] ands = LogicTransformer.getInstance().transform( and );
- And newAnd = ands[0];
- assertContains( a,
- newAnd.getChildren() );
- assertContains( b,
- newAnd.getChildren() );
-
- newAnd = ands[1];
- assertContains( a,
- newAnd.getChildren() );
- assertContains( c,
- newAnd.getChildren() );
-
- ands = LogicTransformer.getInstance().transform( and );
-
// Uncomment this when you need to output a new known correct tree
// result
- // writeTree(ands, "correct_transform1.dat");
+ //writeTree(ands, "correct_transform1.dat");
// Now check the main tree
// Get known correct tree
// The binary stream was created from a handchecked correct output
final ObjectInputStream ois = new ObjectInputStream( this.getClass().getResourceAsStream( "/correct_transform1.dat" ) );
- final And[] correctResultAnds = (And[]) ois.readObject();
+ final GroupElement[] correctResultAnds = (GroupElement[]) ois.readObject();
for ( int j = 0; j < ands.length; j++ ) {
assertEquals( correctResultAnds[j],
Modified: labs/jbossrules/trunk/drools-core/src/test/resources/correct_processTree1.dat
===================================================================
(Binary files differ)
Modified: labs/jbossrules/trunk/drools-core/src/test/resources/correct_transform1.dat
===================================================================
(Binary files differ)
More information about the jboss-svn-commits
mailing list