1 2 package gov.nasa.ltl.graph; 21 22 import java.io.*; 23 24 import java.util.Iterator ; 25 import java.util.LinkedList ; 26 import java.util.List ; 27 import java.util.StringTokenizer ; 28 import java.util.TreeSet ; 29 import java.util.Vector ; 30 31 32 35 public class SFSReduction { 36 public static void main (String [] args) { 37 if (args.length > 1) { 38 System.out.println("usage:"); 39 System.out.println("\tjava gov.nasa.ltl.graph.SFSReduction [<filename>]"); 40 41 return; 42 } 43 44 Graph g = null; 45 46 try { 47 if (args.length == 0) { 48 g = Graph.load(); 49 } else { 50 g = Graph.load(args[0]); 51 } 52 } catch (IOException e) { 53 System.out.println("Can't load the graph."); 54 55 return; 56 } 57 58 Graph reduced = reduce(g); 59 60 reduced.save(); 61 } 62 63 public static Graph reduce (Graph g) { 64 int currNumColors; 67 int prevNumColors = 1; 68 int currNumPO = 3; 69 int prevNumPO = 1; 70 TreeSet newColorSet = null; 71 LinkedList newColorList = null; 72 boolean accepting = false; 73 boolean nonaccepting = false; 74 75 List nodes = g.getNodes(); 77 78 for (Iterator i = nodes.iterator(); i.hasNext();) { 79 Node currNode = (Node) i.next(); 80 currNode.setIntAttribute("_prevColor", 1); 81 82 if (isAccepting(currNode)) { 83 currNode.setIntAttribute("_currColor", 1); 84 accepting = true; 85 } else { 86 currNode.setIntAttribute("_currColor", 2); 87 nonaccepting = true; 88 } 89 } 90 91 if (accepting && nonaccepting) { 92 currNumColors = 2; 93 } else { 94 currNumColors = 1; 95 } 96 97 boolean[][] currPO = new boolean[2][2]; 99 boolean[][] prevPO; 100 101 for (int i = 0; i < 2; i++) { 102 for (int j = 0; j < 2; j++) { 103 if (i >= j) { 104 currPO[i][j] = true; 105 } else { 106 currPO[i][j] = false; 107 } 108 } 109 } 110 111 while ((currNumColors != prevNumColors) || (currNumPO != prevNumPO)) { 112 for (Iterator i = nodes.iterator(); i.hasNext();) { 114 Node currNode = (Node) i.next(); 115 currNode.setIntAttribute("_prevColor", 116 currNode.getIntAttribute("_currColor")); 117 } 118 119 prevPO = currPO; 120 prevNumColors = currNumColors; 121 122 123 newColorList = new LinkedList (); newColorSet = new TreeSet (); 127 for (Iterator i = nodes.iterator(); i.hasNext();) { 128 Node currNode = (Node) i.next(); 129 130 ColorPair currPair = new ColorPair(currNode.getIntAttribute( 131 "_prevColor"), 132 getPrevN(currNode, prevPO)); 133 134 135 138 newColorList.add(new Pair(currNode.getId(), currPair)); 139 newColorSet.add(currPair); 140 } 141 142 currNumColors = newColorSet.size(); 143 144 LinkedList ordered = new LinkedList (); 150 151 for (Iterator i = newColorSet.iterator(); i.hasNext();) { 152 ColorPair currPair = (ColorPair) i.next(); 153 ordered.add(currPair); 154 } 155 156 for (Iterator i = newColorList.iterator(); i.hasNext();) { 158 Pair cPair = (Pair) i.next(); 159 ColorPair currPair = (ColorPair) cPair.getElement(); 160 g.getNode(cPair.getValue()) 161 .setIntAttribute("_currColor", ordered.indexOf(currPair) + 1); 162 } 163 164 165 prevNumPO = currNumPO; 167 currNumPO = 0; 168 currPO = new boolean[currNumColors][currNumColors]; 169 170 for (Iterator i = newColorList.iterator(); i.hasNext();) { 171 ColorPair currPairOne = (ColorPair) ((Pair) i.next()).getElement(); 172 173 for (Iterator j = newColorList.iterator(); j.hasNext();) { 174 ColorPair currPairTwo = (ColorPair) ((Pair) j.next()).getElement(); 175 boolean po = prevPO[currPairTwo.getColor() - 1][currPairOne.getColor() - 1]; 176 boolean dominate = iDominateSet(currPairOne.getIMaxSet(), 177 currPairTwo.getIMaxSet(), prevPO); 178 179 if (po && dominate) { 180 currPO[ordered.indexOf(currPairTwo)][ordered.indexOf(currPairOne)] = true; 181 currNumPO++; 182 } else { 183 currPO[ordered.indexOf(currPairTwo)][ordered.indexOf(currPairOne)] = false; 184 } 185 } 186 } 187 } 188 189 Graph result; 191 192 if (newColorList == null) { 193 result = g; 194 } else { 195 result = new Graph(); 196 197 Node[] newNodes = new Node[currNumColors]; 198 199 for (int i = 0; i < currNumColors; i++) { 200 Node n = new Node(result); 201 newNodes[i] = n; 202 } 203 204 for (Iterator i = newColorList.iterator(); i.hasNext();) { 205 Pair nodePair = (Pair) i.next(); 206 int origNodeId = nodePair.getValue(); 207 ColorPair colPair = (ColorPair) nodePair.getElement(); 208 209 if (newColorSet.contains(colPair)) { 210 newColorSet.remove(colPair); 216 217 TreeSet pairSet = (TreeSet ) colPair.getIMaxSet(); 218 int color = colPair.getColor(); 219 Node currNode = newNodes[color - 1]; 220 221 for (Iterator j = pairSet.iterator(); j.hasNext();) { 222 ITypeNeighbor neigh = (ITypeNeighbor) j.next(); 223 int neighPos = neigh.getColor() - 1; 224 Edge currEdge = new Edge(currNode, newNodes[neighPos], 225 neigh.getTransition()); 226 } 227 228 if (g.getInit().getId() == origNodeId) { 230 result.setInit(currNode); 231 } 232 233 if (isAccepting(g.getNode(origNodeId))) { 235 currNode.setBooleanAttribute("accepting", true); 236 } 237 } else { 238 } } 240 } 241 242 return reachabilityGraph(result); 243 244 } 246 247 private static boolean isAccepting (Node nodeIn) { 248 return (nodeIn.getBooleanAttribute("accepting")); 249 } 250 251 private static TreeSet getPrevN (Node currNode, boolean[][] prevPO) { 252 List edges = currNode.getOutgoingEdges(); 253 LinkedList neighbors = new LinkedList (); 254 ITypeNeighbor iNeigh; 255 TreeSet prevN = new TreeSet (); 256 257 for (Iterator i = edges.iterator(); i.hasNext();) { 258 Edge currEdge = (Edge) i.next(); 259 iNeigh = new ITypeNeighbor(currEdge.getNext() 260 .getIntAttribute("_prevColor"), 261 currEdge.getGuard()); 262 neighbors.add(iNeigh); 263 } 264 265 if (neighbors.size() == 0) { 267 return prevN; 268 } 269 270 boolean useless; 276 277 do { 278 useless = false; 279 iNeigh = (ITypeNeighbor) neighbors.removeFirst(); 280 281 for (Iterator i = neighbors.iterator(); i.hasNext();) { 282 ITypeNeighbor nNeigh = (ITypeNeighbor) i.next(); 283 ITypeNeighbor dominating = iDominates(iNeigh, nNeigh, prevPO); 284 285 if (dominating == iNeigh) { 286 i.remove(); 287 } 288 289 if (dominating == nNeigh) { 290 useless = true; 291 292 break; 293 } 294 } 295 296 if (!useless) { 297 prevN.add(iNeigh); 298 } 299 } while (neighbors.size() > 0); 300 301 return prevN; 302 } 303 304 private static boolean iDominateSet (TreeSet setOne, TreeSet setTwo, 305 boolean[][] prevPO) { 306 TreeSet working = new TreeSet (setTwo); 307 308 for (Iterator i = working.iterator(); i.hasNext();) { 309 ITypeNeighbor neighTwo = (ITypeNeighbor) i.next(); 310 311 for (Iterator j = setOne.iterator(); j.hasNext();) { 312 ITypeNeighbor neighOne = (ITypeNeighbor) j.next(); 313 ITypeNeighbor dominating = iDominates(neighOne, neighTwo, prevPO); 314 315 if (dominating == neighOne) { 316 i.remove(); 317 318 break; 319 } 320 } 321 } 322 323 if (working.size() == 0) { 324 return true; 325 } 326 327 return false; 328 } 329 330 333 private static ITypeNeighbor iDominates (ITypeNeighbor iNeigh, 334 ITypeNeighbor nNeigh, 335 boolean[][] prevPO) { 336 String iTerm = iNeigh.getTransition(); 337 String nTerm = nNeigh.getTransition(); 338 int iColor = iNeigh.getColor(); 339 int nColor = nNeigh.getColor(); 340 String theSubterm = subterm(iTerm, nTerm); 341 342 if (theSubterm == iTerm) { 343 if (prevPO[nColor - 1][iColor - 1]) { 344 return iNeigh; 346 } else { 347 return null; 348 } 349 } 350 351 if (theSubterm == nTerm) { 352 if (prevPO[iColor - 1][nColor - 1]) { 353 return nNeigh; 355 } else { 356 return null; 357 } 358 } 359 360 if (theSubterm.equals("true")) { 361 if (prevPO[nColor - 1][iColor - 1]) { 362 return iNeigh; 364 } else if (prevPO[iColor - 1][nColor - 1]) { 365 return nNeigh; 367 } 368 } 369 370 return null; 371 } 372 373 private static Graph reachabilityGraph (Graph g) { 374 Vector work = new Vector (); 375 Vector reachable = new Vector (); 376 work.add(g.getInit()); 377 378 while (!work.isEmpty()) { 379 Node currNode = (Node) work.firstElement(); 380 reachable.add(currNode); 381 382 if (currNode != null) { 383 List outgoingEdges = currNode.getOutgoingEdges(); 384 385 for (Iterator i = outgoingEdges.iterator(); i.hasNext();) { 386 Edge currEdge = (Edge) i.next(); 387 Node nextNode = (Node) currEdge.getNext(); 388 389 if (!(work.contains(nextNode) || reachable.contains(nextNode))) { 390 work.add(nextNode); 391 } 392 } 393 } 394 395 if (work.remove(0) != currNode) { 396 System.out.println("ERROR"); } 398 } 399 400 List nodes = g.getNodes(); 401 402 if (nodes != null) { 403 for (Iterator i = nodes.iterator(); i.hasNext();) { 404 Node n = (Node) i.next(); 405 406 if (!reachable.contains(n)) { 407 g.removeNode(n); 408 } 409 } 410 } 411 412 return g; 413 } 414 415 private static String subterm (String pred1, String pred2) { 416 if (pred1.equals("-") && pred2.equals("-")) { 417 return "true"; 418 } 419 420 if (pred1.equals("-")) { 421 return pred1; 422 } 423 424 if (pred2.equals("-")) { 425 return pred2; 426 } 427 428 if ((pred1.indexOf("true") != -1) && (pred2.indexOf("true") != -1)) { 429 return "true"; 430 } 431 432 if (pred1.indexOf("true") != -1) { 433 return pred1; 434 } 435 436 if (pred2.indexOf("true") != -1) { 437 return pred2; 438 } 439 440 String alphaStr; 445 String tauStr; 446 447 if (pred1.length() <= pred2.length()) { 448 alphaStr = pred1; 449 tauStr = pred2; 450 } else { 451 alphaStr = pred2; 452 tauStr = pred1; 453 } 454 455 StringTokenizer alphaTk = new StringTokenizer (alphaStr, "&"); 456 StringTokenizer tauTk = new StringTokenizer (tauStr, "&"); 457 LinkedList tauLst = new LinkedList (); 458 459 while (tauTk.hasMoreTokens()) { 461 String token = tauTk.nextToken(); 462 tauLst.add(token); 463 } 464 465 while (alphaTk.hasMoreTokens()) { 466 String alphaLit = alphaTk.nextToken(); 467 468 if (!tauLst.contains(alphaLit)) { 469 return "false"; 470 } 471 } 472 473 if (pred1.length() == pred2.length()) { 474 return "true"; 475 } 476 477 return alphaStr; 478 } 479 } | Popular Tags |