00001 package edu.ksu.cis.bandera.birc; 00002 00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00004 * Bandera, a Java(TM) analysis and transformation toolkit * 00005 * Copyright (C) 1998, 1999 James Corbett (corbett@hawaii.edu) * 00006 * All rights reserved. * 00007 * * 00008 * This work was done as a project in the SAnToS Laboratory, * 00009 * Department of Computing and Information Sciences, Kansas State * 00010 * University, USA (http://www.cis.ksu.edu/santos). * 00011 * It is understood that any modification not identified as such is * 00012 * not covered by the preceding statement. * 00013 * * 00014 * This work is free software; you can redistribute it and/or * 00015 * modify it under the terms of the GNU Library General Public * 00016 * License as published by the Free Software Foundation; either * 00017 * version 2 of the License, or (at your option) any later version. * 00018 * * 00019 * This work is distributed in the hope that it will be useful, * 00020 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00022 * Library General Public License for more details. * 00023 * * 00024 * You should have received a copy of the GNU Library General Public * 00025 * License along with this toolkit; if not, write to the * 00026 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * 00027 * Boston, MA 02111-1307, USA. * 00028 * * 00029 * Java is a trademark of Sun Microsystems, Inc. * 00030 * * 00031 * To submit a bug report, send a comment, or get the latest news on * 00032 * this project and other SAnToS projects, please visit the web-site * 00033 * http://www.cis.ksu.edu/santos * 00034 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 00035 import java.io.*; 00036 import java.util.*; 00037 00038 import edu.ksu.cis.bandera.bir.*; 00039 00040 /** 00041 * Reducer does two things: 00042 * <ol> 00043 * <li> collapses trivial transformations together to reduce the number 00044 * of locations (a trivial transformation is one with no actions). 00045 * <li> uses VisibleExtractor to mark each transformation as 00046 * visible/invisible (note: we no longer collapse sequences of 00047 * invisible transitions together in BIRC but simply mark them 00048 * as invisible and let the translator collapse them if this 00049 * is appropriate). 00050 * </ol> 00051 */ 00052 00053 public class Reducer { 00054 00055 TransSystem system; 00056 int mark; 00057 Vector newTransformations = new Vector(); 00058 00059 public Reducer(TransSystem system) { 00060 this.system = system; 00061 this.mark = Location.getNewMark(); 00062 } 00063 /** 00064 * Follow all invisible transformations from the given location, 00065 * appending them to the transition sequence, until we reach 00066 * a visible transformation. 00067 */ 00068 00069 public void reduce(Location currentLoc, TransSequence seq, 00070 boolean visible) { 00071 // if currentLoc visible, mark it 00072 if (visible) 00073 currentLoc.setMark(mark); 00074 // For each transformation out of currentLoc 00075 TransVector outTrans = currentLoc.getOutTrans(); 00076 for (int i = 0; i < outTrans.size(); i++) { 00077 Transformation trans = outTrans.elementAt(i); 00078 // If the transformation is not visible, 00079 // is not a self-loop, 00080 // does not loop back to some location already in the sequence, 00081 // and is followed by some other transformation, 00082 // Then delete the transformation, add it to the sequence, 00083 // and continue collapsing transformations from the next loc. 00084 if (! trans.isVisible() && 00085 (trans.getFromLoc() != trans.getToLoc()) && 00086 (! seq.containsLoc(trans.getToLoc())) && 00087 (trans.getToLoc().getOutTrans().size() > 0)) { 00088 trans.markDeleted(); 00089 reduce(trans.getToLoc(), seq.add(trans), false); 00090 } 00091 else { 00092 // Visible trans: delete it, add it to the sequence, 00093 // and add the sequence as a new transformation. 00094 trans.markDeleted(); 00095 newTransformations.addElement(seq.add(trans)); 00096 // If we haven't visited the toLoc before, continue from there 00097 if ((trans.getToLoc().getMark() != mark)) 00098 reduce(trans.getToLoc(), new TransSequence(), true); 00099 } 00100 } 00101 } 00102 public void run() { 00103 // First mark all Transformations as trivial/nontrivial 00104 // (use visible flag) 00105 TransVector transVector = system.getTransformations(); 00106 for (int i = 0; i < transVector.size(); i++) { 00107 Transformation trans = transVector.elementAt(i); 00108 trans.setVisible(trans.getActions().size() > 0); 00109 } 00110 00111 // Apply reduction, deleting transformations that will be collapsed 00112 ThreadVector threadVector = system.getThreads(); 00113 for (int i = 0; i < threadVector.size(); i++) { 00114 BirThread thread = threadVector.elementAt(i); 00115 reduce(thread.getStartLoc(), new TransSequence(), true); 00116 } 00117 Transformation.purge(); 00118 00119 // Add collapsed transformations 00120 for (int i = 0; i < newTransformations.size(); i++) { 00121 TransSequence seq =(TransSequence)newTransformations.elementAt(i); 00122 seq.fromLoc().addTrans(seq.toLoc(), seq.guard(), 00123 seq.actions()); 00124 } 00125 00126 // Finally, mark all Transformations as visible/invisible 00127 VisibleExtractor vis = new VisibleExtractor(); 00128 transVector = system.getTransformations(); 00129 for (int i = 0; i < transVector.size(); i++) { 00130 Transformation trans = transVector.elementAt(i); 00131 trans.setVisible(false); 00132 ActionVector actions = trans.getActions(); 00133 for (int j = 0; j < actions.size(); j++) { 00134 vis.reset(); 00135 actions.elementAt(j).apply(vis); 00136 // Transformation is visible if one of its actions is 00137 // visible or observable. 00138 if (actions.elementAt(j).isObservable() || vis.isVisible()) 00139 trans.setVisible(true); 00140 } 00141 } 00142 } 00143 }