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

SFSReduction.java

00001 package gov.nasa.arc.ase.util.graph;
00002 
00003 import java.io.*;
00004 import java.util.TreeSet;
00005 import java.util.List;
00006 import java.util.LinkedList;
00007 import java.util.Iterator;
00008 import java.util.Set;
00009 import java.util.TreeSet;
00010 import java.util.StringTokenizer;
00011 import java.util.Vector;
00012 
00013 
00014 public class SFSReduction {
00015   private static TreeSet getPrevN(Node currNode, boolean prevPO[][]) {
00016     List edges = currNode.getOutgoingEdges();
00017     LinkedList neighbors = new LinkedList();
00018     ITypeNeighbor iNeigh;
00019     TreeSet prevN = new TreeSet();
00020 
00021 
00022     for (Iterator i = edges.iterator(); i.hasNext();) {
00023       Edge currEdge = (Edge)i.next();
00024       iNeigh = new ITypeNeighbor(currEdge.getNext().
00025                                  getIntAttribute("_prevColor"),
00026                                  currEdge.getGuard());
00027       neighbors.add(iNeigh);
00028     }
00029     
00030     // No neighbors present
00031     if (neighbors.size() == 0)
00032       return prevN;
00033 
00034 
00035     // Get the first of the list. Remove it from the list. Compare
00036     // this element with the rest of the list. If element subsumes
00037     // something in remainder of list remove that thing from list. If
00038     // element is subsumed, throw element away, else put element in
00039     // set
00040     boolean useless;
00041     do {
00042       useless = false;
00043       iNeigh = (ITypeNeighbor)neighbors.removeFirst();
00044       for (Iterator i = neighbors.iterator(); i.hasNext();) {
00045         ITypeNeighbor nNeigh = (ITypeNeighbor)i.next();
00046         ITypeNeighbor dominating = iDominates(iNeigh, nNeigh, prevPO);
00047         if (dominating == iNeigh) 
00048           i.remove();
00049         if (dominating == nNeigh) {
00050           useless = true;
00051           break;
00052         }
00053       }
00054       if (!useless)  
00055         prevN.add(iNeigh);
00056     } while (neighbors.size() > 0);
00057 
00058 
00059     return prevN;
00060   }  
00061   /** Returns the neighbor that dominates. If none dominates the
00062    * other, then returns null
00063    */
00064   private static ITypeNeighbor iDominates(ITypeNeighbor iNeigh,
00065                                           ITypeNeighbor nNeigh,
00066                                           boolean prevPO[][]) {
00067     String iTerm = iNeigh.getTransition();
00068     String nTerm = nNeigh.getTransition();
00069     int iColor = iNeigh.getColor();
00070     int nColor = nNeigh.getColor();
00071     String theSubterm = subterm(iTerm, nTerm);
00072     if (theSubterm == iTerm) {
00073       if (prevPO[nColor-1][iColor-1]) {
00074         // iNeigh i-dominates nNeigh
00075         return iNeigh;
00076       } else {
00077         return null;
00078       }
00079     } 
00080     if (theSubterm == nTerm) {
00081       if (prevPO[iColor-1][nColor-1]) {
00082         // nNeigh i-dominates iNeigh
00083         return nNeigh;
00084       } else {
00085         return null;
00086       }
00087     } 
00088     if (theSubterm.equals("true")) {
00089       if (prevPO[nColor-1][iColor-1])
00090         // iNeigh i-dominates nNeigh
00091         return iNeigh;
00092       else if (prevPO[iColor-1][nColor-1]) 
00093         // nNeigh i-dominates iNeigh
00094         return nNeigh;
00095     } 
00096     return null;
00097   }  
00098   private static boolean iDominateSet(TreeSet setOne, TreeSet setTwo,
00099                                       boolean prevPO[][]) {
00100     TreeSet working = new TreeSet(setTwo);
00101     for (Iterator i = working.iterator(); i.hasNext();) {
00102       ITypeNeighbor neighTwo = (ITypeNeighbor)i.next();
00103       for (Iterator j = setOne.iterator(); j.hasNext();) {
00104         ITypeNeighbor neighOne = (ITypeNeighbor)j.next();
00105         ITypeNeighbor dominating = iDominates(neighOne, neighTwo, prevPO);
00106         if (dominating == neighOne) {
00107           i.remove();
00108           break;
00109         }
00110       }
00111     }
00112     if (working.size() == 0)
00113       return true;
00114 
00115 
00116     return false;
00117   }  
00118   private static boolean isAccepting(Node nodeIn) {
00119     return (nodeIn.getBooleanAttribute("accepting"));
00120   }  
00121   public static void main(String[] args) {
00122     if(args.length > 1) {
00123       System.out.println("usage:");
00124       System.out.println("\tjava gov.nasa.arc.ase.util.graph.SFSReduction [<filename>]");
00125       return;
00126     }
00127 
00128 
00129     Graph g = null;
00130 
00131 
00132     try {
00133       if(args.length == 0)
00134         g = Graph.load();
00135       else
00136         g = Graph.load(args[0]);
00137     } catch(IOException e) {
00138       System.out.println("Can't load the graph.");
00139       return;
00140     }
00141 
00142 
00143 
00144     Graph reduced = reduce(g);
00145 
00146 
00147     reduced.save();
00148   }  
00149   private static Graph reachabilityGraph(Graph g) {
00150     Vector work = new Vector();
00151     Vector reachable = new Vector();
00152     work.add(g.getInit());
00153     while(!work.isEmpty()) {
00154       Node currNode = (Node)work.firstElement();
00155       reachable.add(currNode);
00156       if (currNode != null) {
00157         List outgoingEdges = currNode.getOutgoingEdges();
00158         for (Iterator i=outgoingEdges.iterator();i.hasNext();) {
00159           Edge currEdge = (Edge)i.next();
00160           Node nextNode = (Node)currEdge.getNext();
00161           if (!(work.contains(nextNode) || reachable.contains(nextNode)))
00162             work.add(nextNode);
00163         }
00164       } 
00165       if (work.remove(0) != currNode)
00166         System.out.println("ERROR"); // should probably throw exception
00167     }
00168     List nodes = g.getNodes();
00169     if (nodes != null) {
00170       for (Iterator i=nodes.iterator();i.hasNext();) {
00171         Node n = (Node)i.next();
00172         if (!reachable.contains(n))
00173           g.removeNode(n);
00174       }
00175     }
00176     return g;
00177   }  
00178   public static Graph reduce(Graph g) {
00179 
00180 
00181     int currNumColors;
00182     int prevNumColors = 1;
00183     int currNumPO = 4;
00184     int prevNumPO = prevNumColors;
00185     TreeSet newColorSet = null;
00186     LinkedList newColorList = null;
00187     boolean accepting = false;
00188     boolean nonaccepting = false;
00189 
00190 
00191     // Initialization
00192     List nodes = g.getNodes();
00193     for (Iterator i = nodes.iterator(); i.hasNext();) {
00194       Node currNode = (Node)i.next();
00195       currNode.setIntAttribute("_prevColor", 1);
00196       if (isAccepting(currNode)) {
00197         currNode.setIntAttribute("_currColor", 1);
00198         accepting = true;
00199       }
00200       else {
00201         currNode.setIntAttribute("_currColor", 2);
00202         nonaccepting = true;
00203       }
00204     }
00205     if (accepting && nonaccepting) 
00206       currNumColors = 2;
00207     else
00208       currNumColors = 1;
00209     // po(i, j)
00210     boolean currPO[][] = new boolean[2][2];
00211     boolean prevPO[][];
00212     for (int i=0; i<2; i++) {
00213       for (int j=0; j<2; j++) {
00214         if (i >= j)
00215           currPO[i][j] = true;
00216         else
00217           currPO[i][j] = false;
00218       }
00219     }
00220 
00221 
00222     while ((currNumColors != prevNumColors) || (currNumPO != prevNumPO)) {
00223       // Incrementing i, equiv. current values become previous ones
00224       for (Iterator i = nodes.iterator(); i.hasNext();) {
00225         Node currNode = (Node)i.next();
00226         currNode.setIntAttribute("_prevColor", 
00227                                  currNode.getIntAttribute("_currColor"));
00228       } 
00229       prevPO = currPO;
00230       prevNumColors = currNumColors;
00231 
00232 
00233       // Getting the new color pairs
00234       newColorList = new LinkedList();
00235       newColorSet = new TreeSet();
00236       for (Iterator i = nodes.iterator(); i.hasNext();) {
00237         Node currNode = (Node)i.next();
00238         ColorPair currPair = 
00239           new ColorPair(currNode.getIntAttribute("_prevColor"),
00240                         getPrevN(currNode, prevPO));
00241         newColorList.add(new Pair(currNode.getId(), currPair));
00242         newColorSet.add(currPair);
00243       }
00244       currNumColors = newColorSet.size();
00245       
00246       if (prevNumColors == currNumColors)
00247         break;
00248 
00249 
00250       // Convert the set into a linked list so that rank of object is known
00251       LinkedList ordered = new LinkedList();
00252       for (Iterator i = newColorSet.iterator(); i.hasNext();) {
00253         ColorPair currPair = (ColorPair)i.next();
00254         ordered.add(currPair);
00255       }
00256 
00257 
00258       // Renaming color set
00259       for (Iterator i = newColorList.iterator(); i.hasNext();) {
00260         Pair cPair = (Pair)i.next();
00261         ColorPair currPair = (ColorPair)cPair.getElement();
00262         g.getNode(cPair.getValue()).setIntAttribute("_currColor",
00263                                                     ordered.indexOf(currPair) + 1);
00264       }
00265       
00266       // Update partial order
00267       currPO = new boolean[currNumColors][currNumColors];
00268       for (Iterator i = newColorList.iterator(); i.hasNext();) {
00269         ColorPair currPairOne = (ColorPair)((Pair)i.next()).getElement();
00270         for(Iterator j = newColorList.iterator(); j.hasNext();) {
00271           ColorPair currPairTwo = (ColorPair)((Pair)j.next()).getElement();
00272           boolean po = prevPO[currPairTwo.getColor()-1][currPairOne.getColor()-1];
00273           boolean dominate = iDominateSet(currPairOne.getIMaxSet(),
00274                                           currPairTwo.getIMaxSet(), prevPO);
00275           if (po && dominate ) {
00276             currPO[ordered.indexOf(currPairTwo)][ordered.indexOf(currPairOne)]
00277               = true;
00278           }
00279           else
00280             currPO[ordered.indexOf(currPairTwo)][ordered.indexOf(currPairOne)]
00281               = false;
00282         }
00283       } 
00284     }
00285 
00286 
00287     // Create new graph
00288     Graph result;
00289     if (newColorList == null)
00290       result = g;
00291 
00292 
00293     else {
00294 
00295 
00296       result = new Graph();
00297       Node newNodes[] = new Node[currNumColors];
00298       for (int i=0; i< currNumColors; i++) {
00299         Node n = new Node(result);
00300         newNodes[i] = n;
00301       }
00302 
00303 
00304       for (Iterator i = newColorList.iterator();i.hasNext();) {
00305         Pair nodePair = (Pair)i.next();
00306         int origNodeId = nodePair.getValue();
00307         ColorPair colPair = (ColorPair)nodePair.getElement();
00308 
00309 
00310         if (newColorSet.contains(colPair)) {
00311           newColorSet.remove(colPair);
00312           TreeSet pairSet = (TreeSet)colPair.getIMaxSet();
00313           int color = colPair.getColor();
00314           Node currNode = newNodes[color-1];
00315           
00316           for (Iterator j = pairSet.iterator(); j.hasNext();) {
00317             ITypeNeighbor neigh = (ITypeNeighbor)j.next();
00318             int neighPos = neigh.getColor()-1;
00319             Edge currEdge = new Edge(currNode, newNodes[neighPos], neigh.getTransition());
00320           }
00321           // starting node
00322           if (g.getInit().getId() == origNodeId) 
00323             result.setInit(currNode);
00324 
00325 
00326           // accepting node
00327           if (isAccepting(g.getNode(origNodeId)))
00328             currNode.setBooleanAttribute("accepting", true);
00329 
00330 
00331         }
00332       }
00333     } 
00334     return reachabilityGraph(result);
00335     //return result;
00336   }  
00337   private static String subterm(String pred1, String pred2) {
00338 
00339 
00340     if (pred1.equals("-") && pred2.equals("-"))
00341       return "true";
00342     if (pred1.equals("-"))
00343       return pred1;
00344     if (pred2.equals("-"))
00345       return pred2;
00346     
00347     if ((pred1.indexOf("true") != -1) && (pred2.indexOf("true") != -1))
00348       return "true";
00349     if (pred1.indexOf("true") != -1)
00350       return pred1;
00351     if (pred2.indexOf("true") != -1)
00352       return pred2;
00353     
00354     // ASSUMPTION: the shortest predicate, i.e. with less litterals,
00355     // will most probably be the subterm of the other predicate
00356     // (provided terms are simplified)
00357     // alpha subterm of tau, i.e. tau implies alpha
00358     String alphaStr;
00359     String tauStr;
00360 
00361 
00362     if (pred1.length() <= pred2.length()) {
00363       alphaStr = pred1;
00364       tauStr = pred2;
00365     } else {
00366       alphaStr = pred2;
00367       tauStr = pred1;
00368     }
00369       
00370     StringTokenizer alphaTk = new StringTokenizer(alphaStr, "&");
00371     StringTokenizer tauTk = new StringTokenizer(tauStr, "&");
00372     LinkedList tauLst = new LinkedList();
00373 
00374 
00375     // Putting the litterals of tau in a list - for easier access
00376     while (tauTk.hasMoreTokens()) {
00377       String token = tauTk.nextToken();
00378       tauLst.add(token);
00379     }
00380     while (alphaTk.hasMoreTokens()) {
00381       String alphaLit = alphaTk.nextToken();
00382       if (!tauLst.contains(alphaLit))
00383         return "false";
00384     }
00385     if (pred1.length() == pred2.length())
00386       return "true";
00387     return alphaStr;
00388   }  
00389 }

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