Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

SCCReduction.java

00001 package gov.nasa.arc.ase.util.graph;
00002 
00003 import java.io.*;
00004 import java.util.BitSet;
00005 //#ifdef JDK11
00006 
00007 
00008 //#else JDK11
00009 import java.util.List;
00010 import java.util.Iterator;
00011 //#endif JDK11
00012 
00013 public class SCCReduction {
00014   private static boolean anyAcceptingState(List scc, Graph g) {
00015     String type = g.getStringAttribute("type");
00016     String ac = g.getStringAttribute("ac");
00017 
00018     if(type.equals("ba")) {
00019       if(ac.equals("nodes")) {
00020     for(Iterator i = scc.iterator(); i.hasNext(); ) {
00021       Node n = (Node)i.next();
00022 
00023       if(n.getBooleanAttribute("accepting"))
00024         return true;
00025     }
00026       } else if(ac.equals("edges")) {
00027     for(Iterator i = scc.iterator(); i.hasNext(); ) {
00028       Node n = (Node)i.next();
00029 
00030       for(Iterator j = n.getOutgoingEdges().iterator(); j.hasNext(); ) {
00031         Edge e = (Edge)j.next();
00032 
00033         if(e.getBooleanAttribute("accepting"))
00034           return true;
00035       }
00036     }
00037       } else
00038     throw new RuntimeException("invalid accepting type: " + ac);
00039     } else if(type.equals("gba")) {
00040       int nsets = g.getIntAttribute("nsets");
00041 
00042       if(ac.equals("nodes")) {
00043     for(Iterator i = scc.iterator(); i.hasNext(); ) {
00044       Node n = (Node)i.next();
00045 
00046       for(int j = 0; j < nsets; j++)
00047         if(n.getBooleanAttribute("acc"+j))
00048           return true;
00049     }
00050       } else if(ac.equals("edges")) {
00051     for(Iterator i = scc.iterator(); i.hasNext(); ) {
00052       Node n = (Node)i.next();
00053 
00054       for(Iterator j = n.getOutgoingEdges().iterator(); j.hasNext(); ) {
00055         Edge e = (Edge)j.next();
00056 
00057         for(int k = 0; k < nsets; k++)
00058           if(e.getBooleanAttribute("acc"+j))
00059         return true;
00060       }
00061     }
00062       } else
00063     throw new RuntimeException("invalid accepting type: " + ac);
00064     } else
00065       throw new RuntimeException("invalid graph type: " + type);
00066 
00067     return false;
00068   }  
00069   private static void clearAccepting(List scc, Graph g) {
00070     String type = g.getStringAttribute("type");
00071     String ac = g.getStringAttribute("ac");
00072 
00073     if(type.equals("ba")) {
00074       if(ac.equals("nodes")) {
00075     for(Iterator i = scc.iterator(); i.hasNext(); ) {
00076       Node n = (Node)i.next();
00077 
00078       n.setBooleanAttribute("accepting", false);
00079     }
00080       } else if(ac.equals("edges")) {
00081     for(Iterator i = scc.iterator(); i.hasNext(); ) {
00082       Node n = (Node)i.next();
00083 
00084       for(Iterator j = n.getOutgoingEdges().iterator(); j.hasNext(); ) {
00085         Edge e = (Edge)j.next();
00086 
00087         e.setBooleanAttribute("accepting", false);
00088       }
00089     }
00090       } else
00091     throw new RuntimeException("invalid accepting type: " + ac);
00092     } else if(type.equals("gba")) {
00093       int nsets = g.getIntAttribute("nsets");
00094 
00095       if(ac.equals("nodes")) {
00096     for(Iterator i = scc.iterator(); i.hasNext(); ) {
00097       Node n = (Node)i.next();
00098 
00099       for(int j = 0; j < nsets; j++)
00100         n.setBooleanAttribute("acc"+j, false);
00101     }
00102       } else if(ac.equals("edges")) {
00103     for(Iterator i = scc.iterator(); i.hasNext(); ) {
00104       Node n = (Node)i.next();
00105 
00106       for(Iterator j = n.getOutgoingEdges().iterator(); j.hasNext(); ) {
00107         Edge e = (Edge)j.next();
00108 
00109         for(int k = 0; k < nsets; k++)
00110           e.setBooleanAttribute("acc"+k, false);
00111       }
00112     }
00113       } else
00114     throw new RuntimeException("invalid accepting type: " + ac);
00115     } else
00116       throw new RuntimeException("invalid graph type: " + type);
00117   }  
00118   private static void clearExternalEdges(List scc, Graph g) {
00119     String type = g.getStringAttribute("type");
00120     String ac = g.getStringAttribute("ac");
00121 
00122     if(type.equals("ba")) {
00123       if(ac.equals("nodes")) {
00124       } else if(ac.equals("edges")) {
00125     for(Iterator i = scc.iterator(); i.hasNext(); ) {
00126       Node n = (Node)i.next();
00127 
00128       for(Iterator j = n.getOutgoingEdges().iterator(); j.hasNext(); ) {
00129         Edge e = (Edge)j.next();
00130 
00131         if(!scc.contains(e.getNext()))
00132           e.setBooleanAttribute("accepting", false);
00133       }
00134     }
00135       } else
00136     throw new RuntimeException("invalid accepting type: " + ac);
00137     } else if(type.equals("gba")) {
00138       int nsets = g.getIntAttribute("nsets");
00139 
00140       if(ac.equals("nodes")) {
00141       } else if(ac.equals("edges")) {
00142     for(Iterator i = scc.iterator(); i.hasNext(); ) {
00143       Node n = (Node)i.next();
00144 
00145       for(Iterator j = n.getOutgoingEdges().iterator(); j.hasNext(); ) {
00146         Edge e = (Edge)j.next();
00147 
00148         if(!scc.contains(e.getNext()))
00149           for(int k = 0; k < nsets; k++)
00150         e.setBooleanAttribute("acc"+k, false);
00151       }
00152     }
00153       } else
00154     throw new RuntimeException("invalid accepting type: " + ac);
00155     } else
00156       throw new RuntimeException("invalid graph type: " + type);
00157   }  
00158   private static boolean isAccepting(List scc, Graph g) {
00159     String type = g.getStringAttribute("type");
00160     String ac = g.getStringAttribute("ac");
00161 
00162     if(type.equals("ba")) {
00163       if(ac.equals("nodes")) {
00164     for(Iterator i = scc.iterator(); i.hasNext(); )
00165       if(((Node)i.next()).getBooleanAttribute("accepting"))
00166         return true;
00167 
00168     return false;
00169       } else if(ac.equals("edges")) {
00170     for(Iterator i = scc.iterator(); i.hasNext(); ) {
00171       Node n = (Node)i.next();
00172 
00173       for(Iterator j = n.getOutgoingEdges().iterator(); j.hasNext(); ) {
00174         Edge e = (Edge)j.next();
00175 
00176         if(e.getBooleanAttribute("accepting"))
00177           return true;
00178       }
00179     }
00180 
00181     return false;
00182       } else
00183     throw new RuntimeException("invalid accepting type: " + ac);
00184     } else if(type.equals("gba")) {
00185       int nsets = g.getIntAttribute("nsets");
00186       BitSet found = new BitSet(nsets);
00187       int nsccs = 0;
00188 
00189       if(ac.equals("nodes")) {
00190     for(Iterator i = scc.iterator(); i.hasNext(); ) {
00191       Node n = (Node)i.next();
00192 
00193       for(int j = 0; j < nsets; j++) {
00194         if(n.getBooleanAttribute("acc"+j))
00195           if(!found.get(j)) {
00196         found.set(j);
00197         nsccs++;
00198           }
00199       }
00200     }
00201       } else if(ac.equals("edges")) {
00202     for(Iterator i = scc.iterator(); i.hasNext(); ) {
00203       Node n = (Node)i.next();
00204 
00205       for(Iterator j = n.getOutgoingEdges().iterator(); j.hasNext(); ) {
00206         Edge e = (Edge)j.next();
00207 
00208         for(int k = 0; k < nsets; k++) {
00209           if(e.getBooleanAttribute("acc"+k))
00210         if(!found.get(k)) {
00211           found.set(k);
00212           nsccs++;
00213         }
00214         }
00215       }
00216     }
00217       } else
00218     throw new RuntimeException("invalid accepting type: " + ac);
00219 
00220       return nsccs == nsets;
00221     } else
00222       throw new RuntimeException("invalid graph type: " + type);
00223   }  
00224   private static boolean isTerminal(List scc) {
00225     for(Iterator i = scc.iterator(); i.hasNext(); ) {
00226       Node n = (Node)i.next();
00227 
00228       for(Iterator j = n.getOutgoingEdges().iterator(); j.hasNext(); )
00229     if(!scc.contains(((Edge)j.next()).getNext()))
00230       return false;
00231     }
00232 
00233     return true;
00234   }  
00235   private static boolean isTransient(List scc) {
00236     if(scc.size() != 1) return false;
00237 
00238     Node n = (Node)scc.get(0);
00239     for(Iterator i = n.getOutgoingEdges().iterator();
00240     i.hasNext(); )
00241       if(((Edge)i.next()).getNext() == n) return false;
00242 
00243     return true;
00244   }  
00245   public static void main(String[] args) {
00246     if(args.length > 1) {
00247       System.out.println("usage:");
00248       System.out.println("\tjava gov.nasa.arc.ase.util.graph.SCCReduction [<filename>]");
00249       return;
00250     }
00251 
00252     Graph g = null;
00253 
00254     try {
00255       if(args.length == 0)
00256     g = Graph.load();
00257       else
00258     g = Graph.load(args[0]);
00259     } catch(IOException e) {
00260       System.out.println("Can't load the graph.");
00261       return;
00262     }
00263 
00264     g = reduce(g);
00265 
00266     g.save();
00267   }  
00268   public static Graph reduce(Graph g) {
00269     boolean changed;
00270     String type = g.getStringAttribute("type");
00271     String ac = g.getStringAttribute("ac");
00272     boolean acNodes = ac.equals("nodes");
00273 
00274     for(Iterator i = SCC.scc(g).iterator(); i.hasNext(); )
00275       clearExternalEdges((List)i.next(), g);
00276 
00277     do {
00278       changed = false;
00279 
00280       List sccs = SCC.scc(g);
00281 
00282       for(Iterator i = sccs.iterator(); i.hasNext(); ) {
00283     List scc = (List)i.next();
00284     boolean accepting = isAccepting(scc, g);
00285 
00286 
00287     if(!accepting && isTerminal(scc)) {
00288       changed = true;
00289 
00290       for(Iterator j = scc.iterator(); j.hasNext(); )
00291         ((Node)j.next()).remove();
00292     } else if(isTransient(scc) || !accepting) {
00293       changed |= anyAcceptingState(scc, g);
00294       clearAccepting(scc, g);
00295     }
00296       }
00297     } while(changed);
00298 
00299     return g;
00300   }  
00301 }

Generated at Thu Feb 7 06:54:30 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001