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

SmvTypeDecl.java

00001 package edu.ksu.cis.bandera.smv;
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.Vector;
00037 
00038 import edu.ksu.cis.bandera.bir.*;
00039 
00040 /**
00041  * BIR type switch for declaring SMV state variables.
00042  * <p>
00043  * An instance of this class is created by SmvTrans to help it declare
00044  * all the components of a BIR variable (composite types have multiple
00045  * components).   Variables are declared by callbacks to the SmvTrans
00046  * object on declareVar().
00047  * <p>
00048  * The SmvTypeDecl is applied to each variable by its type, with the
00049  * variable itself being passed to the caseXXX() method as the second
00050  * parameter (the Object context).  
00051  * <p>
00052  * If the type is composite, then we recursively apply the type switch
00053  * to the components of the composite type, but the context parameter
00054  * is then a string denoting the prefix of the SMV variable name
00055  * for the components of that variable.
00056  * <p>
00057  * Note that the varName() method must be called at the top of
00058  * each caseXXX() method to record the variable source and
00059  * other parameters for the subsequent recursive calls (which
00060  * will not get the StateVar as a param).
00061  */
00062 
00063 public class SmvTypeDecl extends AbstractTypeSwitch implements BirConstants {
00064 
00065     SmvTrans smvTrans;         // Translator class we're working for
00066     TransSystem system;
00067 
00068     StateVar source;         // BIR var we're declaring the components of
00069     SmvVar container;        // SmvVar that contains the vars being declared
00070     boolean constrained;     // constrained = has its own TRANS formula
00071     SmvVar deadFlag;         // SmvVar that indicates whether this var is live
00072 
00073     String refIndexType;    // SMV type for refIndex
00074     String instNumType;     // SMV type for instance numbers
00075     int maxSize;            // maximum size of any collection
00076 
00077     public SmvTypeDecl(SmvTrans smvTrans, TransSystem sys) {
00078     this.smvTrans = smvTrans;
00079     this.system = sys;
00080 
00081     // Calculate the maximum collection size and use it to build
00082     // the refIndex and instNum types (for ref vars)
00083     StateVarVector targets = sys.refAnyType().getTargets();
00084     maxSize = 0;
00085     for (int i = 0; i < targets.size(); i++)
00086         if (targets.elementAt(i).getType().isKind(COLLECTION)) {
00087         int size = ((Collection)targets.elementAt(i).getType())
00088             .getSize().getValue();
00089         if (size > maxSize)
00090             maxSize = size;
00091         }
00092     refIndexType = "0 .. " + targets.size();
00093     instNumType = "0 .. " + (maxSize - 1);
00094     }
00095     /**
00096      * Declare array variable.
00097      * <p>
00098      * An array variable is an aggregate with the following components:
00099      * <ul>
00100      * <li> A length variable recording the length of the array
00101      * <li> One or more variables for each possible array slot
00102      *  (created via recursive calls).
00103      * </ul>
00104      */
00105 
00106     public void caseArray(Array type, Object o)
00107     {
00108     String name = varName(o);
00109     SmvVar array = smvTrans.declareVar(name,null,source,null,
00110                        container,false,deadFlag);
00111     int size = type.getSize().getValue();
00112     String lengthType = "0 .. " + size;
00113     smvTrans.declareVar(smvTrans.lengthVar(name), 
00114                 lengthType,source,"0",array,constrained,deadFlag);
00115     for (int i = 0; i < size; i++) {
00116         // these components are contained in the array variable
00117         this.container = array;  
00118         type.getBaseType().apply(this,smvTrans.elementVar(name, i));
00119     }
00120     }
00121     /**
00122      * Declare boolean variable.
00123      */
00124 
00125     public void caseBool(Bool type, Object o) 
00126     {
00127     String name = varName(o);
00128     smvTrans.declareVar(name,"boolean",source,
00129                 initValue(type,o),container,constrained,deadFlag);
00130     }
00131     /**
00132      * Declare collection variable.
00133      * <p>
00134      * A collection variable is an aggregate with the following components:
00135      * <ul>
00136      * <li> An inuse variable for each possible collection instance,
00137      *  which is true if that instance has been allocated.
00138      * <li> One or more variables for each possible collection instance
00139      *  (created via recursive calls).
00140      * </ul>
00141      */
00142 
00143     public void caseCollection(Collection type, Object o)
00144     {
00145     String name = varName(o);
00146     SmvVar col = smvTrans.declareVar(name,null,source,null,
00147                      container,false,null);
00148     int size = type.getSize().getValue();
00149     for (int i = 0; i < size; i++) {
00150         SmvVar inuse = smvTrans.declareVar(smvTrans.inUseVar(name,i),
00151                            "boolean",source, "0",
00152                            col,constrained,null);
00153         // Instances are contained in collection
00154         this.container = col;
00155         // Collection instance is dead if inuse false
00156         this.deadFlag = inuse;
00157         type.getBaseType().apply(this,smvTrans.instanceVar(name,i));
00158         this.deadFlag = null;
00159     }
00160     }
00161     /**
00162      * Declare enumerated variable.
00163      * <p>
00164      * Since we used named integer constants for each enumerated value,
00165      * this is really just a range type.
00166      */
00167 
00168     public void caseEnumerated(Enumerated type, Object o) 
00169     {
00170     String name = varName(o);
00171     Vector constants = type.getConstants();
00172     String smvType = type.getFirstElement() + " .. " +
00173         (type.getFirstElement() + type.getEnumeratedSize() - 1);
00174     smvTrans.declareVar(name,smvType,source,
00175                 initValue(type,o),container,constrained,deadFlag);
00176     }
00177     /**
00178      * Declare field variable.
00179      */
00180 
00181     public void caseField(Field type, Object o)
00182     {
00183     String name = varName(o);
00184     type.getType().apply(this, smvTrans.fieldVar(name,type));
00185     }
00186     /**
00187      * Declare lock variable.
00188      * <p>
00189      * A lock variable is an aggregate with the following components:
00190      * <ul>
00191      * <li> An owner variable indicating which thread holds the lock
00192      * <li> A count variable, recording the number of acquisitions
00193      * of the lock (for relocking)
00194      * <li> A wait variable for each thread indicating whether that
00195      *  thread is blocked in the wait queue of this lock
00196      * </ul>
00197      */
00198 
00199     public void caseLock(Lock type, Object o)
00200     {
00201     String name = varName(o);
00202     SmvVar lock = smvTrans.declareVar(name,null,source,
00203                       null,container,false,deadFlag);
00204     smvTrans.declareVar(smvTrans.ownerVar(name),smvTrans.getThreadType(),
00205                 source,"NoThread",lock,constrained,deadFlag);
00206     smvTrans.declareVar(smvTrans.countVar(name),SmvTrans.LOCK_COUNT_TYPE,
00207                 source,"0",lock,constrained,deadFlag);
00208     ThreadVector threads = system.getThreads();
00209     for (int i = 0; i < threads.size(); i++)
00210         smvTrans.declareVar(smvTrans.waitVar(name,threads.elementAt(i)),
00211                 "boolean",source,"0",
00212                 lock,constrained,deadFlag);
00213     }
00214     /**
00215      * Declare range variable.
00216      */
00217 
00218     public void caseRange(Range type, Object o) 
00219     {
00220     String name = varName(o);
00221     String smvType = type.getFromVal().getValue() + " .. " +
00222         type.getToVal().getValue();
00223     smvTrans.declareVar(name,smvType,source,
00224                 initValue(type,o),container,constrained,deadFlag);
00225     }
00226     /**
00227      * Declare record variable.
00228      * <p>
00229      * An record variable is an aggregate with 
00230      * one or more variables for each field
00231      * (created via recursive calls).
00232      */
00233 
00234     public void caseRecord(Record type, Object o)
00235     {
00236     String name = varName(o);
00237     Vector fields = type.getFields();
00238     SmvVar record = smvTrans.declareVar(name,null,source,
00239                         null,container,false,deadFlag);
00240     for (int i = 0; i < fields.size(); i++) {
00241         // Fields are contained in record var
00242         this.container = record;
00243         ((Field)fields.elementAt(i)).apply(this, o);
00244     }
00245     }
00246     /**
00247      * Declare reference variable.
00248      * <p>
00249      * A reference is an aggregate with the following components:
00250      * <ul>
00251      * <li> a refIndex variable, specifying the target pointed to 
00252      * (or 0 for null)
00253      * <li> an instance variable, specifying the instance number
00254      * of the collection.
00255      * </ul>
00256      * Note that reference variables are unusual in that they may
00257      * appear as final values in expressions even though they
00258      * are implemented as two variables.  We solve this problem
00259      * by defining a "printForm" for an SMV variable that is
00260      * used to display the variable in a formula.  The printForm
00261      * of a reference R is (R_refIndex * MAX_COLLECT_SIZE + R_instNum),
00262      * thus the two components (R_refIndex and R_instNum) are combined
00263      * into a single integer for the purposes of assignment and
00264      * equality tests.  Dereferencing (the most common operation) 
00265      * uses the components seperately.
00266      */
00267 
00268     public void caseRef(Ref type, Object o)
00269     {
00270     String name = varName(o);
00271     SmvVar ref = smvTrans.declareVar(name, null,source, null, 
00272                      container,constrained,deadFlag);
00273     this.container = ref;
00274     SmvVar refIndex = 
00275         smvTrans.declareVar(smvTrans.refIndexVar(name),refIndexType,source,
00276                 "0",container,false,deadFlag);
00277     SmvVar instNum = 
00278         smvTrans.declareVar(smvTrans.instNumVar(name),instNumType,source,
00279                 "0",container,false,deadFlag);
00280     ref.setPrintForm("(" + refIndex.getName() + " * MAX_COLLECT_SIZE + " +
00281              instNum.getName() + ")");
00282     }
00283     public void defaultCase(Object obj) {
00284     throw new RuntimeException("Construct not handled: " + obj);
00285     }
00286     public int getMaxCollectionSize() { return maxSize; }
00287     /** 
00288      * Get initial value of variable.
00289      * <p>
00290      * If the context is a String, the variable is a component,
00291      * so just use the default value of the type.
00292      * Otherwise (context is StateVar), get the initial value 
00293      * of that variable and translate it.
00294      */
00295 
00296     String initValue(Type type, Object context) {
00297     Expr initVal;
00298     if (context instanceof String)
00299         initVal = type.defaultVal();
00300     else
00301         initVal = ((StateVar)context).getInitVal();
00302     initVal.apply(smvTrans);
00303     return smvTrans.getResult().toString();
00304     }
00305     /**
00306      * Return the name of the variable indicated by the context.
00307      * <p>
00308      * The context is either a StateVar (for a top-level call) or
00309      * a String denoting a prefix of a name (for a nested call to
00310      * declare the components of a composite type).
00311      * <p>
00312      * This must be called at the top of each caseXXX() method to set the
00313      * source, container, and constrained fields.
00314      */
00315     String varName(Object context) {
00316     if (context instanceof String)
00317         return (String) context;
00318     else {
00319         source = (StateVar)context;
00320         // top-level vars are not contained in any other var
00321         container = null;       
00322         // constrained if global (locals are set by thread TRANS formula)
00323         constrained = (source.getThread() == null);  
00324         return source.getName();
00325     }
00326     }
00327 }

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