VIS

src/var/varVariable.c

Go to the documentation of this file.
00001 
00036 #include "varInt.h"
00037 
00038 static char rcsid[] UNUSED = "$Id: varVariable.c,v 1.6 2009/01/18 01:58:09 fabio Exp $";
00039 
00040 /*---------------------------------------------------------------------------*/
00041 /* Constant declarations                                                     */
00042 /*---------------------------------------------------------------------------*/
00043 
00044 
00045 /*---------------------------------------------------------------------------*/
00046 /* Stucture declarations                                                     */
00047 /*---------------------------------------------------------------------------*/
00048 
00049 
00050 /*---------------------------------------------------------------------------*/
00051 /* Type declarations                                                         */
00052 /*---------------------------------------------------------------------------*/
00053 
00054 
00055 /*---------------------------------------------------------------------------*/
00056 /* Variable declarations                                                     */
00057 /*---------------------------------------------------------------------------*/
00058 
00059 
00060 /*---------------------------------------------------------------------------*/
00061 /* Macro declarations                                                        */
00062 /*---------------------------------------------------------------------------*/
00063 
00064 
00067 /*---------------------------------------------------------------------------*/
00068 /* Static function prototypes                                                */
00069 /*---------------------------------------------------------------------------*/
00070 
00071 static int _VarVariableSetType(Var_Variable_t *var, int type);
00072 static int _VarVariableResetType(Var_Variable_t *var, int type);
00073 static char * _VarTypeDecode(int type);
00074 static array_t * _VarStringArrayDup(array_t *array);
00075 static void _VarStringArrayFree(array_t *array);
00076 
00080 /*---------------------------------------------------------------------------*/
00081 /* Definition of exported functions                                          */
00082 /*---------------------------------------------------------------------------*/
00083 
00105 boolean
00106 Var_VariableAddRangeInfo(
00107   Var_Variable_t * var,
00108   int numValues,
00109   array_t * symValArray)
00110 {
00111   int i;
00112   char *symValue;
00113   st_table *valueToIndex;
00114 
00115   if (var->indexToValue != NIL(array_t) || var->numValues != 2){
00116     error_append("Error: The range of variable ");
00117     error_append(var->name);
00118     error_append(" has been already set.\n");
00119     return 0;
00120   }
00121 
00122   if (symValArray != NIL(array_t)){
00123     if (numValues != array_n(symValArray)){
00124       error_append("Error: Mismatch of range and # of symbolic values.\n");
00125       return 0;
00126     }
00127     valueToIndex = st_init_table(strcmp,st_strhash);
00128     var->indexToValue = _VarStringArrayDup(symValArray);
00129     for (i=0; i < numValues; i++) {
00130       symValue = array_fetch(char *,var->indexToValue,i);
00131       if (st_insert(valueToIndex,symValue,(char *)((long)i))) {
00132         error_append("Error: Invalid argument for Var_VariableAddRangeInfo().\n");
00133         error_append("- Symbolic value ");
00134         error_append(symValue);
00135         error_append(" is redefined.\n");
00136         st_free_table(valueToIndex);
00137         return 0;
00138       }
00139     }
00140     var->valueToIndex = valueToIndex;
00141   }
00142   var->numValues = numValues;
00143   return 1;
00144 }
00145 
00146 
00159 boolean
00160 Var_VariableExpandRange(
00161   Var_Variable_t *var,
00162   int numValues)
00163 {
00164   if (numValues <= var->numValues){
00165     error_append("Error: A range can only be expanded.\n");
00166     return 0;
00167   }
00168   if (var->indexToValue != NIL(array_t)){
00169     int i;
00170     char *dummyName;
00171 
00172     for (i=var->numValues; i < numValues; i++){
00173       /* put empty strings for expanded range */
00174       dummyName = ALLOC(char,1);
00175       *dummyName = '\0';
00176       array_insert_last(char *,var->indexToValue,dummyName);
00177     }
00178   }
00179   var->numValues = numValues;
00180   return 1;
00181 } 
00182 
00196 boolean
00197 Var_VariableReduceRange(
00198   Var_Variable_t *var,
00199   int numValues)
00200 {
00201   if(numValues > var->numValues){
00202     return Var_VariableExpandRange(var,numValues);
00203   }
00204   else if (var->indexToValue != NIL(array_t)){
00205     error_append("Error: Cannot reduce the range of a symbolic variable.\n");
00206     return 0;
00207   }
00208 
00209   var->numValues = numValues;
00210   return 1;
00211 }
00212 
00234 Var_Variable_t *
00235 Var_VariableAlloc(
00236   Hrc_Node_t *hnode, 
00237   char *name)
00238 {
00239   Var_Variable_t *var;
00240 
00241   var = ALLOC(Var_Variable_t,1);
00242   var->name = util_strsav(name);
00243   var->hnode = hnode;
00244   if (hnode != NIL(Hrc_Node_t)){
00245     if ( Hrc_NodeAddVariable(hnode,var) == 0 ){
00246       Var_VariableFree(var);
00247       return NIL(Var_Variable_t);
00248     }
00249   }
00250   var->type = 0;
00251   /* assume that this is a Boolean variable w/o symbolic value definition */
00252   var->numValues = 2;
00253   var->numFanoutTables = 0;
00254   var->indexToValue = NIL(array_t);
00255   var->valueToIndex = NIL(st_table);
00256   var->typeIdentifier = NIL(char);
00257   var->undef = NIL(void);
00258   return var;
00259 }
00260 
00272 void
00273 Var_VariableFree(Var_Variable_t *var)
00274 {
00275   if (var->hnode != NIL(Hrc_Node_t)){
00276     Hrc_NodeDeleteVariable(var->hnode,var);
00277   }
00278   FREE(var->name);
00279   if (var->indexToValue != NIL(array_t)){
00280     _VarStringArrayFree(var->indexToValue);
00281   }
00282   if (var->valueToIndex != NIL(st_table)){
00283     st_free_table(var->valueToIndex);
00284   }
00285   if (var->typeIdentifier != NIL(char)){
00286     FREE(var->typeIdentifier);
00287   }
00288   FREE(var);
00289 }
00290 
00303 Var_Variable_t *
00304 Var_VariableDup(
00305   Var_Variable_t *var,
00306   Hrc_Node_t *hnode)
00307 {
00308   Var_Variable_t *varDup;
00309 
00310   varDup = Var_VariableAlloc(hnode,var->name);
00311   varDup->type = var->type;
00312   varDup->hnode = hnode;
00313   varDup->numFanoutTables = var->numFanoutTables;
00314   if (Var_VariableAddRangeInfo(varDup,var->numValues,var->indexToValue) == 0){
00315     return NIL(Var_Variable_t);
00316   }
00317   if (var->typeIdentifier != NIL(char)){
00318     varDup->typeIdentifier = util_strsav(var->typeIdentifier);
00319   }
00320   return varDup;
00321 }
00322 
00334 char *
00335 Var_VariableReadName(Var_Variable_t *var)
00336 {
00337   return var->name;
00338 }
00339 
00351 boolean
00352 Var_VariableTestIsPI(Var_Variable_t *var)
00353 {
00354   return (((var->type) & VarPI) ? 1:0);
00355 }
00356 
00368 boolean
00369 Var_VariableTestIsPO(Var_Variable_t *var)
00370 {
00371   return (((var->type) & VarPO) ? 1:0);
00372 }
00373 
00385 boolean
00386 Var_VariableTestIsPS(Var_Variable_t *var)
00387 {
00388   return (((var->type) & VarPS) ? 1:0);
00389 }
00390 
00402 boolean
00403 Var_VariableTestIsNS(Var_Variable_t *var)
00404 {
00405   return (((var->type) & VarNS) ? 1:0);
00406 }
00407 
00419 boolean
00420 Var_VariableTestIsSI(Var_Variable_t *var)
00421 {
00422   return (((var->type) & VarSI) ? 1:0);
00423 }
00424 
00436 boolean
00437 Var_VariableTestIsSO(Var_Variable_t *var)
00438 {
00439   return (((var->type) & VarSO) ? 1:0);
00440 }
00441 
00454 boolean
00455 Var_VariableTestIsSymbolic(Var_Variable_t *var)
00456 {
00457   if (var->indexToValue != NIL(array_t)){
00458     return 1;
00459   }
00460   return 0;
00461 }
00462 
00475 boolean
00476 Var_VariableTestIsEnumerative(Var_Variable_t *var)
00477 {
00478   if (var->indexToValue == NIL(array_t)){
00479     return 1;
00480   }
00481   return 0;
00482 }
00483 
00496 boolean
00497 Var_VariableTestIsValueInRange(
00498   Var_Variable_t *var,
00499   int value)
00500 {
00501   if (var->indexToValue != NIL(array_t)){
00502     return 0;
00503   }
00504   if (value >= 0 && value < var->numValues){
00505     return 1;
00506   }
00507   return 0;
00508 }
00509 
00521 int
00522 Var_VariableReadNumValues(Var_Variable_t *var)
00523 {
00524   return var->numValues;
00525 }
00526 
00538 int
00539 Var_VariableReadNumFanoutTables(Var_Variable_t *var)
00540 {
00541   return var->numFanoutTables;
00542 }
00543 
00555 void
00556 Var_VariableIncrementNumFanoutTables(Var_Variable_t *var)
00557 {
00558   (var->numFanoutTables)++;
00559 }
00560 
00572 void
00573 Var_VariableResetNumFanoutTables(
00574   Var_Variable_t* var)
00575 {
00576   var->numFanoutTables = 0;
00577 }
00578 
00579 
00591 char *
00592 Var_VariableReadSymbolicValueFromIndex(
00593   Var_Variable_t *var,
00594   int i)
00595 {
00596   assert(var->indexToValue != NIL(array_t));
00597   return array_fetch(char *,var->indexToValue,i);
00598 }
00599 
00612 int
00613 Var_VariableReadIndexFromSymbolicValue(
00614   Var_Variable_t *var,
00615   char *symbolicValue)
00616 {
00617   int  isFound;
00618   int  index;
00619 
00620   assert(var->valueToIndex != NIL(st_table));
00621   isFound = st_lookup_int(var->valueToIndex,symbolicValue,&index);
00622   return( isFound ? index : -1);
00623 }
00624 
00636 Hrc_Node_t *
00637 Var_VariableReadHnode(Var_Variable_t *var)
00638 {
00639   return var->hnode;
00640 }
00641 
00656 char *
00657 Var_VariableReadTypeIdentifier(Var_Variable_t *var)
00658 {
00659   return var->typeIdentifier;
00660 }
00661 
00662 
00674 void *
00675 Var_VariableReadUndef(Var_Variable_t *var)
00676 {
00677   return var->undef;
00678 }
00679 
00692 boolean
00693 Var_VariableChangeName(
00694   Var_Variable_t *var,
00695   char *name)
00696 {
00697   if (var->hnode != NIL(Hrc_Node_t)){
00698     if (Hrc_NodeDeleteVariable(var->hnode,var) == 0){
00699       /* this variable should have been in the hnode */
00700       return 0;
00701     }
00702   }
00703   FREE(var->name);
00704   var->name = util_strsav(name); 
00705   if (var->hnode != NIL(Hrc_Node_t)){
00706     if (Hrc_NodeAddVariable(var->hnode,var) == 0){
00707       /* there is a node with the new name in the hnode already */
00708       return 0;
00709     }
00710   }
00711   return 1;
00712 }
00713 
00729 int
00730 Var_VariableSetPI(Var_Variable_t *var)
00731 {
00732   return _VarVariableSetType(var,VarPI);
00733 }
00734 
00750 int
00751 Var_VariableSetPO(Var_Variable_t *var)
00752 {
00753   return _VarVariableSetType(var,VarPO);
00754 }
00755 
00771 int
00772 Var_VariableSetPS(Var_Variable_t *var)
00773 {
00774   return _VarVariableSetType(var,VarPS);
00775 }
00776 
00792 int
00793 Var_VariableSetNS(Var_Variable_t *var)
00794 {
00795   return _VarVariableSetType(var,VarNS);
00796 }
00797 
00811 int
00812 Var_VariableSetSI(Var_Variable_t *var)
00813 {
00814   return _VarVariableSetType(var,VarSI);
00815 }
00816 
00830 int
00831 Var_VariableSetSO(Var_Variable_t *var)
00832 {
00833   return _VarVariableSetType(var,VarSO);
00834 }
00835 
00849 int
00850 Var_VariableResetPI(Var_Variable_t *var)
00851 {
00852   return _VarVariableResetType(var,VarPI);
00853 }
00854 
00868 int
00869 Var_VariableResetPO(Var_Variable_t *var)
00870 {
00871   return _VarVariableResetType(var,VarPO);
00872 }
00873 
00887 int
00888 Var_VariableResetPS(Var_Variable_t *var)
00889 {
00890   return _VarVariableResetType(var,VarPS);
00891 }
00892 
00906 int
00907 Var_VariableResetNS(Var_Variable_t *var)
00908 {
00909   return _VarVariableResetType(var,VarNS);
00910 }
00911 
00925 int
00926 Var_VariableResetSI(Var_Variable_t *var)
00927 {
00928   return _VarVariableResetType(var,VarSI);
00929 }
00930 
00944 int
00945 Var_VariableResetSO(Var_Variable_t *var)
00946 {
00947   return _VarVariableResetType(var,VarSO);
00948 }
00949 
00961 void
00962 Var_VariableResetAllTypes(Var_Variable_t *var)
00963 {
00964   var->type = 0;
00965 }
00966 
00967 
00982 void
00983 Var_VariableSetTypeIdentifier(
00984   Var_Variable_t *var,
00985   char *typeIdentifier)
00986 {
00987   if (var->typeIdentifier != NIL(char)){
00988     FREE(var->typeIdentifier);
00989   }
00990   var->typeIdentifier = util_strsav(typeIdentifier);
00991 }
00992 
01008 boolean
01009 Var_VariablesTestIdentical(
01010   Var_Variable_t *var1, 
01011   Var_Variable_t *var2)
01012 {
01013   Hrc_Manager_t *hmgr1, *hmgr2;
01014   Hrc_Node_t *hnode1, *hnode2, *rootNode;
01015   Var_Variable_t *varCanonical1, *varCanonical2;
01016 
01017   hnode1 = Var_VariableReadHnode(var1);
01018   hnode2 = Var_VariableReadHnode(var2);
01019   hmgr1 = Hrc_NodeReadManager(hnode1);
01020   hmgr2 = Hrc_NodeReadManager(hnode2);
01021 
01022   if (hmgr1 != hmgr2){
01023     error_append("Error: Variables ");
01024     error_append(Var_VariableReadName(var1));
01025     error_append(" and ");
01026     error_append(Var_VariableReadName(var2));
01027     error_append(" are not under the same manager.\n");
01028     return 0;
01029   }
01030   /* if two variables reside in the same hnode */
01031   if (hnode1 == hnode2){
01032     if (var1 == var2){
01033       return 1;
01034     }
01035     return 0;
01036   }
01037 
01038   /* otherwise */
01039   rootNode = Hrc_ManagerReadRootNode(hmgr1);
01040  
01041   varCanonical1 = Hrc_VariableFindActualFromFormal(hnode1,var1,rootNode);
01042   varCanonical2 = Hrc_VariableFindActualFromFormal(hnode2,var2,rootNode);
01043   if (varCanonical1 == varCanonical2){
01044     return 1;
01045   }
01046   return 0;
01047 }
01048 
01049 
01061 boolean
01062 Var_VariablesTestHaveSameDomain(
01063   Var_Variable_t *var1, 
01064   Var_Variable_t *var2)
01065 {
01066   array_t *indexToValue1, *indexToValue2;
01067   char *value1, *value2;
01068   int i;
01069 
01070   if (var1->numValues != var2->numValues)
01071     return 0;
01072   indexToValue1 = var1->indexToValue;
01073   indexToValue2 = var2->indexToValue;
01074   if (indexToValue1 == NIL(array_t) || indexToValue2 == NIL(array_t))
01075     return 1;
01076   for (i=0; i < array_n(indexToValue1); i++){
01077     value1 = array_fetch(char *,indexToValue1,i);
01078     value2 = array_fetch(char *,indexToValue2,i);
01079     if (strcmp(value1,value2)){
01080       return 0;    
01081     }
01082   }
01083   return 1;
01084 }
01085 
01098 boolean
01099 Var_VariableTestTypeConsistency(Var_Variable_t *var)
01100 {
01101   /* checking PI/PO */
01102   if ((var->type & 03) == 03){
01103     error_append("Error: Variable ");
01104     error_append(Var_VariableReadName(var));
01105     error_append(" is of type PI/PO.\n");
01106     return 0;
01107   }
01108   /* checking PI/PS */
01109   if ((var->type & 05) == 05){
01110     error_append("Error: Variable ");
01111     error_append(Var_VariableReadName(var));
01112     error_append(" is of type PI/PS.\n");
01113     return 0;
01114   }
01115   /* checking PI/SO */
01116   if ((var->type & 041) == 041){
01117     error_append("Error: Variable ");
01118     error_append(Var_VariableReadName(var));
01119     error_append(" is of type PI/SO.\n");
01120     return 0;
01121   }
01122   return 1;
01123 }
01124 
01137 boolean
01138 Var_VariablesTestHaveSameTypeIdentifier(
01139   Var_Variable_t *var1,
01140   Var_Variable_t *var2)
01141 {
01142   if (var1->typeIdentifier == NIL(char) && var2->typeIdentifier == NIL(char)){
01143     return 1;
01144   }
01145   if (var1->typeIdentifier == NIL(char) || var2->typeIdentifier == NIL(char)){
01146     return 0;
01147   }
01148   if (strcmp(var1->typeIdentifier,var2->typeIdentifier) == 0 ){
01149     return 1;
01150   }
01151   return 0;
01152 }
01153 
01154 
01155 /*---------------------------------------------------------------------------*/
01156 /* Definition of internal functions                                          */
01157 /*---------------------------------------------------------------------------*/
01158 
01159 /*---------------------------------------------------------------------------*/
01160 /* Definition of static functions                                            */
01161 /*---------------------------------------------------------------------------*/
01162 
01177 static int
01178 _VarVariableSetType(Var_Variable_t *var,int type)
01179 {
01180 /*
01181   if (var->type & type){
01182     error_append("Warning: Variable ");
01183     error_append(Var_VariableReadName(var));
01184     error_append(" is already set to ");
01185     error_append(_VarTypeDecode(type));
01186     error_append(".\n");
01187      return 0;
01188   }
01189 */
01190   var->type |= type;
01191   if (Var_VariableTestTypeConsistency(var) == 0){
01192      return -1;
01193   }
01194   return 1;
01195 }
01196 
01211 static int
01212 _VarVariableResetType(Var_Variable_t *var,int type)
01213 {
01214 /*
01215   if (var->type & type){
01216     error_append("Warning: Variable ");
01217     error_append(Var_VariableReadName(var));
01218     error_append(" is already set to ");
01219     error_append(_VarTypeDecode(type));
01220     error_append(".\n");
01221      return 0;
01222   }
01223 */
01224   if ((var->type & type) == 0){
01225     return 0;
01226   }
01227   var->type &= ~type;
01228   return 1;
01229 }
01230 
01243 static char *
01244 _VarTypeDecode(int type)
01245 {
01246   /* suppress information on SI/SO for simplicity */
01247   type &= 017;
01248   switch(type){
01249     case 00:
01250       return "Internal";
01251     case 01: 
01252       return "PI";
01253     case 02: 
01254       return "PO";
01255     case 03: 
01256       error_append("Error: Strange type PI/PO.\n");
01257       return "PI/PO";
01258     case 04: 
01259       return "PS";
01260     case 05:
01261       error_append("Error: Strange type PI/PS.\n");
01262       return "PI/PS";
01263     case 06:
01264       return "PO/PS";
01265     case 07:
01266       error_append("Error: Strange type PI/PO/PS.\n");
01267       return "PI/PO/PS";
01268     case 010: 
01269       return "NS";
01270     case 011:
01271       return "PI/NS";
01272     case 012:
01273       return "PO/NS";
01274     case 013:
01275       error_append("Error: Strange type PI/PO/NS.\n");
01276       return "PI/PO/NS";
01277     case 014:
01278       return "PS/NS";
01279     case 015:
01280       error_append("Error: Strange type PI/PS/NS.\n");
01281       return "PI/PS/NS";
01282     case 016:
01283       return "PO/PS/NS";
01284     case 017:
01285       error_append("Error: Strange type PI/PO/PS/NS.\n");
01286       return "PI/PO/PS/NS";
01287     default: 
01288       fail("Strange type in VarTypeDecode().\n");
01289       return NIL(char); /* not reached */
01290   }
01291 }
01292 
01305 static array_t *
01306 _VarStringArrayDup(array_t *array)
01307 {
01308   int i;
01309   char *symbol,*newSymbol;
01310   array_t *newArray;
01311 
01312   newArray = array_alloc(char *,0);
01313   for (i=0; i < array_n(array); i++) {
01314     symbol = array_fetch(char *, array, i);
01315     newSymbol = util_strsav(symbol);
01316     array_insert_last(char *,newArray,newSymbol);
01317   }
01318   return newArray;
01319 }
01320 
01333 static void
01334 _VarStringArrayFree(array_t *array)
01335 {
01336   int i;
01337   char *symbol;
01338 
01339   for (i=0; i < array_n(array); i++) {
01340     symbol = array_fetch(char *, array, i);
01341     FREE(symbol);
01342   }
01343   array_free(array);
01344 }