00001 package gov.nasa.arc.ase.jpf;
00002
00003
00004 import java.io.*;
00005 import java.util.*;
00006 import gov.nasa.arc.ase.util.Debug;
00007 import gov.nasa.arc.ase.jpf.expr.Expr;
00008 import gov.nasa.arc.ase.jpf.expr.SubExpr;
00009
00010 public class SM {
00011 private int nstates;
00012 private int[][] adjlist;
00013 private String[] attributes;
00014 private String[][] state_attributes;
00015 private String[][][] transition_attributes;
00016
00017 private Expr expr;
00018
00019 private SubExpr[][] guards;
00020 private SubExpr[][] actions;
00021 private Sch sch = null;
00022
00023 boolean[] accepting;
00024 boolean[] trivial;
00025 boolean[] persistant;
00026
00027 public static class Wrapper {
00028 private int[] data;
00029 private int h = 0;
00030
00031 public Wrapper(int[] d) {
00032 data = d;
00033 for(int i = 0; i < data.length; i++)
00034 h += d[i];
00035 }
00036
00037 public int hashCode() {
00038 return h;
00039 }
00040
00041 public boolean equals(Object o) {
00042 Wrapper w = (Wrapper)o;
00043
00044 if(h != w.h) return false;
00045
00046 if(data.length != w.data.length) return false;
00047
00048 for(int i = 0; i < data.length; i++)
00049 if(data[i] != w.data[i]) return false;
00050
00051 return true;
00052 }
00053 }
00054 private SM(int ns) {
00055 nstates = ns;
00056 adjlist = new int[ns][];
00057 state_attributes = new String[ns][];
00058 transition_attributes = new String[ns][][];
00059
00060 expr = new Expr();
00061
00062 guards = new SubExpr[ns][];
00063 actions = new SubExpr[ns][];
00064
00065 accepting = new boolean[ns];
00066 trivial = new boolean[ns];
00067 persistant = new boolean[ns];
00068 }
00069 private static String attributesToString(String[] a) {
00070 StringBuffer sb = new StringBuffer();
00071
00072 for(int i = 0; i < a.length; i++) {
00073 if(i != 0) sb.append(',');
00074 sb.append(a[i]);
00075 }
00076
00077 return sb.toString();
00078 }
00079 public void backtrack(int s, int t) {
00080 actions[s][t].backtrack();
00081 }
00082 public int execute(int s, int t) {
00083 actions[s][t].execute();
00084
00085 return adjlist[s][t];
00086 }
00087 public SubExpr getAction(int s, int t) {
00088 return actions[s][t];
00089 }
00090 private static boolean getBooleanAttribute(String[] as, String a) {
00091 for(int i = 0; i < as.length; i++)
00092 if(as[i].equals(a)) return true;
00093
00094 return false;
00095 }
00096 public boolean getGraphBooleanAttribute(String a) {
00097 return getBooleanAttribute(attributes, a);
00098 }
00099 public String getGraphStringAttribute(String a) {
00100 return getStringAttribute(attributes, a);
00101 }
00102 public SubExpr getGuard(int s, int t) {
00103 return guards[s][t];
00104 }
00105 public boolean getStateBooleanAttribute(int s, String a) {
00106 return getBooleanAttribute(state_attributes[s], a);
00107 }
00108 public int getStateCount() {
00109 return nstates;
00110 }
00111 public String getStateStringAttribute(int s, String a) {
00112 return getStringAttribute(state_attributes[s], a);
00113 }
00114 private static String getStringAttribute(String[] as, String a) {
00115 for(int i = 0; i < as.length; i++)
00116 if(as[i].startsWith(a + "="))
00117 return as[i].substring(a.length() + 1);
00118
00119 return null;
00120 }
00121 public int getSuccessor(int s, int t) {
00122 return adjlist[s][t];
00123 }
00124 public boolean getTransitionBooleanAttribute(int s, int t, String a) {
00125 return getBooleanAttribute(transition_attributes[s][t], a);
00126 }
00127 public int getTransitionCount(int s) {
00128 return adjlist[s].length;
00129 }
00130 public String getTransitionStringAttribute(int s, int t, String a) {
00131 return getStringAttribute(transition_attributes[s][t], a);
00132 }
00133 private void init() {
00134 }
00135 public boolean isEnabled(int s, int t) {
00136 return guards[s][t].evaluate();
00137 }
00138 public static SM load(String fname) {
00139 try {
00140 BufferedReader in = new BufferedReader(new FileReader(fname));
00141 int ns = readInt(in);
00142 SM sm = new SM(ns);
00143 sm.setGraphAttributes(readAttributes(in));
00144 for(int i = 0; i < ns; i++) {
00145 int nt = readInt(in);
00146 sm.setStateAttributes(i, readAttributes(in));
00147 sm.accepting[i] = sm.getStateBooleanAttribute(i, "accepting");
00148 sm.trivial[i] = sm.getStateBooleanAttribute(i, "trivial");
00149 sm.persistant[i] = sm.getStateBooleanAttribute(i, "persistant");
00150 sm.setNTransitions(i, nt);
00151
00152 for(int j = 0; j < nt; j++) {
00153 sm.setAdj(i, j, readInt(in));
00154 sm.setGuard(i, j, readString(in));
00155 sm.setAction(i, j, readString(in));
00156 sm.setTransitionAttribute(i, j, readAttributes(in));
00157 }
00158 }
00159
00160 sm.init();
00161
00162 return sm;
00163 } catch(FileNotFoundException e) {
00164 Debug.println(Debug.ERROR, "file not found -- " + fname);
00165 throw new JPFErrorException("");
00166 } catch(IOException e) {
00167 Debug.println(Debug.ERROR, "error reading file -- " + fname);
00168 throw new JPFErrorException("");
00169 }
00170
00171
00172
00173 }
00174 private static String[] readAttributes(BufferedReader in) throws IOException {
00175 String line = readString(in);
00176
00177 if(line.equals("-")) return new String[0];
00178
00179 StringTokenizer st = new StringTokenizer(line, ",");
00180 int ntokens = st.countTokens();
00181 String[] tokens = new String[ntokens];
00182 for(int i = 0; i < ntokens; i++)
00183 tokens[i] = st.nextToken();
00184
00185 return tokens;
00186 }
00187 public static int readInt(BufferedReader in) throws IOException {
00188 String line;
00189
00190 do {
00191 line = in.readLine();
00192 int idx = line.indexOf('#');
00193 if(idx != -1) line = line.substring(0, idx);
00194 line = line.trim();
00195 } while(line.length() == 0);
00196
00197 return Integer.parseInt(line);
00198 }
00199 public static String readString(BufferedReader in) throws IOException {
00200 String line;
00201
00202 do {
00203 line = in.readLine();
00204 int idx = line.indexOf('#');
00205 if(idx != -1) line = line.substring(0, idx);
00206 line = line.trim();
00207 } while(line.length() == 0);
00208
00209 return line;
00210 }
00211 private void setAction(int s, int t, String a) {
00212 actions[s][t] = expr.parse(a);
00213 }
00214 private void setAdj(int s, int t, int a) {
00215 adjlist[s][t] = a;
00216 }
00217 private void setGraphAttributes(String[] a) {
00218 attributes = a;
00219 }
00220 private void setGuard(int s, int t, String g) {
00221 if(g.equals("else"))
00222 guards[s][t] = null;
00223 else
00224 guards[s][t] = expr.parse(g);
00225 }
00226 private void setNTransitions(int s, int nt) {
00227 adjlist[s] = new int[nt];
00228 guards[s] = new SubExpr[nt];
00229 actions[s] = new SubExpr[nt];
00230 transition_attributes[s] = new String[nt][];
00231 }
00232 public void setSch(Sch s) {
00233 sch = s;
00234 }
00235 private void setStateAttributes(int s, String[] a) {
00236 state_attributes[s] = a;
00237 }
00238 private void setTransitionAttribute(int s, int t, String[] a) {
00239 transition_attributes[s][t] = a;
00240 }
00241 }