[jboss-svn-commits] JBL Code SVN: r10987 - in labs/jbossrules/trunk/drools-core/src/main/java/org/drools: reteoo and 2 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Sun Apr 15 21:25:42 EDT 2007


Author: mark.proctor at jboss.com
Date: 2007-04-15 21:25:42 -0400 (Sun, 15 Apr 2007)
New Revision: 10987

Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaGroupImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaItem.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/PropagationContextImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/ScheduledAgendaItem.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TruthMaintenanceSystem.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Activation.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/AgendaGroup.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/PropagationContext.java
Log:
JBRULES-797 Modified object causes logical assertion to retract even though its still true

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaGroupImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaGroupImpl.java	2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaGroupImpl.java	2007-04-16 01:25:42 UTC (rev 10987)
@@ -84,7 +84,7 @@
         return (Activation) this.queue.dequeue();
     }
 
-    public boolean isActivate() {
+    public boolean isActive() {
         return this.active;
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaItem.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaItem.java	2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaItem.java	2007-04-16 01:25:42 UTC (rev 10987)
@@ -147,6 +147,10 @@
     public LinkedList getLogicalDependencies() {
         return this.justified;
     }
+    
+    public void setLogicalDependencies(LinkedList justified) {
+        this.justified = justified;
+    }
 
     public boolean isActivated() {
         return this.activated;

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/PropagationContextImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/PropagationContextImpl.java	2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/PropagationContextImpl.java	2007-04-16 01:25:42 UTC (rev 10987)
@@ -106,28 +106,30 @@
     }
 
     public void addRetractedTuple(final Rule rule,
-                                  final ReteTuple tuple) {
+                                  final Activation activation) {
         if ( this.retracted == null ) {
             this.retracted = new ObjectHashMap();
         }
+        
+        ReteTuple tuple = ( ReteTuple) activation.getTuple();
 
-        TupleHashTable tuples = (TupleHashTable) this.retracted.get( rule );
+        ObjectHashMap tuples = (ObjectHashMap) this.retracted.get( rule );
         if ( tuples == null ) {
-            tuples = new TupleHashTable();
+            tuples = new ObjectHashMap();
             this.retracted.put( rule,
                                 tuples );
         }
-        tuples.add( tuple );
+        tuples.put( tuple, activation );
     }
 
-    public ReteTuple removeRetractedTuple(final Rule rule,
+    public Activation removeRetractedTuple(final Rule rule,
                                           final ReteTuple tuple) {
         if ( this.retracted == null ) {
             return null;
         }
 
-        final TupleHashTable tuples = (TupleHashTable) this.retracted.get( rule );
-        return tuples.remove( tuple );
+        final ObjectHashMap tuples = (ObjectHashMap) this.retracted.get( rule );
+        return ( Activation ) tuples.remove( tuple );
     }
 
     public void clearRetractedTuples() {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/ScheduledAgendaItem.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/ScheduledAgendaItem.java	2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/ScheduledAgendaItem.java	2007-04-16 01:25:42 UTC (rev 10987)
@@ -230,4 +230,8 @@
     public GroupElement getSubRule() {
         return this.subrule;
     }
+
+    public void setLogicalDependencies(LinkedList justified) {
+        this.justified = justified;
+    }
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TruthMaintenanceSystem.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TruthMaintenanceSystem.java	2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TruthMaintenanceSystem.java	2007-04-16 01:25:42 UTC (rev 10987)
@@ -109,45 +109,110 @@
             final Set set = (Set) this.justifiedMap.get( handle.getId() );
             if ( set != null ) {
                 set.remove( node );
-                if ( set.isEmpty() ) {
-                    // this needs to be scheduled so we don't upset the current
-                    // working memory operation                    
-                    WorkingMemoryAction action = new LogicalRetractCallback( this, set, handle, context );
-                    workingMemory.queueWorkingMemoryAction( action );
-                }
+                WorkingMemoryAction action = new LogicalRetractCallback( this,
+                                                                         node,
+                                                                         set,
+                                                                         handle,
+                                                                         context );    
+                workingMemory.queueWorkingMemoryAction( action );
             }
+//            if ( set != null ) {
+//                set.remove( node );
+//                if ( set.isEmpty() ) {
+//                    // this needs to be scheduled so we don't upset the current
+//                    // working memory operation                    
+//                    WorkingMemoryAction action = new LogicalRetractCallback( this,
+//                                                                             node,
+//                                                                             set,
+//                                                                             handle,
+//                                                                             context );
+//                    workingMemory.queueWorkingMemoryAction( action );
+//
+//                    //                    this.justifiedMap.remove( handle.getId() );                    
+//                    //                    WorkingMemoryAction action = new WorkingMemoryRetractAction(handle,
+//                    //                                                                                false,
+//                    //                                                                                true,
+//                    //                                                                                context.getRuleOrigin(),
+//                    //                                                                                context.getActivationOrigin() );                    
+//                    //                    this.workingMemory.queueWorkingMemoryAction( action );                  
+//                }
+            }
         }
+    
+
+    public class WorkingMemoryRetractAction
+        implements
+        WorkingMemoryAction {
+        private InternalFactHandle factHandle;
+
+        private boolean            removeLogical;
+
+        private boolean            updateEqualsMap;
+
+        private Rule               ruleOrigin;
+
+        private Activation         activationOrigin;
+
+        public WorkingMemoryRetractAction(final InternalFactHandle factHandle,
+                                          final boolean removeLogical,
+                                          final boolean updateEqualsMap,
+                                          final Rule ruleOrigin,
+                                          final Activation activationOrigin) {
+            super();
+            this.factHandle = factHandle;
+            this.removeLogical = removeLogical;
+            this.updateEqualsMap = updateEqualsMap;
+            this.ruleOrigin = ruleOrigin;
+            this.activationOrigin = activationOrigin;
+        }
+
+        public void execute(InternalWorkingMemory workingMemory) {
+            workingMemory.retractObject( this.factHandle,
+                                         this.removeLogical,
+                                         this.updateEqualsMap,
+                                         this.ruleOrigin,
+                                         this.activationOrigin );
+        }
     }
 
-    
-    
-    public static class LogicalRetractCallback implements WorkingMemoryAction {
+    public static class LogicalRetractCallback
+        implements
+        WorkingMemoryAction {
         private final TruthMaintenanceSystem tms;
-        private final Set set;
-        private final InternalFactHandle handle;
-        private final PropagationContext context;
+        private final LogicalDependency node;
+        private final Set                    set;
+        private final InternalFactHandle     handle;
+        private final PropagationContext     context;
 
-        public LogicalRetractCallback(TruthMaintenanceSystem tms, Set set, InternalFactHandle handle, PropagationContext context) {
+        public LogicalRetractCallback(TruthMaintenanceSystem tms,
+                                      LogicalDependency node,
+                                      Set set,
+                                      InternalFactHandle handle,
+                                      PropagationContext context) {
             this.tms = tms;
+            this.node = node;
             this.set = set;
             this.handle = handle;
             this.context = context;
         }
 
         public void execute(InternalWorkingMemory workingMemory) {
-            if ( set.isEmpty() ) {
-                this.tms.getJustifiedMap().remove( handle.getId() );
-                // this needs to be scheduled so we don't upset the current
-                // working memory operation
-                workingMemory.retractObject( this.handle,
-                                             false,
-                                             true,
-                                             context.getRuleOrigin(),
-                                             context.getActivationOrigin() );
-            }
+
+                if ( set.isEmpty() ) {
+                    if ( set.isEmpty() ) {
+                        this.tms.getJustifiedMap().remove( handle.getId() );
+                        // this needs to be scheduled so we don't upset the current
+                        // working memory operation
+                        workingMemory.retractObject( this.handle,
+                                                     false,
+                                                     true,
+                                                     context.getRuleOrigin(),
+                                                     context.getActivationOrigin() );
+                    }
+                }
         }
-    }    
-    
+    }
+
     /**
      * The FactHandle is being removed from the system so remove any logical dependencies
      * between the  justified FactHandle and its justifiers. Removes the FactHandle key 
@@ -185,6 +250,8 @@
                                      final Rule rule) throws FactException {
         final LogicalDependency node = new LogicalDependency( activation,
                                                               handle );
+        activation.getRule().setHasLogicalDependency( true );
+        
         activation.addLogicalDependency( node );
         Set set = (Set) this.justifiedMap.get( handle.getId() );
         if ( set == null ) {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java	2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java	2007-04-16 01:25:42 UTC (rev 10987)
@@ -23,8 +23,10 @@
 import org.drools.common.AgendaItem;
 import org.drools.common.BaseNode;
 import org.drools.common.InternalAgenda;
+import org.drools.common.InternalFactHandle;
 import org.drools.common.InternalRuleFlowGroup;
 import org.drools.common.InternalWorkingMemory;
+import org.drools.common.LogicalDependency;
 import org.drools.common.NodeMemory;
 import org.drools.common.PropagationContextImpl;
 import org.drools.common.ScheduledAgendaItem;
@@ -37,6 +39,7 @@
 import org.drools.spi.PropagationContext;
 import org.drools.spi.RuleFlowGroup;
 import org.drools.util.Iterator;
+import org.drools.util.LinkedList;
 import org.drools.util.TupleHashTable;
 
 /**
@@ -234,33 +237,64 @@
                 // do not add the activation if the rule is "lock-on-active" and the AgendaGroup is active
                 // we must check the context to determine if its a new tuple or an exist re-activated tuple as part of the retract                
                 if ( context.getType() == PropagationContext.MODIFICATION ) {
-                    if ( this.rule.isLockOnActive() && agendaGroup.isActivate() && context.removeRetractedTuple( this.rule,
-                                                                                                                 tuple ) == null ) {
-                        // This rule is locked and active, do not allow new tuples to activate 
-                        return;
+                    if ( this.rule.isLockOnActive() && agendaGroup.isActive() ) {
+                        Activation justifier = context.removeRetractedTuple( this.rule,
+                                                                             tuple );
+                        if ( justifier == null ) {
+                            // This rule is locked and active, do not allow new tuples to activate 
+                            return;
+                        } else if ( this.rule.hasLogicalDependency() ) {
+                            copyLogicalDependencies( context,
+                                                     workingMemory,
+                                                     item,
+                                                     justifier );
+                        }
+                    } else if ( this.rule.hasLogicalDependency() ) {
+                        Activation justifier = context.removeRetractedTuple( this.rule,
+                                                                             tuple );
+                        copyLogicalDependencies( context,
+                                                 workingMemory,
+                                                 item,
+                                                 justifier );
                     }
-                } else if ( this.rule.isLockOnActive() && agendaGroup.isActivate() ) {
+                } else if ( this.rule.isLockOnActive() && agendaGroup.isActive() ) {
                     return;
                 }
 
                 agendaGroup.add( item );
             } else {
                 //There is  a RuleFlowNode so add it there, instead  of the Agenda
-
+                RuleFlowGroup rfg = memory.getRuleFlowGroup();
                 // Lazy cache ruleFlowGroup
-                if ( memory.getRuleFlowGroup() == null ) {
-                    memory.setRuleFlowGroup( workingMemory.getAgenda().getRuleFlowGroup( this.rule.getRuleFlowGroup() ) );
+                if ( rfg == null ) {
+                    rfg = workingMemory.getAgenda().getRuleFlowGroup( this.rule.getRuleFlowGroup() );
+                    memory.setRuleFlowGroup( rfg );
                 }
 
                 // do not add the activation if the rule is "lock-on-active" and the RuleFlowGroup is active
-                // we must check the context to determine if its a new tuple or an exist re-activated tuple as part of the retract 
+                // we must check the context to determine if its a new tuple or an exist re-activated tuple as part of the retract                
                 if ( context.getType() == PropagationContext.MODIFICATION ) {
-                    if ( this.rule.isLockOnActive() && memory.getRuleFlowGroup().isActive() && context.removeRetractedTuple( this.rule,
-                                                                                                                             tuple ) == null ) {
-                        // This rule is locked and active, do not allow new tuples to activate 
-                        return;
+                    if ( this.rule.isLockOnActive() && rfg.isActive() ) {
+                        Activation justifier = context.removeRetractedTuple( this.rule,
+                                                                             tuple );
+                        if ( justifier == null ) {
+                            // This rule is locked and active, do not allow new tuples to activate 
+                            return;
+                        } else if ( this.rule.hasLogicalDependency() ) {
+                            copyLogicalDependencies( context,
+                                                     workingMemory,
+                                                     item,
+                                                     justifier );
+                        }
+                    } else if ( this.rule.hasLogicalDependency() ) {
+                        Activation justifier = context.removeRetractedTuple( this.rule,
+                                                                             tuple );
+                        copyLogicalDependencies( context,
+                                                 workingMemory,
+                                                 item,
+                                                 justifier );
                     }
-                } else if ( this.rule.isLockOnActive() && memory.getRuleFlowGroup().isActive() ) {
+                } else if ( this.rule.isLockOnActive() && rfg.isActive() ) {
                     return;
                 }
 
@@ -283,6 +317,24 @@
         agenda.increaseActiveActivations();
     }
 
+    private void copyLogicalDependencies(final PropagationContext context,
+                                         final InternalWorkingMemory workingMemory,
+                                         final AgendaItem item,
+                                         Activation justifier) {
+        if ( justifier != null ) {
+            final LinkedList list = justifier.getLogicalDependencies();
+            if ( list != null && !list.isEmpty() ) {
+                for ( LogicalDependency node = (LogicalDependency) list.getFirst(); node != null; node = (LogicalDependency) node.getNext() ) {
+                    final InternalFactHandle handle = (InternalFactHandle) node.getFactHandle();
+                    workingMemory.getTruthMaintenanceSystem().addLogicalDependency( handle,
+                                                                                    item,
+                                                                                    context,
+                                                                                    this.rule );
+                }
+            }
+        }
+    }
+
     public void retractTuple(final ReteTuple leftTuple,
                              final PropagationContext context,
                              final InternalWorkingMemory workingMemory) {
@@ -295,10 +347,19 @@
         }
 
         final Activation activation = tuple.getActivation();
+        if ( activation.getLogicalDependencies() != null && !activation.getLogicalDependencies().isEmpty() ) {
+            context.addRetractedTuple( this.rule,
+                                       activation );
+        }
+
         if ( activation.isActivated() ) {
-            if ( this.rule.isLockOnActive() && context.getType() == PropagationContext.MODIFICATION ) {
-                context.addRetractedTuple( this.rule,
-                                           tuple );
+            if ( context.getType() == PropagationContext.MODIFICATION ) {
+                // during a modify if we have either isLockOnActive or the activation has logical dependencies
+                // then we need to track retractions, so we know which are exising activations and which are truly new
+                if ( this.rule.isLockOnActive() ) {
+                    context.addRetractedTuple( this.rule,
+                                               activation );
+                }
             }
 
             activation.remove();
@@ -309,7 +370,8 @@
 
             if ( activation.getRuleFlowGroupNode() != null ) {
                 final InternalRuleFlowGroup ruleFlowGroup = activation.getRuleFlowGroupNode().getRuleFlowGroup();
-                ruleFlowGroup.removeActivation( activation, workingMemory );
+                ruleFlowGroup.removeActivation( activation,
+                                                workingMemory );
             }
 
             workingMemory.getAgendaEventSupport().fireActivationCancelled( activation,

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	2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java	2007-04-16 01:25:42 UTC (rev 10987)
@@ -88,6 +88,8 @@
     private String            ruleFlowGroup;
 
     private boolean           lockOnActive;
+    
+    private boolean           hasLogicalDependency;
 
     /** indicates that the rule is semantically correct. */
     private boolean           semanticallyValid;
@@ -323,6 +325,14 @@
         return (Declaration) this.declarations.get( identifier );
     }
 
+    public boolean hasLogicalDependency() {
+        return this.hasLogicalDependency;
+    }
+    
+    public void setHasLogicalDependency(boolean hasLogicalDependency) {
+        this.hasLogicalDependency = hasLogicalDependency;
+    }
+    
     public boolean isLockOnActive() {
         return this.lockOnActive;
     }
@@ -330,7 +340,7 @@
     public void setLockOnActive(final boolean lockOnActive) {
         this.lockOnActive = lockOnActive;
     }
-
+    
     /**
      * Retrieve the set of all <i>root fact object </i> parameter
      * <code>Declarations</code>.

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Activation.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Activation.java	2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Activation.java	2007-04-16 01:25:42 UTC (rev 10987)
@@ -80,6 +80,8 @@
     public void addLogicalDependency(LogicalDependency node);
 
     public LinkedList getLogicalDependencies();
+    
+    public void setLogicalDependencies(LinkedList justified);
 
     public boolean isActivated();
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/AgendaGroup.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/AgendaGroup.java	2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/AgendaGroup.java	2007-04-16 01:25:42 UTC (rev 10987)
@@ -57,6 +57,6 @@
      */
     public int size();
 
-    public boolean isActivate();
+    public boolean isActive();
 
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/PropagationContext.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/PropagationContext.java	2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/PropagationContext.java	2007-04-16 01:25:42 UTC (rev 10987)
@@ -43,10 +43,10 @@
     public int getDormantActivations();
 
     public void addRetractedTuple(Rule rule,
-                                  ReteTuple tuple);
+                                  Activation activation);
 
-    public ReteTuple removeRetractedTuple(Rule rule,
-                                          ReteTuple tuple);
+    public Activation removeRetractedTuple(Rule rule,
+                                           ReteTuple tuple);
 
     public void clearRetractedTuples();
 




More information about the jboss-svn-commits mailing list