Added minimum size analysis.
[repair.git] / Repair / RepairCompiler / MCC / IR / GraphAnalysis.java
index 878f9392c108b68140434479ca871e6a54a6c042..6b690a859c4da45ee161c5a48367f63daf65bc20 100755 (executable)
@@ -15,68 +15,98 @@ public class GraphAnalysis {
     public GraphAnalysis(Termination t) {
        termination=t;
     }
-    /**  This method returns true if leaving node gn in the repair
-     *  dependence graph will not result in cycles.
-     gn = updatenode, conjunctionnode, consequence node
-    */
+
     private boolean safetransclosure(GraphNode gn, Set removed, Set cantremove, Set couldremove) {
        Stack workset=new Stack();
        HashSet closureset=new HashSet();
        boolean needcyclecheck=false;
-       HashSet cantremovetrans=new HashSet();
-       workset.push(gn);
+       HashSet dependent=new HashSet();
 
-       /* Iterating over everything reachable from gn */
+       /* Compute dependent set */
+       workset.push(gn);
        while(!workset.empty()) {
            GraphNode gn2=(GraphNode)workset.pop();
+           for(Iterator edgeit=gn2.edges();edgeit.hasNext();) {
+               GraphNode gn3=((GraphNode.Edge)edgeit.next()).getTarget();
+               if (removed.contains(gn3))
+                   continue;
+               if (!termination.conjunctions.contains(gn3)&&!dependent.contains(gn3)) {
+                   dependent.add(gn3);
+                   workset.push(gn3);
+               }
+           }
+       }
 
-           /* Closureset is everything we've already iterated over */
+       /* Compute the closure set */
+       workset.push(gn);
+       while(!workset.empty()) {
+           GraphNode gn2=(GraphNode)workset.pop();
            if (!closureset.contains(gn2)) {
                closureset.add(gn2);
-               boolean goodoption=false;
                for(Iterator edgeit=gn2.edges();edgeit.hasNext();) {
                    GraphNode gn3=((GraphNode.Edge)edgeit.next()).getTarget();
                    if (removed.contains(gn3))
                        continue;
-
-                   /* Consider only the nodes in the graph */
-
-                   
-                   if (((cantremove.contains(gn2)||!couldremove.contains(gn2))
-                        &&termination.conjunctions.contains(gn2))||
-                       cantremovetrans.contains(gn2))
-                       cantremovetrans.add(gn3);
-
-                   if (termination.abstractrepair.contains(gn3)||
-                       termination.conjunctions.contains(gn3)||
-                       termination.updatenodes.contains(gn3)) {
-                       /**  Check for cycles if the graphnode can't
-                        * be removed (we know we aren't introducing
-                        * new things to repair). */
-                       if ((!termination.abstractrepair.contains(gn3)&&
-                            cantremove.contains(gn3))||
-                           cantremovetrans.contains(gn3)) {
-                           needcyclecheck=true;
-                       } else return false;
-                   }
-                   if ((!couldremove.contains(gn3))||cantremove.contains(gn3))
-                       goodoption=true;
                    workset.push(gn3);
                }
-               if (!goodoption) {
-                   if (termination.scopenodes.contains(gn2))
-                       return false;
-               }
            }
        }
-       if (needcyclecheck) {
-           Set cycles=GraphNode.findcycles(closureset);
-           for(Iterator it=cycles.iterator();it.hasNext();) {
-               GraphNode gn2=(GraphNode)it.next();
-               if (termination.abstractrepair.contains(gn2)||
-                   termination.conjunctions.contains(gn2)||
-                   termination.updatenodes.contains(gn2))
-                   return false;
+
+       /* Check for harmful cycles through gn */
+       Set cycles=GraphNode.findcycles(closureset);
+       if (cycles.contains(gn))
+           return false;
+
+       /* Check for harmful cycles being introduced in dependent nodes */
+       cycles=GraphNode.findcycles(dependent);
+       for(Iterator it=cycles.iterator();it.hasNext();) {
+           GraphNode gn2=(GraphNode)it.next();
+           if (termination.abstractrepair.contains(gn2)||
+               termination.conjunctions.contains(gn2)||
+               termination.updatenodes.contains(gn2))
+               return false;
+       }
+
+       /* Make sure all abstractrepairs/consequence nodes in the dependent nodes
+          are well formed. */
+    outerloop:
+       for(Iterator it=dependent.iterator();it.hasNext();) {
+           GraphNode gn2=(GraphNode)it.next();
+           if (termination.abstractrepair.contains(gn2)||
+               termination.scopenodes.contains(gn2)) {
+               boolean ismodify=false;
+               int numadd=0;
+               int numremove=0;
+
+               if (termination.abstractrepair.contains(gn2)&&
+                   ((TermNode)gn2.getOwner()).getAbstract().getType()==AbstractRepair.MODIFYRELATION)
+                   ismodify=true;
+
+               innerloop:
+               for(Iterator edgeit=gn2.edges();edgeit.hasNext();) {
+                   GraphNode gn3=((GraphNode.Edge)edgeit.next()).getTarget();
+                   if (removed.contains(gn3))
+                       continue innerloop;
+                   if (cantremove.contains(gn3)||
+                       !couldremove.contains(gn3)) {
+                       if (ismodify) {
+                           TermNode tn3=(TermNode)gn3.getOwner();
+                           MultUpdateNode mun=tn3.getUpdate();
+                           if (mun.getType()==MultUpdateNode.ADD)
+                               numadd++;
+                           if (mun.getType()==MultUpdateNode.REMOVE)
+                               numremove++;
+                           if (mun.getType()==MultUpdateNode.MODIFY)
+                               continue outerloop;
+                           if ((numadd>0)&&(numremove>0||!((TermNode)gn2.getOwner()).getAbstract().needsRemoves(termination.state)))
+                               continue outerloop;
+                       } else
+                           if (termination.consequence.contains(gn3)||
+                               termination.updatenodes.contains(gn3))
+                               continue outerloop;
+                   }
+               }
+               return false;
            }
        }
        return true;
@@ -324,9 +354,10 @@ public class GraphAnalysis {
            /* Searches individual conjunctions + abstract action +updates for cycles */
            for(Iterator it=termination.conjunctions.iterator();it.hasNext();) {
                GraphNode gn=(GraphNode)it.next();
-               boolean foundnocycle=false;
-               
+
                for (Iterator edgeit=gn.edges();edgeit.hasNext();) {
+                    boolean foundnocycle=false;
+
                    GraphNode.Edge e=(GraphNode.Edge)edgeit.next();
                    GraphNode gn2=e.getTarget();
                    TermNode tn2=(TermNode)gn2.getOwner();
@@ -335,14 +366,14 @@ public class GraphAnalysis {
                    AbstractRepair ar=tn2.getAbstract();
                    boolean ismodify=ar.getType()==AbstractRepair.MODIFYRELATION;
                    int numadd=0;int numremove=0;
-                   
+
                    for (Iterator edgeit2=gn2.edges();edgeit2.hasNext();) {
                        GraphNode.Edge e2=(GraphNode.Edge)edgeit2.next();
                        GraphNode gn3=e2.getTarget();
                        TermNode tn3=(TermNode)gn3.getOwner();
                        if (tn3.getType()!=TermNode.UPDATE)
                            continue;
-                       
+
                        boolean containsgn=cantremove.contains(gn);
                        boolean containsgn2=cantremove.contains(gn2);
                        boolean containsgn3=cantremove.contains(gn3);
@@ -387,14 +418,15 @@ public class GraphAnalysis {
                                mustremove.add(gn3);
                        }
                    }
-               }
 
-               if(!foundnocycle) {
-                   if (!mustremove.contains(gn)) {
-                       change=true;
-                       mustremove.add(gn);
-                   }
-               }
+
+                    if(!foundnocycle) {
+                        if (!mustremove.contains(gn)) {
+                            change=true;
+                            mustremove.add(gn);
+                        }
+                    }
+                }
            }
 
            /* Searches scope nodes + compensation nodes */
@@ -420,7 +452,7 @@ public class GraphAnalysis {
                                change=true;
                                mustremove.add(gn2);
                            }
-                       } 
+                       }
                        if (!containsgn)
                            cantremove.remove(gn);
                        if (!containsgn2)