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

BirTrace.java

00001 package edu.ksu.cis.bandera.bir;
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 ca.mcgill.sable.util.*;
00036 
00037 import java.util.*;
00038 
00039 /**
00040  * A BIR Trace, which represents either a counterexample to
00041  * a property, a positive result (i.e., property holds), or
00042  * a reason for an incomplete model check.
00043  * <p>
00044  * A BIR trace is constructed by a translator after parsing the
00045  * output of a verifier and interpretting it as a sequence of
00046  * transitions through the BIR transition system.  The trace
00047  * may end with a trap (e.g., NullPointerException).
00048  * <p>
00049  * Traps indicate run-time errors in the program or that fixed
00050  * resource bounds on the model have been exceeded.  There are three
00051  * such traps :<br>   
00052  * <ul>
00053  * <li> RangeLimitException : integer value is out of specified range
00054  * <li> ArraySizeLimitException : attempt to allocate an array bigger
00055  *      than the defined limit
00056  * <li> CollectionSizeLimitException : attempt to allocate more than
00057  *      the defined maximum number of instances
00058  * </ul>
00059  * <p>
00060  * In addition to the transformations, the constructor of the
00061  * trace must specify certain CHOICES made by actions in the
00062  * trace:
00063  * <ul>
00064  * <li> If an AssignAction performs a nondeterministic assignment,
00065  *   the specific value assigned must be recorded as the CHOICE for
00066  *   that action.
00067  * <li> If an AssignAction executes an allocator, the instance number
00068  *   allocated must be recorded as the CHOICE for that action
00069  *   (this is not used for dSPIN).
00070  * </ul>
00071  * Once all the transformations and choices have been added, invoking
00072  * the done() method will run the BIR simulator and generate the
00073  * BIR states for the trace (a state is generated for each action
00074  * in the trace).
00075  * <p>
00076  * The trace can be queried to determine if the check:
00077  * <ul>
00078  * <li> Verified the property (<code>isVerified()</code>)
00079  * <li> Failed to verify the property (<code>!isVerified()</code>)
00080  * <li> Failed due to a model resource bounds violation (<code>isLimitViolation()</code>)
00081  * <li> Failed due to a checker problem, e.g., insufficient memory (<code>!isComplete()</code>)
00082  * </ul>
00083  */
00084 
00085 public class BirTrace {
00086 
00087     boolean verified;              // property was verified (no counterexample)
00088     boolean completed;             // verifier terminated
00089     boolean limitviolation;        // verifier terminated
00090     boolean outofmemory;        // verifier out of memory
00091     boolean depthexceeded;      // verifier overran search depth
00092     boolean vectorexceeded;     // verifier overran vector width
00093     TransSystem system;
00094     TransVector transVector = new TransVector();  // transforms in trace
00095     Vector choiceVector = new Vector();           // choices made in trace
00096     String trapName;
00097     Transformation currentTrans;
00098     Transformation trapTrans;                     // transform causing trap
00099     int trapActionNum;                            // action that caused trap
00100     int numActions = 0;                           // number of actions in trace
00101     BirState [] state;                            // BIR states of trace
00102     public BirTrace(TransSystem system) {
00103     this.system = system;
00104     this.completed = false;
00105     this.verified = false;
00106     this.limitviolation = false;
00107     this.outofmemory = false;
00108     this.depthexceeded = false;
00109     this.vectorexceeded = false;
00110     }
00111     public BirTrace(TransSystem system, java.util.List l) {
00112         this(system);
00113         processTrail(l);
00114     }
00115     /**
00116      * Add a transformation to the end of the trace.
00117      */
00118 
00119     public void addTrans(Transformation trans) {
00120     if (currentTrans != null)
00121         numActions += currentTrans.getActions().size();
00122     currentTrans = trans;
00123     transVector.addElement(trans);
00124     choiceVector.addElement(new int[trans.getActions().size()+1]);
00125     }
00126     /**
00127      * Run simulator to complete construction of trace.
00128      */
00129 
00130     public void done() {
00131     int actionCount = 0;
00132     Vector stateVector = new Vector();
00133     BirState currentState = 
00134         BirState.initialState(system,transVector,choiceVector);
00135     stateVector.addElement(currentState.copy());
00136     for (int i = 0; i < transVector.size(); i++) {
00137         Transformation trans = transVector.elementAt(i);
00138         int choices [] = (int []) choiceVector.elementAt(i);
00139         ActionVector actions = trans.getActions();
00140         for (int j = 0; j < actions.size(); j++) {
00141         actionCount++;
00142         if (trapTrans == trans && trapActionNum <= j + 1)
00143             break;   // don't execute the action that caused trap
00144         int choiceNum = choices[j + 1];
00145         Action action = actions.elementAt(j);
00146         // Apply action to get next state
00147         currentState.applyAction(action,choiceNum);
00148         stateVector.addElement(currentState.copy());
00149         }
00150         currentState.completeTrans(trans);
00151     }
00152     state = new BirState[actionCount + 1];
00153     for (int i = 0; i < stateVector.size(); i++)
00154         state[i] = (BirState) stateVector.elementAt(i);
00155 
00156     // Stutter last state for trap action
00157     if (stateVector.size() <= actionCount) 
00158         state[stateVector.size()] = state[stateVector.size() - 1];
00159     numActions = actionCount;
00160     }
00161     public String evalExpr(Expr expr, int stateIndex) {
00162     return state[stateIndex].exprValue(expr);
00163     }
00164     public int getNumActions() { return numActions; }
00165     public BirState getState(int stateIndex) {
00166     return state[stateIndex];
00167     }
00168     public TransSystem getTransSystem() { return system; }
00169     public TransVector getTransVector() { return transVector; }
00170     public Action getTrapAction() {
00171     if (trapTrans == null)
00172         return null;
00173     if (trapActionNum > 0)
00174         return trapTrans.getActions().elementAt(trapActionNum - 1);
00175     else // trap in guard --- report Stmt of first Action as source
00176         return trapTrans.getActions().elementAt(0);
00177     }
00178     public String getTrapName() { return trapName; }
00179     public Transformation getTrapTrans() { return trapTrans; }
00180     public boolean isComplete() { return completed; }
00181 public boolean isDepthExceeded() { return depthexceeded; }
00182     public boolean isLimitViolation() { return limitviolation; }
00183 public boolean isOutOfMemory() { return outofmemory; }
00184 public boolean isVectorExceeded() { return vectorexceeded; }
00185     public boolean isVerified() { return verified; }
00186     public void print(boolean showStates) {
00187     if (! completed)
00188         System.out.println("CHECKER FAILED");
00189     else if (verified)
00190         System.out.println("VERIFIED");
00191     else {
00192         int actionCount = 0;
00193         System.out.println("BIR TRACE:");
00194         if (showStates) 
00195         state[0].print();
00196         for (int i = 0; i < transVector.size(); i++) {
00197         Transformation trans = transVector.elementAt(i);
00198         Location fromLoc = trans.getFromLoc();
00199         System.out.println("TRANS " + 
00200                    fromLoc.getThread().getName() + ": " +
00201                    fromLoc.getLabel());
00202         BirPrinter.printTrans(trans);
00203         actionCount += trans.getActions().size();
00204         if (showStates && actionCount < state.length)
00205             state[actionCount].print();
00206         }
00207         if (trapName != null) 
00208         System.out.println("TRAP " + trapName);
00209     }
00210     }
00211 
00212   /**
00213    * Parse a line of the spin simulator output, possibly adding a transform
00214    * to the trace.
00215    * <p>
00216    * Most of the lines (generated by spin) we ignore, but the PROMELA
00217    * contains special print statements that generate lines containing
00218    * the strings "BIR: L T A S" or "BIR? A C".  The string "BIR: L T A S"
00219    * is printed when executing an action: L is the location number, T
00220    * is the index of the transform out of that location, A is the index
00221    * of the action in the transform (0 is the guard, the actions begin
00222    * with 1), and S is the status of the action (usually OK, but may
00223    * be a trap name).  The string "BIR? A C" is printed when an
00224    * action makes a choice (e.g., choose expression): A is the
00225    * action index (the transformation is assumed to be the last
00226    * one for which a "BIR: ..." was seen), and C is an integer
00227    * representing the choice.
00228    */
00229 private void processTrail(java.util.List l)
00230 {
00231     if (l == null || l.size() == 0)
00232     {
00233         setVerified(true); return;
00234     }
00235 
00236     for (java.util.Iterator i = l.iterator(); i.hasNext(); )
00237     {
00238         String line = (String) i.next();
00239         if (!line.startsWith("BIR")) continue;
00240 
00241         try {
00242             StringTokenizer st = new StringTokenizer(line.substring(4));
00243             if (line.startsWith("BIR:"))
00244             {
00245                 // BIR: <loc> <trans> <action> <status>
00246                 int locId = Integer.parseInt(st.nextToken());
00247                 int transNum = Integer.parseInt(st.nextToken());
00248                 int actionNum = Integer.parseInt(st.nextToken());
00249                 String status = st.nextToken();
00250                 Location loc = system.getLocation(locId);
00251                 Transformation trans = loc.getOutTrans().elementAt(transNum);
00252                 if (status.equals("OK")) {
00253                     // Add trans only for first action
00254                     if (actionNum == 1) addTrans(trans);
00255                 } else // Status not OK---record trap
00256                     setTrap(status, trans, actionNum);
00257             } else if (line.startsWith("BIR?"))
00258             {
00259                 // BIR? <action> <choice>
00260                 int actionNum = Integer.parseInt(st.nextToken());
00261                 int choiceNum = Integer.parseInt(st.nextToken());
00262                 setChoice(actionNum, choiceNum);
00263             }
00264         } catch (Exception e)
00265         {
00266             throw new RuntimeException("Invalid BIR traces!");
00267         }
00268     }
00269     done();
00270     setVerified(false);
00271 }
00272     /**
00273      * Set the choice number of the given action of the current transformation.
00274      */
00275 
00276     public void setChoice(int actionNum, int choiceNum) {
00277     // subtrace 1 since action numbers start from 1
00278     int actionChoices [] = (int []) choiceVector.lastElement();
00279     actionChoices[actionNum - 1] = choiceNum;
00280     }
00281 public void setDepthExceeded() {
00282     this.depthexceeded = true;
00283     this.verified = false;
00284     this.completed = true;
00285 }
00286 public void setOutOfMemory() {
00287     this.outofmemory = true;
00288     this.verified = false;
00289     this.completed = true;
00290 }
00291     /**
00292      * Set the trap info for the trace.
00293      */
00294 
00295     public void setTrap(String trapName, Transformation trapTrans, 
00296             int actionNum) { 
00297     this.trapName = trapName;
00298         limitviolation = trapName.endsWith("LimitException"); 
00299     this.trapTrans = trapTrans;
00300     this.trapActionNum = actionNum;
00301     }
00302 public void setVectorExceeded() {
00303     this.vectorexceeded = true;
00304     this.verified = false;
00305     this.completed = true;
00306 }
00307     public void setVerified(boolean verified) { 
00308     this.verified = verified; 
00309     this.completed = true;
00310     }
00311 }

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