VIS

src/tbl/tblUtil.c

Go to the documentation of this file.
00001 
00042 #include "tblInt.h"
00043 
00044 static char rcsid[] UNUSED = "$Id: tblUtil.c,v 1.19 2009/04/11 02:01:29 fabio Exp $";
00045 
00046 /*---------------------------------------------------------------------------*/
00047 /* Type declarations                                                    */
00048 /*---------------------------------------------------------------------------*/
00049 
00050 /* Structure used to sort table inputs. */
00051 typedef struct varOrdStruct {
00052   int id;                       /* input column number */
00053   int rank;                     /* low-ranked columns should go first */
00054 } Var_Ord_t;
00055 
00056 
00059 /*---------------------------------------------------------------------------*/
00060 /* Static function prototypes                                                */
00061 /*---------------------------------------------------------------------------*/
00062 
00063 static int TableEntryComputeHashVal(Tbl_Table_t *table, Tbl_Entry_t *entry);
00064 static array_t* TableCreatIntArray(int size);
00065 static char* TableObtainSignature(Tbl_Table_t * table, int outputColumn);
00066 static int varCompare(const void *x, const void *y);
00067 
00071 /*---------------------------------------------------------------------------*/
00072 /* Definition of exported functions                                          */
00073 /*---------------------------------------------------------------------------*/
00074 
00085 Tbl_Table_t*
00086 Tbl_TableAlloc(void)
00087 {
00088   Tbl_Table_t * table;
00089 
00090   table = ALLOC(Tbl_Table_t,1);
00091   table->inputNames = array_alloc(Var_Variable_t*,0);
00092   table->outputNames = array_alloc(Var_Variable_t*,0);
00093   table->data = ALLOC(Tbl_Data_t,1);  
00094   TblTableReadDefaults(table) = array_alloc(Tbl_Entry_t*,0);
00095   TblTableReadRefCount(table) = 1;
00096   TblTableReadData(table) = array_alloc(Tbl_Row_t*,0);
00097   return table;
00098 }
00099 
00100 
00113 void
00114 Tbl_TableFree(
00115   Tbl_Table_t *  table /* The table to be freed */)
00116 {
00117   int i,j,k;
00118   Tbl_Row_t * row;
00119   Tbl_Entry_t *entry;
00120     
00121     
00122   if (table != NIL(Tbl_Table_t)) {
00123     if (TblTableReadRefCount(table) < 2) {
00124   Tbl_TableForEachEntry(table,j,i,k,entry) {
00125       if (entry != NIL(Tbl_Entry_t)) {
00126         Tbl_EntryFree(entry);
00127       }
00128     }                        
00129     TblTableForEachRow(table,row,i){
00130       array_free(row->inputs);
00131       array_free(row->outputs);
00132       FREE(row);
00133     }
00134     Tbl_TableForEachDefaultEntry(table,entry,i) {
00135       if (entry != NIL(Tbl_Entry_t)) {
00136         Tbl_EntryFree(entry);
00137       }
00138     }            
00139     array_free(TblTableReadDefaults(table));
00140     array_free(TblTableReadData(table));
00141     FREE(table->data);
00142   
00143     }
00144   else {
00145     TblTableReadRefCount(table)--;;
00146   }
00147     array_free(table->inputNames);
00148     array_free(table->outputNames);
00149     FREE(table);
00150   }
00151 }   
00152 
00164 Tbl_Table_t *
00165 Tbl_TableSoftDup(
00166   Tbl_Table_t *  table /* The table to be duplicated */)
00167 {
00168   Tbl_Table_t *tabledup;
00169 
00170   assert(TblTableReadRefCount(table) >0);
00171   tabledup = ALLOC(Tbl_Table_t,1);
00172   tabledup->data = table->data;
00173 
00174   tabledup->inputNames = array_dup(table->inputNames);
00175   tabledup->outputNames = array_dup(table->outputNames);
00176   
00177   TblTableReadRefCount(table) ++;
00178   return tabledup;
00179 }
00180 
00192 Tbl_Table_t *
00193 Tbl_TableHardDup(
00194   Tbl_Table_t *  table /* The table to be duplicated */)
00195 {
00196   Tbl_Table_t * tabledup;
00197   int i;
00198   Tbl_Entry_t *newEntry, *entry;
00199   Var_Variable_t *var;
00200   Tbl_Row_t *row;
00201 
00202   tabledup = Tbl_TableAlloc();
00203 
00204   Tbl_TableForEachInputVar(table,i,var){
00205     Tbl_TableAddColumn(tabledup,var,0);
00206   }
00207 
00208   Tbl_TableForEachOutputVar(table,i,var){
00209     Tbl_TableAddColumn(tabledup,var,1);
00210   }  
00211 
00212   Tbl_TableForEachDefaultEntry(table,entry,i) {
00213     if (entry != NIL(Tbl_Entry_t)) {
00214       newEntry = Tbl_EntryDup(entry);
00215     }
00216     else {
00217       newEntry = NIL(Tbl_Entry_t);
00218     }
00219     (void) Tbl_TableDefaultSetEntry(tabledup,newEntry,i);
00220   }
00221 
00222   TblTableForEachRow(table,row,i){
00223     TblTableSetRow(tabledup,TblRowDup(row),i);
00224   }
00225   
00226   return tabledup;
00227 }
00228 
00229 
00244 boolean
00245 Tbl_TableDefaultSetEntry(
00246     Tbl_Table_t *table,
00247     Tbl_Entry_t *entry,
00248     int index)
00249 {
00250   if (TblTableReadRefCount(table) > 1) {
00251     printf(" WARNING: You are modifying more than one table by re-setting this entry\n");
00252   }
00253   
00254   if (array_n(TblTableReadDefaults(table)) < index) {
00255     return FALSE; 
00256   }
00257   
00258   if (entry != NIL(Tbl_Entry_t)) {
00259     entry->ioType = 1;
00260     entry->varColNum = index;
00261     /* debug */
00262     if (entry->type == Tbl_EntryEqual_c)
00263     assert(Tbl_EntryReadVarIndex(entry) < Tbl_TableReadNumInputs(table));    
00264   }
00265   
00266   
00267   array_insert(Tbl_Entry_t*, TblTableReadDefaults(table),index,entry);
00268   return TRUE;
00269 }
00270 
00285 Tbl_Entry_t*
00286 Tbl_TableDefaultReadEntry(
00287     Tbl_Table_t *table,
00288     int index)
00289 {
00290   if (array_n(TblTableReadDefaults(table)) < index) {
00291     return NIL(Tbl_Entry_t); 
00292   }
00293 
00294   return (array_fetch(Tbl_Entry_t*, TblTableReadDefaults(table),index));
00295 }
00296 
00297     
00309 int 
00310 Tbl_TableAddRow(
00311   Tbl_Table_t *  table)
00312 {
00313   Tbl_Row_t * row;
00314   int i;
00315 
00316   if (table != NIL(Tbl_Table_t)) {
00317   if (TblTableReadRefCount(table) > 1) {
00318     printf(" WARNING: You are modifying more than one table by adding this row\n");
00319   }    
00320       row = ALLOC(Tbl_Row_t,1);
00321       row->inputs = array_alloc(Tbl_Entry_t*,0);
00322       for (i=0; i < array_n(table->inputNames); i++) {
00323         array_insert_last(Tbl_Entry_t*,row->inputs, NIL(Tbl_Entry_t)); 
00324       }
00325       
00326 
00327       row->outputs = array_alloc(Tbl_Entry_t*,0);
00328       for (i=0; i < array_n(table->outputNames); i++) {
00329         array_insert_last(Tbl_Entry_t*,row->outputs, NIL(Tbl_Entry_t)); 
00330       }
00331                         
00332       array_insert_last(Tbl_Row_t*, TblTableReadData(table),row);
00333       return ( array_n(TblTableReadData(table)) -1);
00334     }
00335   else return -1;
00336 }  
00337 
00357 int
00358 Tbl_TableAddColumn(
00359   Tbl_Table_t *  table /* the table */,
00360   Var_Variable_t *  var /* the Var being added */,
00361   int  flag /* This flag is set to 0 if it is an input and 1 if it is and output
00362  */)
00363 {
00364   int i, index;
00365   Tbl_Row_t *row;
00366   array_t *carray;
00367   
00368   assert(table !=NIL(Tbl_Table_t));
00369   assert((flag==0)||(flag ==1));
00370   if (TblTableReadRefCount(table) > 1) {
00371     printf(" WARNING: You may be modifying more than one table by adding this column\n");
00372   }  
00373   index = 0;
00374   for (i=0; i< array_n(TblTableReadData(table)); i++) {
00375     row = array_fetch(Tbl_Row_t*,TblTableReadData(table),i);
00376     if (flag==0) {
00377       carray = row->inputs; 
00378     }
00379     else {
00380       carray = row->outputs; 
00381     }
00382   
00383     array_insert_last(Tbl_Entry_t*,carray,NIL(Tbl_Entry_t));
00384   
00385   }
00386   if (flag==0) {
00387     array_insert_last(Var_Variable_t*, table->inputNames, var);
00388     index = array_n(table->inputNames);
00389   }
00390   else {
00391       array_insert_last(Var_Variable_t*, table->outputNames, var);
00392       index = array_n(table->outputNames);      
00393       array_insert_last(Tbl_Entry_t*,
00394                         TblTableReadDefaults(table),NIL(Tbl_Entry_t));
00395     }
00396 
00397   return index;
00398 }
00399 
00414 Tbl_Table_t *
00415 Tbl_TableRowDelete(
00416    Tbl_Table_t *originalTable,
00417    int rowNumToDelete,
00418    array_t *freeArray            
00419    )
00420 {
00421     Tbl_Table_t *newTable;
00422     int i, rownum, newRowNum, numInputs, numOutputs;
00423     Var_Variable_t *var, *newVar;
00424     Tbl_Row_t *row UNUSED;
00425     Tbl_Entry_t *newEntry, *origEntry, *entry, *dupEntry;
00426 
00427     newTable = Tbl_TableAlloc();
00428     Tbl_TableForEachInputVar(originalTable, i, var){
00429         newVar = Var_VariableDup(var, NIL(Hrc_Node_t));
00430         array_insert_last(Var_Variable_t *, freeArray, newVar);
00431         (void) Tbl_TableAddColumn(newTable, newVar, 0);
00432     }
00433     Tbl_TableForEachOutputVar(originalTable, i, var){
00434         newVar = Var_VariableDup(var, NIL(Hrc_Node_t));
00435         array_insert_last(Var_Variable_t *, freeArray, newVar);
00436         (void) Tbl_TableAddColumn(newTable, newVar, 1);
00437     }
00438     for(i = 0; i < Tbl_TableReadNumOutputs(originalTable); i++){
00439         entry = Tbl_TableDefaultReadEntry(originalTable, i);
00440         if(entry != NIL(Tbl_Entry_t)){
00441             dupEntry = Tbl_EntryDup(entry);
00442             Tbl_TableDefaultSetEntry(newTable, dupEntry, i);
00443         }
00444     }
00445     numInputs = Tbl_TableReadNumInputs(originalTable);
00446     numOutputs = Tbl_TableReadNumOutputs(originalTable);
00447     TblTableForEachRow(originalTable, row, rownum){
00448         if(rownum != rowNumToDelete){
00449             newRowNum = Tbl_TableAddRow(newTable);
00450             for(i = 0; i < numInputs; i++){
00451                 origEntry = Tbl_TableReadEntry(originalTable, rownum, i, 0);
00452                 newEntry = Tbl_EntryDup(origEntry);
00453                 Tbl_TableSetEntry(newTable, newEntry, newRowNum, i, 0);
00454             }
00455             for(i = 0; i < numOutputs; i++){
00456                 origEntry = Tbl_TableReadEntry(originalTable, rownum, i, 1);
00457                 newEntry = Tbl_EntryDup(origEntry);
00458                 Tbl_TableSetEntry(newTable, newEntry, newRowNum, i, 1);
00459             }
00460         }
00461     }
00462     Tbl_TableFree(originalTable);
00463     return newTable;
00464 }
00465 
00481 Var_Variable_t*
00482 Tbl_TableReadIndexVar(
00483   Tbl_Table_t *  table,
00484   int index,
00485   int  flag /* Set to 0 if it is an input Var and 1 if it an output Var */
00486 )
00487 {
00488   array_t *carray;
00489 
00490   assert(table !=NIL(Tbl_Table_t));
00491   assert((flag==0)||(flag ==1));
00492   
00493   if (flag==0) {
00494     carray = table->inputNames;
00495   }
00496   else {
00497     carray = table->outputNames;
00498   }
00499             
00500   return (array_fetch(Var_Variable_t*,carray,index));
00501 }
00502 
00517 Tbl_Entry_t *
00518 Tbl_TableReadEntry(
00519   Tbl_Table_t *  table ,
00520   int  rowNum,
00521   int  colNum,
00522   int  flag )
00523 {
00524   Tbl_Row_t *row;
00525   Tbl_Entry_t *entry;
00526     
00527 
00528   assert(table !=NIL(Tbl_Table_t));
00529   assert((flag==0)||(flag ==1));
00530   
00531   row = TblTableReadRow(table,rowNum);
00532   entry = TblRowReadEntry(row,colNum,flag);
00533     
00534   return entry;
00535 }
00536 
00552 boolean 
00553 Tbl_TableSetEntry(
00554   Tbl_Table_t *  table /* The Table to be examined */,
00555   Tbl_Entry_t * newEntry,
00556   int  i /* Row Id */,
00557   int  j /* Column Id */,
00558   int  flag /* flag indicating whether it is an input or output */)
00559 {
00560   Tbl_Row_t *row;
00561   Tbl_Entry_t *entry;
00562 
00563   assert(table !=NIL(Tbl_Table_t));
00564   assert((flag==0)||(flag ==1));
00565   if (TblTableReadRefCount(table) > 1) {
00566     printf(" WARNING: You are modifying more than one table by  re-setting this entry\n");
00567   }
00568 
00569   entry = Tbl_TableReadEntry(table ,i,j,flag);
00570  if (entry != NIL(Tbl_Entry_t)) {
00571    Tbl_EntryFree(entry);
00572   }
00573 
00574   row = TblTableReadRow(table,i);
00575 
00576   newEntry->ioType = flag;
00577   newEntry->varColNum = j;
00578   TblRowSetEntry(row,newEntry,j,flag);
00579   
00580   return TRUE;
00581 }
00582 
00597 boolean
00598 Tbl_TableSetEntryDc(
00599   Tbl_Table_t *  table,
00600   int  i,
00601   int  j,
00602   int  flag)
00603 {
00604   array_t *ioarray;
00605   int range;
00606   Tbl_Entry_t *entry;
00607 
00608   assert(table !=NIL(Tbl_Table_t));
00609   assert((flag==0)||(flag ==1));
00610   if (TblTableReadRefCount(table) > 1) {
00611     printf(" WARNING: You are modifying more than one table by re-setting this entry\n");
00612   }
00613   
00614   if (flag==0) {
00615     ioarray = table->inputNames;
00616   }
00617   else {
00618     ioarray = table->outputNames;
00619   }
00620 
00621   range = Var_VariableReadNumValues(array_fetch(Var_Variable_t*,ioarray,j));
00622   entry = Tbl_TableReadEntry(table,i,j,flag);
00623   Tbl_EntrySetValue(entry,0,range-1);
00624   return TRUE;
00625 }
00642 void
00643 Tbl_TableAddEntryRange(
00644   Tbl_Table_t *  table,
00645   int  i,
00646   int  j,
00647   int  val1,
00648   int  val2,
00649   int  flag)
00650 {
00651   Tbl_Entry_t *entry;
00652 
00653   if (TblTableReadRefCount(table) > 1) {
00654     printf(" WARNING: You are modifying more than one table by changing the re-setting this entry\n");
00655   }
00656   
00657   entry = Tbl_TableReadEntry(table,i,j,flag);
00658   Tbl_EntrySetValue(entry,val1,val2);
00659     
00660 }
00661   
00676 void
00677 Tbl_TableComplementEntry(
00678   Tbl_Table_t *  table,
00679   int  i,
00680   int  j,
00681   int  flag)
00682 {
00683   Tbl_Entry_t *entry;
00684     
00685   entry = Tbl_TableReadEntry(table,i,j,flag);
00686   Tbl_EntryComplement(entry,0,(Var_VariableReadNumValues(Tbl_EntryReadActualVar(table, entry))) -1 );
00687 
00688 }
00689 
00703 void
00704 Tbl_TableSetEquality(
00705   Tbl_Table_t *  table,
00706   int  i,
00707   int  j,
00708   int flag,
00709   Var_Variable_t *  var)
00710 {
00711   Tbl_Entry_t *entry;
00712   int index,check;
00713   Var_Variable_t *tblVar;
00714 
00715   check =0;
00716   entry = Tbl_TableReadEntry(table,i,j,flag);
00717   Tbl_TableForEachInputVar(table, index,tblVar) {
00718     if (tblVar == var) {
00719       Tbl_EntrySetEqual(entry,index);
00720       check =1;
00721       break;
00722     }
00723   }
00724   
00725   if (check == 0) {
00726     printf(" WARNING: Output Equal Another Output not supported, no change made\n ");
00727   }
00728 }
00729 
00730 
00745 boolean
00746 Tbl_TableEntryIsDc(
00747   Tbl_Table_t *  table,
00748   int  i,
00749   int  j,
00750   int flag)
00751 {
00752   Tbl_Range_t *range;
00753   Tbl_Entry_t *entry;
00754   lsGen gen;
00755   Var_Variable_t *var;
00756   
00757   assert(table !=NIL(Tbl_Table_t));
00758 
00759   entry = Tbl_TableReadEntry(table,i,j,flag);
00760 
00761     if (lsLength(entry->EntryData.listOfRanges) == 1){
00762       var = Tbl_EntryReadActualVar(table,entry);
00763       lsForEachItem(entry->EntryData.listOfRanges, gen, range) {
00764         if ((range->begin ==0)&&(range->end ==
00765                                  Var_VariableReadNumValues(var)-1)){
00766           lsFinish(gen);
00767           return TRUE;
00768         }
00769       }
00770     }
00771   return FALSE;
00772 }
00773 
00774 
00793 boolean
00794 Tbl_TableTestIsConstant(
00795   Tbl_Table_t *  table,
00796   int            outputColumnId)
00797 {
00798   int colNum, rowNum;
00799   boolean check;
00800   Tbl_Entry_t *entry;
00801   Var_Variable_t *var;
00802   Tbl_Range_t *range;
00803   lsGen gen;
00804   int value, constant,count;
00805   
00806   
00807   assert(table !=NIL(Tbl_Table_t));
00808   assert((outputColumnId >= 0) && (outputColumnId <
00809                                    Tbl_TableReadNumOutputs(table)));
00810 
00811   if (Tbl_TableReadNumRows(table) == 1) {  
00812     if (array_n(table->inputNames) == 0) {
00813       entry = Tbl_TableReadEntry(table, 0, outputColumnId, 1);
00814       if (entry->type == Tbl_EntryNormal_c) {
00815         if (Tbl_EntryReadNumValues(entry) == 1) {
00816           return TRUE;
00817         }
00818       }
00819     }
00820     else {
00821       check = TRUE;
00822       Tbl_TableForEachInputEntry(table,rowNum,colNum,entry) {
00823         if (entry->type != Tbl_EntryNormal_c) {
00824           return FALSE;
00825         }
00826         if (check == TRUE) {
00827           check = FALSE;
00828           if (lsLength(entry->EntryData.listOfRanges) == 1){
00829             var = Tbl_EntryReadActualVar(table,entry);
00830             lsForEachItem(entry->EntryData.listOfRanges, gen, range) {
00831               if ((range->begin ==0)&&(range->end ==
00832                                        Var_VariableReadNumValues(var)-1)){
00833                 check = TRUE;
00834               }
00835             }
00836           }
00837         }
00838       }
00839       
00840       if (check) {
00841         entry = Tbl_TableReadEntry(table,0,outputColumnId,1);
00842         if (entry->type != Tbl_EntryNormal_c) {
00843           return FALSE;
00844         }            
00845         if (Tbl_EntryReadNumValues(entry) == 1) {
00846           return TRUE;
00847         }
00848       }
00849     }
00850   }
00851   else if (Tbl_TableReadNumRows(table) == 0) {
00852     entry = Tbl_TableDefaultReadEntry(table,outputColumnId);
00853     if (entry->type != Tbl_EntryNormal_c) {
00854       return FALSE;
00855     }    
00856     if (Tbl_EntryReadNumValues(entry) == 1) {
00857       return TRUE;
00858     }
00859   }
00860   else {
00861     entry = Tbl_TableDefaultReadEntry(table,outputColumnId);    
00862     if (entry == NIL(Tbl_Entry_t)){
00863       constant = -1;      
00864       Tbl_TableForEachOutputEntry(table,rowNum,colNum,entry) {
00865         if (colNum == outputColumnId) {
00866           if (entry->type != Tbl_EntryNormal_c){
00867             return FALSE;
00868           }          
00869           count = 1;
00870           Tbl_EntryForEachValue(entry,value,gen,range) {
00871             lsStatus status;
00872             if (count > 1) {
00873               status = lsFinish(gen); 
00874               assert(status == LS_OK);  
00875               return FALSE;
00876             }
00877             else {
00878               if (constant != -1) {
00879                 if (constant != value) {
00880                   status = lsFinish(gen);
00881                   assert(status == LS_OK); 
00882                   return FALSE;
00883                 }
00884               }
00885               else {
00886                 constant = value;
00887               }
00888             }
00889             count ++;        
00890           }
00891         }
00892       }
00893       return TRUE;
00894     }
00895   }
00896   return FALSE;
00897 }
00898 
00899 
00913 boolean
00914 Tbl_TableTestIsNonDeterministicConstant(
00915   Tbl_Table_t *  table,
00916   int            outputColumnId)
00917 {
00918   assert(table !=NIL(Tbl_Table_t));
00919   
00920   if (array_n(table->inputNames) == 0) {
00921     if (!Tbl_TableTestIsConstant(table, outputColumnId)) {
00922       return TRUE;
00923     }
00924   }
00925   
00926   return FALSE;
00927 }
00928 
00929 
00943 int
00944 Tbl_TableTestIsDeterministic(
00945   Tbl_Table_t *  table)
00946 {
00947 
00948 /* intersect every pair of input rows and
00949    then compare outputs if they're not same --- */
00950 /* Sunil Khatri is implementing this */
00951   return 0;
00952 }
00953 
00968 boolean
00969 Tbl_TableTestIsOutputSpaceComplete(
00970   Tbl_Table_t *table,
00971   mdd_manager *mddMgr)
00972 {
00973   int i, offset,rowNum,colNum,oldRowNum;
00974   boolean check;
00975   Mvf_Function_t *mvf;
00976   mdd_t *temp, *result, *function, *x;
00977   Var_Variable_t *var;
00978   Tbl_Entry_t *entry;
00979   array_t        *faninMvfArray ;
00980   array_t        *mvarValues ;
00981   int             numOutputs;
00982   
00983   if (Tbl_TableReadNumInputs(table) != 0) {
00984     return FALSE;
00985   }
00986 
00987   x = NIL(mdd_t);
00988   faninMvfArray     = array_alloc(Mvf_Function_t *, 0);
00989   mvarValues        = array_alloc(int, 0);
00990   numOutputs         = Tbl_TableReadNumOutputs(table );
00991 
00992   
00993   /* Add mdd's for new table input variables. */
00994   Tbl_TableForEachOutputVar(table, colNum, var) {
00995     array_insert_last(int, mvarValues, Var_VariableReadNumValues(var));
00996   }
00997   offset = array_n(mdd_ret_mvar_list(mddMgr));    
00998   mdd_create_variables(mddMgr,mvarValues, NIL(array_t), NIL(array_t));
00999   array_free(mvarValues);
01000 
01001   /*
01002    * Construct an MVF for each table input. The MVF for column i is the MVF
01003    * for MDD variable i.
01004    */
01005   for (i = 0; i < numOutputs; i++) {
01006     Mvf_Function_t *faninMvf = Mvf_FunctionCreateFromVariable(mddMgr, (i+offset));
01007     array_insert_last(Mvf_Function_t *, faninMvfArray, faninMvf);
01008   }
01009   /* Compute the MVF of the outputs */
01010 
01011 /* iterate over output part and compute all mvf's of rows */
01012 /* add to total */
01013   function = mdd_zero(mddMgr);
01014   oldRowNum = -1;
01015   result = mdd_zero(mddMgr);  
01016   Tbl_TableForEachOutputEntry(table,rowNum,colNum,entry) {    
01017     if (rowNum != oldRowNum) {
01018       temp =function;
01019       function = mdd_or(temp,result, 1,1);
01020       mdd_free(temp);
01021       mdd_free(result);        
01022       result = mdd_one(mddMgr);
01023     }
01024     if (entry->type == Tbl_EntryNormal_c) {
01025       mvf = array_fetch(Mvf_Function_t*,faninMvfArray,colNum);
01026       x = TblEntryNormalConstructMdd(mddMgr,entry,mvf);          
01027     }
01028     else  if (entry->type == Tbl_EntryEqual_c) {
01029       printf("Failure: output equal to another output construct not supported\n");
01030       assert(FALSE);
01031     }
01032     temp = result;
01033     result = mdd_and(x,temp,1,1);
01034     mdd_free(x);
01035     mdd_free(temp);
01036     oldRowNum = rowNum;
01037   }
01038   temp =function;
01039   function = mdd_or(temp,result, 1,1);
01040   mdd_free(temp);
01041   mdd_free(result);        
01042 
01043   check = mdd_is_tautology(function,1);
01044   mdd_free(function);
01045   
01046   for (i=0;i < array_n(faninMvfArray); i++){
01047     Mvf_FunctionFree(array_fetch(Mvf_Function_t *,faninMvfArray,i));
01048   }
01049   array_free(faninMvfArray);
01050   return check;
01051 }
01052 
01053 
01075 array_t *
01076 Tbl_TableComputeMvfAndInputDependenciesOfOutput(
01077   Tbl_Table_t *table,
01078   mdd_manager  *mddMgr,  
01079   int          outIndex,
01080   int *value)
01081 {
01082   int             i, offset;
01083   Mvf_Function_t *outMvf;
01084   Var_Variable_t *var;
01085   int             colNum;
01086   array_t        *faninMvfArray     = array_alloc(Mvf_Function_t *, 0);
01087   array_t        *mvarValues        = array_alloc(int, 0);
01088   array_t        *totalSupportArray = array_alloc(int, 0);
01089   int             numInputs         = Tbl_TableReadNumInputs(table );
01090   
01091   /* Add mdd's for new table input variables. */
01092   Tbl_TableForEachInputVar(table, colNum, var) {
01093     array_insert_last(int, mvarValues, Var_VariableReadNumValues(var));
01094   }
01095   offset = array_n(mdd_ret_mvar_list(mddMgr));    
01096   mdd_create_variables(mddMgr,mvarValues, NIL(array_t), NIL(array_t));
01097   array_free(mvarValues);
01098 
01099   /*
01100    * Construct an MVF for each table input. The MVF for column i is the MVF
01101    * for MDD variable i.
01102    */
01103   for (i = 0; i < numInputs; i++) {
01104     Mvf_Function_t *faninMvf = Mvf_FunctionCreateFromVariable(mddMgr, (i+offset));
01105     array_insert_last(Mvf_Function_t *, faninMvfArray, faninMvf);
01106   }
01107   /* Compute the MVF of the output indexed by outIndex. */
01108   outMvf = Tbl_TableBuildMvfFromFanins(table, outIndex, faninMvfArray, mddMgr);
01109   Mvf_FunctionArrayFree(faninMvfArray);
01110 
01111 
01112   totalSupportArray 
01113       = Mvf_FunctionComputeSupport(outMvf,mddMgr,value);
01114   
01115   Mvf_FunctionFree(outMvf);  
01116   return totalSupportArray;
01117 }
01118 
01119 
01143 Tbl_Table_t*
01144 Tbl_TableCreateTrueSupportTableForOutput(
01145   Tbl_Table_t *table,
01146   Mvf_Function_t *outMvf,
01147   mdd_manager *mddMgr,
01148   int offset,  
01149   int outIndex,
01150   array_t *varMap /* maps input column to mdd id */
01151   )
01152 {
01153   array_t *support;
01154   Tbl_Table_t * newTable;
01155   int i, inputId, rowNum, colNum, newColNum, newEqColNum, value, eqColNum;
01156   Tbl_Entry_t *newEntry, *entry;
01157   Var_Variable_t *var;
01158   Tbl_Row_t *row UNUSED;
01159   st_table *supLookup;
01160 
01161   newTable = Tbl_TableAlloc();  
01162   /* compute dependancies and put in a hash table */
01163 
01164   if (outMvf != NIL(Mvf_Function_t)) {
01165     support =
01166         Mvf_FunctionComputeSupport(outMvf,mddMgr,&value);
01167   }
01168   else {
01169     offset = array_n(mdd_ret_mvar_list(mddMgr));
01170     support =
01171         Tbl_TableComputeMvfAndInputDependenciesOfOutput(table,mddMgr,outIndex,&value);
01172   }
01173   
01174   if(support == NIL(array_t)) {
01175     /* create a constant table */
01176     var = Tbl_TableReadIndexVar(table,outIndex,1);
01177     Tbl_TableAddColumn(newTable,var,1);
01178     i  = Tbl_TableAddRow(newTable);
01179     newEntry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
01180     Tbl_TableSetEntry(newTable, newEntry, 0, 0, 1);
01181     Tbl_TableAddEntryRange(newTable,0,0,value,value,1);
01182     newEntry = NIL(Tbl_Entry_t);    
01183     (void) Tbl_TableDefaultSetEntry(newTable,newEntry,0);
01184     return newTable;
01185   }
01186 
01187   supLookup = st_init_table(st_numcmp, st_numhash);
01188 
01189   arrayForEachItem(int, support, i, inputId) {
01190     st_insert(supLookup,(char*)((long)(inputId - offset)),(char*)((long)i));
01191   }
01192   array_free(support);
01193 
01194   /* Account for multiple columns mapping to the same MDD variable.
01195    * There are two reasons why there may be fewer variables in the MVF
01196    * than there are input columns in a table:
01197    * 1. Multiple columns are tied to the same Var_Variable_t and hence
01198    *    get the same MDD variable.
01199    * 2. Variables that are in the apparent support of the table are not
01200    *    in the true support of the MVF.
01201    * The first reason is captured by varMap, the second by supLookup.
01202    * Now we merge the two and replace supLookup with the resulting table.
01203    */
01204   if (varMap != NIL(array_t)) {
01205     int mapped;
01206     int nCol = 0;
01207     Var_Ord_t *varArray = ALLOC(Var_Ord_t, array_n(varMap));
01208     arrayForEachItem(int, varMap, i, mapped) {
01209       int position;
01210       if (st_lookup_int(supLookup, (char*)(long) mapped, &position) == 1) {
01211         varArray[nCol].id = i;
01212         varArray[nCol].rank = position;
01213         nCol++;
01214       }
01215     }
01216     qsort((void *)varArray, nCol, sizeof(Var_Ord_t), varCompare);
01217     st_free_table(supLookup);
01218     supLookup = st_init_table(st_numcmp, st_numhash);
01219     for (i=0; i < nCol; i++) {
01220       st_insert(supLookup, (char*)((long)varArray[i].id), (char*)((long)i));
01221     }
01222     FREE(varArray);
01223   }
01224 
01225   /* foreach input var check if in true support and then insert */
01226   Tbl_TableForEachInputVar(table,i,var){
01227     if (st_lookup_int(supLookup, (char*)(long) i, &newColNum) == 1) {
01228       Tbl_TableAddColumn(newTable,var,0);
01229     }
01230   }
01231 
01232   /* insert only specified output */
01233   Tbl_TableForEachOutputVar(table,i,var){
01234     if (i == outIndex) {    
01235       Tbl_TableAddColumn(newTable,var,1);
01236     }  
01237   }
01238 
01239   /* add rows to this table */
01240 
01241   TblTableForEachRow(table, row, rowNum){
01242     i = Tbl_TableAddRow(newTable);
01243   }
01244 
01245   for (rowNum =0; rowNum < Tbl_TableReadNumRows(table); rowNum++ ) {
01246     for (colNum =0; colNum < Tbl_TableReadNumInputs(table); colNum++) {
01247       if (st_lookup_int(supLookup, (char*)(long) colNum, &newColNum) == 1) {
01248         entry = Tbl_TableReadEntry(table,rowNum, colNum, 0);
01249         newEntry = Tbl_EntryDup(entry);              
01250         if (Tbl_EntryIsEqual(entry)) {
01251           eqColNum = Tbl_EntryReadVarIndex(entry);
01252           if (st_lookup_int(supLookup,(char*)(long)eqColNum,&newEqColNum) == 0) {
01253             fail("Entry Equal Var not in True Support\n");
01254           }
01255           else {
01256             Tbl_EntrySetEqual(newEntry,newEqColNum);
01257           }
01258         }
01259         Tbl_TableSetEntry(newTable, newEntry, rowNum, newColNum, 0);      
01260       }
01261     }
01262   }
01263 
01264 
01265   for (rowNum =0; rowNum < Tbl_TableReadNumRows(table); rowNum++ ) {
01266     entry = Tbl_TableReadEntry(table,rowNum, outIndex, 1);
01267     newEntry = Tbl_EntryDup(entry);
01268     if (entry->type == Tbl_EntryEqual_c) {
01269       eqColNum = Tbl_EntryReadVarIndex(entry);
01270       if (st_lookup_int(supLookup,(char*)(long)eqColNum,&newEqColNum) == 0) {
01271         fail("Entry Equal Var not in True Support\n");
01272       }
01273       else {
01274         Tbl_EntrySetEqual(newEntry,newEqColNum);
01275       }
01276     }
01277     Tbl_TableSetEntry(newTable, newEntry, rowNum, 0, 1);
01278   }
01279   st_free_table(supLookup);
01280 
01281 
01282   Tbl_TableForEachDefaultEntry(table,entry,i) {
01283     if (i==outIndex) {        
01284       if (entry != NIL(Tbl_Entry_t)) {
01285         if (entry->type != Tbl_EntryEqual_c) {
01286           newEntry = Tbl_EntryDup(entry);
01287         }
01288         else{
01289           eqColNum =
01290             Tbl_TableReadVarIndex(newTable,Tbl_EntryReadVar(table,entry),0);
01291           if (eqColNum != -1) {
01292             newEntry = Tbl_EntryDup(entry);
01293             Tbl_EntrySetEqual(newEntry,eqColNum);
01294           }
01295           else {
01296             newEntry = NIL(Tbl_Entry_t);
01297           }
01298         }
01299       }
01300       else {
01301         newEntry = NIL(Tbl_Entry_t);
01302       }
01303       (void) Tbl_TableDefaultSetEntry(newTable,newEntry,0);
01304     }
01305   }
01306 
01307   return newTable;
01308 }
01309 
01322 boolean
01323 Tbl_TableSwapRows(
01324   Tbl_Table_t *  table,
01325   int  i,
01326   int  j)
01327 {
01328   Tbl_Row_t *rowi, *rowj;
01329     
01330   assert(table !=NIL(Tbl_Table_t));
01331   if (TblTableReadRefCount(table) > 1) {
01332     printf(" WARNING: You are modifying more than one table by swapping these rows\n");
01333   }
01334   
01335   rowi = TblTableReadRow(table,i);
01336   rowj = TblTableReadRow(table,j);
01337   TblTableSetRow(table,rowi,j);
01338   TblTableSetRow(table,rowj,i);
01339 
01340   return TRUE;
01341 }
01342   
01343 
01357 boolean
01358 Tbl_TableSwapColumns(
01359   Tbl_Table_t *  table,
01360   int  i,
01361   int  j,
01362   int  flag)
01363 {
01364   int k, rowNum,colNum,flag2;
01365   Tbl_Row_t *row UNUSED;
01366   Tbl_Entry_t *coli, *colj, *entry;
01367   array_t *rowArray;
01368   Var_Variable_t *vari, *varj;
01369     
01370   assert(table !=NIL(Tbl_Table_t));
01371   assert((flag==0)||(flag ==1));
01372   if (TblTableReadRefCount(table) > 1) {
01373     printf(" WARNING: You are modifying more than one table by swapping rows\n");
01374   }
01375   
01376   TblTableForEachRow(table,row,k) {
01377     coli = Tbl_EntryDup(Tbl_TableReadEntry(table,k,i,flag));
01378     colj = Tbl_EntryDup(Tbl_TableReadEntry(table,k,j,flag));    
01379 
01380     Tbl_TableSetEntry(table,coli,k,j,flag);
01381     Tbl_TableSetEntry(table,colj,k,i,flag);
01382   }
01383 
01384   if (flag == 0) {
01385     rowArray = table->inputNames;
01386   }
01387   else {
01388     rowArray = table->outputNames;
01389   }
01390 
01391   vari = array_fetch(Var_Variable_t*,rowArray,i);
01392   varj = array_fetch(Var_Variable_t*,rowArray,j);
01393   array_insert(Var_Variable_t*,rowArray,i,varj);
01394   array_insert(Var_Variable_t*,rowArray,j,vari);
01395 
01396   /* Correct Equal entries */
01397   Tbl_TableForEachEntry(table,rowNum,colNum,flag2,entry) {
01398     if (entry->type == Tbl_EntryEqual_c) {
01399       if (Tbl_EntryReadVarIndex(entry)==i){
01400         Tbl_EntrySetEqual(entry,j);
01401       }
01402       else if (Tbl_EntryReadVarIndex(entry)==j){
01403         Tbl_EntrySetEqual(entry,i);
01404       }      
01405     }
01406   }
01407 
01408   
01409   Tbl_TableForEachDefaultEntry(table,entry,colNum) {
01410     if (entry != NIL(Tbl_Entry_t)) {
01411     if (entry->type == Tbl_EntryEqual_c) {
01412       if (Tbl_EntryReadVarIndex(entry)==i){
01413         Tbl_EntrySetEqual(entry,j);
01414       }
01415       else if (Tbl_EntryReadVarIndex(entry)==j){
01416         Tbl_EntrySetEqual(entry,i);
01417       }      
01418     }
01419     }    
01420     }
01421   
01422   return TRUE;
01423 }
01424       
01446 void
01447 Tbl_TableCanonicalize(
01448     Tbl_Table_t * table)
01449 {
01450   int numRows, numInputs, numOutputs, rowNum, colNum;
01451   array_t *rowValArray;
01452   Tbl_Row_t *colVal;
01453   int i, val1,val2;
01454   
01455 
01456   numRows = Tbl_TableReadNumRows(table);
01457   numInputs = Tbl_TableReadNumInputs(table);
01458   numOutputs = Tbl_TableReadNumOutputs(table);
01459   
01460   rowValArray = TableCreatIntArray(numRows);
01461   colVal = ALLOC(Tbl_Row_t,1);
01462   colVal->inputs= TableCreatIntArray(numInputs);
01463   colVal->outputs= TableCreatIntArray(numOutputs);
01464 
01465   for(i=0; i< numRows; i++) {
01466     for(rowNum=0; rowNum< numRows-1; rowNum++) {
01467       if (Tbl_TableRowDominatesRow(table,rowNum,rowNum+1,rowValArray)) {
01468         Tbl_TableSwapRows(table,rowNum,rowNum+1);
01469         val1 = array_fetch(int,rowValArray,rowNum);
01470         val2 =array_fetch(int,rowValArray,rowNum+1);
01471         array_insert(int,rowValArray,rowNum,val2);
01472         array_insert(int,rowValArray,rowNum+1,val1);
01473       }
01474     }
01475   }
01476 
01477   for(i=0; i< numInputs; i++) {  
01478     for(colNum=0; colNum< numInputs-1; colNum++) {
01479       if (Tbl_TableColDominatesCol(table,colNum,colNum+1,0,colVal)) {
01480         Tbl_TableSwapColumns(table,colNum,colNum+1,0);
01481         val1 = array_fetch(int,TblRowReadInputs(colVal),colNum);
01482         val2 = array_fetch(int,TblRowReadInputs(colVal),colNum+1);
01483         array_insert(int,TblRowReadInputs(colVal),colNum,val2);
01484         array_insert(int,TblRowReadInputs(colVal),colNum+1,val1);
01485       }
01486     }
01487   }
01488 
01489   for(i=0; i< numOutputs; i++) {  
01490     for(colNum=0; colNum< numOutputs-1; colNum++) {
01491       if (Tbl_TableColDominatesCol(table,colNum,colNum+1,1,colVal)) {
01492         Tbl_TableSwapColumns(table,colNum,colNum+1,1);
01493         val1 = array_fetch(int,TblRowReadOutputs(colVal),colNum);
01494         val2 = array_fetch(int,TblRowReadOutputs(colVal),colNum+1);
01495         array_insert(int,TblRowReadOutputs(colVal),colNum,val2);
01496         array_insert(int,TblRowReadOutputs(colVal),colNum+1,val1);        
01497       }
01498     }
01499   }
01500   TblRowFree(colVal); 
01501   array_free(rowValArray);
01502 }
01515 boolean
01516 Tbl_TableRowDominatesRow(
01517   Tbl_Table_t *table,
01518   int rowa,
01519   int rowb,
01520   array_t *rowValArray)  
01521 {
01522   int valuea, valueb, totala, totalb;
01523   Tbl_Entry_t *entrya, *entryb;
01524   int colNum;
01525 
01526   
01527 
01528   valuea = array_fetch(int,rowValArray,rowa);
01529   totala = valuea;
01530   
01531   if (valuea == -1) {
01532     totala =0;    
01533     Tbl_RowForEachInputEntry(table,rowa,entrya,colNum) {
01534       valuea = TableEntryComputeHashVal(table,entrya);
01535       totala = valuea + totala;      
01536     }
01537     Tbl_RowForEachOutputEntry(table,rowa,entrya,colNum) {
01538       valuea = TableEntryComputeHashVal(table,entrya);
01539       totala = valuea + totala;      
01540     }        
01541     array_insert(int, rowValArray,rowa,totala);
01542   }
01543 
01544   valueb = array_fetch(int,rowValArray,rowb);
01545   totalb = valueb;
01546   
01547   if (valueb == -1) {
01548     totalb =0;    
01549     Tbl_RowForEachInputEntry(table,rowb,entryb,colNum) {
01550       valueb = TableEntryComputeHashVal(table,entryb);
01551       totalb = valueb + totalb;      
01552     }
01553     Tbl_RowForEachOutputEntry(table,rowb,entryb,colNum) {
01554       valueb = TableEntryComputeHashVal(table,entryb);
01555       totalb = valueb + totalb;      
01556     }        
01557     array_insert(int, rowValArray,rowb,totalb);
01558   }  
01559   
01560   if (totala < totalb ) {
01561     return FALSE;
01562   }
01563   else {
01564     return TRUE;
01565   }
01566 }  
01567 
01581 boolean
01582 Tbl_TableColDominatesCol(
01583   Tbl_Table_t *table,
01584   int cola,
01585   int colb,
01586   int flag,
01587   Tbl_Row_t *colValArray)  
01588 {
01589 
01590   int valuea, valueb, totala, totalb;
01591   Tbl_Entry_t *entrya, *entryb;
01592   int colNum, rowNum;
01593   
01594   if (flag == 0) {
01595     valuea = array_fetch(int,TblRowReadInputs(colValArray),cola);
01596   }
01597   else {
01598     valuea = array_fetch(int,TblRowReadOutputs(colValArray),cola);
01599   }
01600 
01601   totala = valuea;
01602   if (valuea == -1) {
01603   totala =0;
01604     if (flag ==0) {
01605       Tbl_TableForEachInputEntry(table,rowNum,colNum,entrya){
01606         if (colNum == cola) {
01607           valuea = TableEntryComputeHashVal(table,entrya);
01608           totala = valuea + totala;      
01609         }
01610       }
01611     array_insert(int, TblRowReadInputs(colValArray),cola,totala);      
01612     }
01613     else if (flag ==1) {
01614       Tbl_TableForEachOutputEntry(table,rowNum,colNum,entrya){
01615         if (colNum == cola) {    
01616           valuea = TableEntryComputeHashVal(table,entrya);
01617           totala = valuea + totala;      
01618         }
01619       }
01620     array_insert(int, TblRowReadOutputs(colValArray),cola,totala);      
01621     }
01622   }
01623 
01624   if (flag ==0) {
01625     valueb = array_fetch(int,TblRowReadInputs(colValArray),colb);
01626   }
01627   else {
01628     valueb = array_fetch(int,TblRowReadOutputs(colValArray),colb);
01629   }
01630   
01631   totalb = valueb;  
01632   if (valueb == -1) {
01633   totalb =0;  
01634     if (flag ==0) {
01635       Tbl_TableForEachInputEntry(table,rowNum,colNum,entryb){
01636         if (colNum == colb) {
01637           valueb = TableEntryComputeHashVal(table,entryb);
01638           totalb = valueb + totalb;      
01639         }
01640       }
01641     array_insert(int, TblRowReadInputs(colValArray),colb,totalb);      
01642     }
01643     else if (flag ==1) {
01644       Tbl_TableForEachOutputEntry(table,rowNum,colNum,entryb){
01645         if (colNum == colb) {    
01646           valuea = TableEntryComputeHashVal(table,entryb);
01647           totalb = valueb + totalb;      
01648         }
01649       }
01650     array_insert(int, TblRowReadOutputs(colValArray),colb,totalb);      
01651     }
01652   }
01653   
01654   if (totala < totalb ) {
01655     return FALSE;
01656   }
01657   else {
01658     return TRUE;
01659   }
01660 }
01661 
01675 boolean
01676 Tbl_TablesAreIdentical(
01677     Tbl_Table_t *tablea,
01678     Tbl_Table_t *tableb,
01679     int a,
01680     int b)
01681 {
01682   char *signaturea;
01683   char *signatureb;
01684 
01685   signaturea = TableObtainSignature(tablea, a);
01686   signatureb = TableObtainSignature(tableb, b);  
01687   if (strcmp(signaturea, signatureb) == 0) {
01688     FREE(signaturea);
01689     FREE(signatureb);    
01690     return TRUE;
01691   }
01692   FREE(signaturea);
01693   FREE(signatureb);    
01694   return FALSE;
01695 }
01696 
01697 
01698 
01713 mdd_t *
01714 Tbl_TableRowToMdd(
01715   Tbl_Table_t *  table,
01716   mdd_manager *  manager,
01717   int  i,
01718   array_t *  svArray /* array of array of mdd_t to be used */)
01719 {
01720   mdd_t *result, *finalResult, *temp;
01721   int j,k;
01722   Tbl_Entry_t *entry;
01723   Mvf_Function_t *mvf1, *mvf2;
01724     
01725 
01726   result = NIL(mdd_t);
01727   finalResult = mdd_one(manager);
01728     
01729   Tbl_RowForEachInputEntry(table,i,entry,j) {
01730     if ((entry->type) == Tbl_EntryNormal_c) {
01731       mvf1 = array_fetch(Mvf_Function_t*,svArray,j);
01732       result = TblEntryNormalConstructMdd(manager,entry,mvf1);
01733     }
01734     else if ((entry->type == Tbl_EntryEqual_c)) {
01735       k = Tbl_EntryReadVarIndex(entry);
01736       mvf1 = array_fetch(Mvf_Function_t*,svArray,j);
01737       mvf2 = array_fetch(Mvf_Function_t*,svArray,k);
01738       result = Mvf_FunctionsComputeEquivalentSet(mvf1,mvf2);
01739     }
01740     else if (entry->type == Tbl_EntryUnassigned_c) {
01741       return NIL(mdd_t);
01742     }
01743         
01744     temp = finalResult;
01745     finalResult = mdd_and(temp,result,1,1);
01746     mdd_free(temp);
01747     mdd_free(result);
01748   }
01749     
01750   Tbl_RowForEachOutputEntry(table,i,entry,j) {
01751     if ((entry->type) == Tbl_EntryNormal_c) {
01752       mvf1 = array_fetch(Mvf_Function_t*,svArray,j);
01753       result = TblEntryNormalConstructMdd(manager,entry,mvf1);
01754     }
01755     else if ((entry->type == Tbl_EntryEqual_c)) {
01756       k = Tbl_EntryReadVarIndex(entry);
01757       mvf1 = array_fetch(Mvf_Function_t*,svArray,j);
01758       mvf2 = array_fetch(Mvf_Function_t*,svArray,k);
01759       result = Mvf_FunctionsComputeEquivalentSet(mvf1,mvf2);
01760     }
01761     else if (entry->type == Tbl_EntryUnassigned_c) {
01762       return NIL(mdd_t);
01763     }
01764     
01765     temp = finalResult;
01766     finalResult = mdd_and(temp,result,1,1);
01767     mdd_free(temp);
01768     mdd_free(result);
01769   }
01770   return finalResult;
01771 }
01772 
01773 
01791 Mvf_Function_t *
01792 Tbl_TableBuildNonDetConstantMvf(
01793   Tbl_Table_t * table,
01794   int outIndex,
01795   int mddId,
01796   mdd_manager *  mddMgr)
01797 {
01798 
01799   lsGen gen;
01800   Tbl_Entry_t *entry;
01801   Tbl_Range_t *range;
01802   int value, rowNum, colNum;
01803   mdd_t *x;
01804   Mvf_Function_t *function;
01805   
01806   assert(Tbl_TableReadNumInputs(table) ==0);
01807 
01808   value = Var_VariableReadNumValues(Tbl_TableReadIndexVar(table,outIndex,1));
01809   function = Mvf_FunctionAlloc(mddMgr,value);
01810   
01811   Tbl_TableForEachOutputEntry(table,rowNum,colNum,entry) {
01812     if (colNum == outIndex) {
01813       assert(entry->type == Tbl_EntryNormal_c);
01814       Tbl_EntryForEachValue(entry,value,gen,range) {
01815         x = mdd_eq_c(mddMgr,mddId,value);
01816         Mvf_FunctionAddMintermsToComponent(function, value,x);
01817         mdd_free(x);
01818       }
01819     }
01820   }
01821   return function;
01822 }
01823 
01824 
01842 Mvf_Function_t *
01843 Tbl_TableBuildMvfFromFanins(
01844   Tbl_Table_t * table,
01845   int outIndex,
01846   array_t * faninArray,
01847   mdd_manager *  mddMgr)
01848 {
01849 
01850   lsGen gen;
01851   Tbl_Entry_t *entry, *entry2,*inputEntry;
01852   Tbl_Range_t *range;
01853   int value, rowNum, colNum, rowColNum, i;
01854   mdd_t *x, *result, *temp;
01855   Mvf_Function_t *function, *mvf1, *mvf2;
01856   
01857 
01858   x = NIL(mdd_t);
01859   value = Var_VariableReadNumValues(Tbl_TableReadIndexVar(table,outIndex,1));
01860   function = Mvf_FunctionAlloc(mddMgr,value);
01861   
01862   Tbl_TableForEachOutputEntry(table,rowNum,colNum,entry) {
01863     if (colNum == outIndex) {
01864       if (entry->type == Tbl_EntryNormal_c) {
01865         result = mdd_one(mddMgr);
01866         Tbl_RowForEachInputEntry(table,rowNum,inputEntry,rowColNum) {
01867           if (inputEntry->type == Tbl_EntryNormal_c) {
01868             mvf1 = array_fetch(Mvf_Function_t*,faninArray,rowColNum);
01869             x = TblEntryNormalConstructMdd(mddMgr,inputEntry,mvf1);
01870           }
01871           else if (inputEntry->type == Tbl_EntryEqual_c) {
01872             value =Tbl_EntryReadVarIndex(inputEntry);
01873             mvf1 = array_fetch(Mvf_Function_t*,faninArray,rowColNum);
01874             mvf2 = array_fetch(Mvf_Function_t*,faninArray,value);
01875             x = Mvf_FunctionsComputeEquivalentSet(mvf1,mvf2);
01876           }
01877           temp = result;
01878           result = mdd_and(x,temp,1,1);
01879           mdd_free(temp);
01880           mdd_free(x);
01881         }
01882         Tbl_EntryForEachValue(entry,value,gen,range) {  
01883           Mvf_FunctionAddMintermsToComponent(function, value,result);
01884         }
01885         mdd_free(result);
01886       }
01887       else  if (entry->type == Tbl_EntryEqual_c) {
01888         value = Tbl_EntryReadVarIndex(entry);
01889         if (value == -1) {
01890         fail("Failure: Not equal to any input var in this table\n");
01891         }
01892         
01893           
01894         /* must be equal to an input */
01895         
01896         entry2 = Tbl_TableReadEntry(table,rowNum,value,0);
01897         result = mdd_one(mddMgr);
01898         Tbl_RowForEachInputEntry(table,rowNum,inputEntry,rowColNum) {
01899           if (inputEntry->type == Tbl_EntryNormal_c) {
01900             mvf1 = array_fetch(Mvf_Function_t*,faninArray,rowColNum);
01901             x = TblEntryNormalConstructMdd(mddMgr,inputEntry,mvf1);
01902           }
01903           else if (inputEntry->type == Tbl_EntryEqual_c) {
01904             value =Tbl_EntryReadVarIndex(inputEntry);
01905             mvf1 = array_fetch(Mvf_Function_t*,faninArray,rowColNum);
01906             mvf2 = array_fetch(Mvf_Function_t*,faninArray,value);
01907             x = Mvf_FunctionsComputeEquivalentSet(mvf1,mvf2);
01908           }
01909           temp = result;
01910           result = mdd_and(x,temp,1,1);
01911           mdd_free(temp);
01912           mdd_free(x);
01913         }
01914 
01915         rowColNum = Tbl_EntryReadVarIndex(entry);
01916         mvf1 = array_fetch(Mvf_Function_t*,faninArray,rowColNum);        
01917         value = Var_VariableReadNumValues(Tbl_EntryReadActualVar(table,entry2));
01918         temp = result;
01919 
01920         for(i=0; i< value; i++) {
01921           x = Mvf_FunctionReadComponent(mvf1,i);
01922           result = mdd_and(temp,x,1,1);
01923           Mvf_FunctionAddMintermsToComponent(function, i,result);
01924           mdd_free(result);
01925         }
01926         mdd_free(temp);
01927       }  
01928     }
01929   }
01930 
01931   /* accounting for the defaults */
01932   entry = Tbl_TableDefaultReadEntry(table,outIndex);
01933   if (entry != NIL(Tbl_Entry_t)) {  
01934     temp = Mvf_FunctionComputeDomain(function);
01935     result = mdd_not(temp);
01936     mdd_free(temp);
01937 
01938     if (entry->type == Tbl_EntryNormal_c) {    
01939       Tbl_EntryForEachValue(entry,value,gen,range) {
01940         Mvf_FunctionAddMintermsToComponent(function, value,result);
01941       }
01942     }
01943     else {
01944       value = Tbl_EntryReadVarIndex(entry);
01945       if (value == -1) {
01946         fail("Failure: Not equal to any input var in this table\n");
01947       }
01948       mvf1 = array_fetch(Mvf_Function_t*,faninArray,value);
01949       
01950       Mvf_FunctionForEachComponent(mvf1,i,x) {
01951         temp = mdd_and(x,result,1,1);
01952         Mvf_FunctionAddMintermsToComponent(function, i ,temp);
01953         mdd_free(temp);
01954       }
01955     }
01956     
01957     mdd_free(result);    
01958   }
01959         
01960   return function;  
01961 }
01962 
01963   
01964         
01983 int
01984 Tbl_TableReadConstValue(
01985   Tbl_Table_t * table,
01986   int outputColumnId)
01987 {
01988   int colNum, rowNum;
01989   boolean check;
01990   Tbl_Entry_t *entry;
01991   Var_Variable_t *var;
01992   Tbl_Range_t *range;
01993   lsGen gen;
01994   int value, constant,count;
01995   
01996 
01997   constant = -1;
01998   assert(table !=NIL(Tbl_Table_t));
01999   assert((outputColumnId >= 0) && (outputColumnId <
02000                                    Tbl_TableReadNumOutputs(table)));
02001 
02002   if (Tbl_TableReadNumRows(table) == 1) {  
02003     if (array_n(table->inputNames) == 0) {
02004       entry = Tbl_TableReadEntry(table, 0, outputColumnId, 1);
02005       if (entry->type == Tbl_EntryNormal_c) {
02006         if (Tbl_EntryReadNumValues(entry) == 1) {
02007           Tbl_EntryForEachValue(entry,value,gen,range) {
02008             constant = value;
02009           }
02010           return constant;
02011         }
02012       }
02013     }
02014     else {
02015       check = TRUE;
02016       Tbl_TableForEachInputEntry(table,rowNum,colNum,entry) {
02017         if (entry->type != Tbl_EntryNormal_c) {
02018           return -1;
02019         }
02020         if (check == TRUE) {
02021           check = -1;
02022           if (lsLength(entry->EntryData.listOfRanges) == 1){
02023             var = Tbl_EntryReadActualVar(table,entry);
02024             lsForEachItem(entry->EntryData.listOfRanges, gen, range) {
02025               if ((range->begin ==0)&&(range->end ==
02026                                        Var_VariableReadNumValues(var)-1)){
02027                 check = TRUE;
02028               }
02029             }
02030           }
02031         }
02032       }
02033       
02034       if (check) {
02035         entry = Tbl_TableReadEntry(table,0,outputColumnId,1);
02036         if (entry->type != Tbl_EntryNormal_c) {
02037           return -1;
02038         }            
02039         if (Tbl_EntryReadNumValues(entry) == 1) {
02040           Tbl_EntryForEachValue(entry,value,gen,range) {
02041             constant = value;
02042           }
02043           return constant;
02044         }
02045       }
02046     }
02047   }
02048   else if (Tbl_TableReadNumRows(table) == 0) {
02049     entry = Tbl_TableDefaultReadEntry(table,outputColumnId);
02050     if (entry->type != Tbl_EntryNormal_c) {
02051       return -1;
02052     }    
02053     if (Tbl_EntryReadNumValues(entry) == 1) {
02054       Tbl_EntryForEachValue(entry,value,gen,range) {
02055         constant = value;
02056       }
02057       return constant;      
02058     }
02059   }
02060   else {
02061     entry = Tbl_TableDefaultReadEntry(table,outputColumnId);    
02062     if (entry == NIL(Tbl_Entry_t)){
02063       constant = -1;
02064       Tbl_TableForEachOutputEntry(table,rowNum,colNum,entry) {
02065         if (colNum == outputColumnId) {
02066           count = 1;
02067         if (entry->type != Tbl_EntryNormal_c){
02068           return -1;
02069         }          
02070           Tbl_EntryForEachValue(entry,value,gen,range) {
02071             lsStatus status;
02072             if (count > 1) {
02073               status = lsFinish(gen); 
02074               assert(status == LS_OK);
02075               return -1;
02076             }
02077             else {
02078               if (constant != -1) {
02079                 if (constant != value) {
02080                   status = lsFinish(gen); 
02081                   assert(status == LS_OK); 
02082                   return -1;
02083                 }
02084               }
02085               else {
02086                 constant = value;
02087               }
02088             }
02089             count ++;        
02090           }
02091         }
02092       }
02093       return constant;
02094     }
02095   }
02096   
02097   return -1;
02098 }
02099 
02111 Tbl_Table_t *
02112 Tbl_MddToTable(
02113   mdd_t *  mdd,
02114   mdd_manager *  manager,
02115   st_table *  idtoVar,
02116   array_t * inputids)
02117 {
02119   /* use foreach cube */
02120   printf("Not implemented as yet, contact gms@ic\n");
02121   return NIL(Tbl_Table_t);
02122 }
02123 
02124 
02139 boolean
02140 Tbl_TableSubstituteVar(
02141   Tbl_Table_t *  table,
02142   Var_Variable_t *  oldVar,
02143   Var_Variable_t *  newVar)
02144 {
02145   int i,k;
02146   int flag;
02147   Var_Variable_t *var;
02148 
02149 
02150   k = -1;
02151   flag =0;
02152   var = NIL(Var_Variable_t);
02153 
02154   if (!Var_VariablesTestHaveSameDomain(oldVar,newVar)) return FALSE;
02155 
02156   if (table != NIL(Tbl_Table_t)) {
02157     Tbl_TableForEachInputVar(table,i,var) {
02158       if (var == oldVar) {
02159         k = i;
02160         i = Tbl_TableReadNumInputs(table);
02161         flag = 0;
02162       }
02163     }
02164     if (k == -1) {
02165       Tbl_TableForEachOutputVar(table,i,var) {
02166         if (var == oldVar) {
02167           k = i;
02168           i = Tbl_TableReadNumOutputs(table);
02169           flag = 1;
02170         }
02171       }
02172     }
02173     if (k != -1) {
02174       Tbl_TableSetVar(table,k,newVar,flag);
02175       /* traverse all the entries of the table and change all the references
02176       to the old variable in the equal-to construct to the new variable */
02177       /* The above no longer has to be done as the entry refers to an
02178          index rather than the var */
02179       return TRUE;
02180     }
02181     else {
02182       return FALSE;
02183     }
02184   }
02185   return FALSE;
02186 }
02187 
02200 void
02201 Tbl_TableSetVar(
02202   Tbl_Table_t * table,
02203   int i,
02204   Var_Variable_t * sv,
02205   int flag)
02206 {
02207   array_t *svarray;
02208   
02209   if (flag==0){
02210     svarray = Tbl_TableReadInputVars(table);
02211   }
02212   else {
02213     svarray = Tbl_TableReadOutputVars(table);
02214   }
02215   
02216   array_insert(Var_Variable_t*,svarray,i,sv);
02217 }
02218 
02232 array_t *
02233 Tbl_TableSplit(
02234   Tbl_Table_t *  table)
02235 {
02236   int i,j, rowNum, colNum;
02237   array_t *resArray;
02238   Tbl_Table_t *newtable;
02239   Var_Variable_t *output, *input;
02240   Tbl_Entry_t *entry, *newEntry;
02241     
02242 
02243   resArray = array_alloc(Tbl_Table_t*,0);
02244     
02245   Tbl_TableForEachOutputVar(table,i,output) {
02246     newtable = Tbl_TableAlloc();
02247     Tbl_TableAddColumn(newtable,output,1);
02248     Tbl_TableForEachInputVar(table,colNum,input) {
02249       Tbl_TableAddColumn(newtable,input,0);
02250     }
02251     for (rowNum =0; rowNum < Tbl_TableReadNumRows(table); rowNum++) {
02252       (void) Tbl_TableAddRow(newtable);
02253     }
02254     
02255     Tbl_TableForEachEntry(table,rowNum,colNum,j,entry) {
02256       if (j==0) {
02257         newEntry = Tbl_EntryDup(entry);
02258         Tbl_TableSetEntry(newtable,newEntry,rowNum,colNum,0);
02259       }
02260       else {
02261         if (colNum ==i) {
02262           newEntry = Tbl_EntryDup(entry);
02263           Tbl_TableSetEntry(newtable,newEntry,rowNum,0,1);
02264         }
02265       }
02266     }
02267     entry = Tbl_TableDefaultReadEntry(table,i);
02268     if (entry != NIL(Tbl_Entry_t)) {
02269       newEntry = Tbl_EntryDup(entry);
02270       Tbl_TableDefaultSetEntry(newtable,newEntry,0);
02271     }
02272     
02273     array_insert_last(Tbl_Table_t*,resArray,newtable);
02274   }
02275   return resArray;
02276 }
02277   
02278 
02290 int 
02291 Tbl_TableReadNumInputs(
02292     Tbl_Table_t * table)
02293 {
02294   return(array_n(table->inputNames));
02295     
02296 }
02297   
02298 
02310 int
02311 Tbl_TableReadNumOutputs(
02312   Tbl_Table_t *  table)
02313 {
02314   return(array_n(table->outputNames));
02315 }
02316   
02329 int
02330 Tbl_TableReadNumVars(
02331   Tbl_Table_t *table,
02332   int flag)
02333 {
02334   if (flag==0) {
02335     return Tbl_TableReadNumInputs(table);
02336   }
02337   else {
02338     return Tbl_TableReadNumOutputs(table);
02339   }
02340 }
02341 
02353 int
02354 Tbl_TableReadNumRows(
02355   Tbl_Table_t *  table)
02356 {
02357   return(array_n(TblTableReadData(table)));
02358 }
02359   
02375 int
02376 Tbl_TableReadVarIndex(
02377   Tbl_Table_t *  table,
02378   Var_Variable_t *  var,
02379   int  flag /* Set to 0 if it is an input Var and 1 if it an output Var */
02380 )
02381 {
02382   int i;
02383   array_t *carray;
02384   Var_Variable_t *aVar;
02385 
02386   assert(table !=NIL(Tbl_Table_t));
02387   assert((flag==0)||(flag ==1));  
02388   
02389   if (flag==0) {
02390     carray = table->inputNames; 
02391   }
02392   else {
02393     carray = table->outputNames; 
02394   }
02395             
02396   for (i=0; i< array_n(carray);i++) {
02397     aVar = array_fetch(Var_Variable_t*,carray,i);
02398     if (var==aVar) {
02399       return i;
02400     }
02401   }
02402   return -1;
02403 }
02404 
02420 void
02421 Tbl_TablePrintStats(
02422   Tbl_Table_t *table,
02423     FILE *fp)
02424 {
02425   int rowNum, colNum,i,dc, total;
02426   Tbl_Entry_t *entry;
02427   Var_Variable_t *var;
02428   lsGen gen;
02429   Tbl_Range_t *range;
02430 
02431   fprintf(fp,"Table Stats\n");   
02432   fprintf(fp,"Number of  Inputs           = %d\n",Tbl_TableReadNumInputs(table));
02433   
02434   fprintf(fp,"Inputs                      :"); 
02435   Tbl_TableForEachInputVar(table,colNum,var){
02436     fprintf(fp,"%s ",Var_VariableReadName(var));
02437   }
02438   fprintf(fp,"\n");
02439   fprintf(fp,"Values                      :");
02440   
02441   Tbl_TableForEachInputVar(table,colNum,var){
02442     fprintf(fp,"%d ",Var_VariableReadNumValues(var));
02443   }
02444   fprintf(fp,"\n");  
02445   
02446   fprintf(fp,"Number of  Outputs          = %d\n",Tbl_TableReadNumOutputs(table));
02447   
02448   fprintf(fp,"Outputs                     :");
02449   
02450   Tbl_TableForEachOutputVar(table,colNum,var){
02451     fprintf(fp,"%s ",Var_VariableReadName(var));
02452   }
02453   fprintf(fp,"\n");
02454   fprintf(fp,"Values                      :");
02455   Tbl_TableForEachOutputVar(table,colNum,var){
02456     fprintf(fp,"%d ",Var_VariableReadNumValues(var));
02457   }
02458   fprintf(fp,"\n");    
02459   fprintf(fp,"Number of  Rows             = %d\n",Tbl_TableReadNumRows(table));
02460 
02461   dc = 0;
02462   total =0;
02463   Tbl_TableForEachEntry(table,rowNum,colNum,i,entry) {
02464     total++;
02465     if(entry->type == Tbl_EntryNormal_c) {    
02466       if (lsLength(entry->EntryData.listOfRanges) == 1){
02467         var = Tbl_EntryReadActualVar(table,entry);
02468         lsForEachItem(entry->EntryData.listOfRanges, gen, range) {
02469           if ((range->begin ==0)&&(range->end == Var_VariableReadNumValues(var)-1)){
02470             dc++;
02471           }
02472         }
02473       }
02474     }
02475   }
02476   if (total > 0) {
02477     i = 100 *dc/total;
02478   }
02479   else {
02480     i = 0;
02481   }
02482   
02483   fprintf(fp,"# Don't Care entries        = %d\n",dc);
02484   fprintf(fp,"Percent Don't Care entries  = %d\n",i);    
02485 }
02486 
02487 
02505 void
02506 Tbl_TableWriteBlifMvToFileSpecial(
02507     Tbl_Table_t *table,
02508     int flag,
02509     FILE *fp)
02510 {
02511   int rowNum, colNum,i;
02512   Tbl_Entry_t *entry;
02513   Var_Variable_t *var;
02514     
02515 
02516   if (flag ==0) {
02517     fprintf(fp,".table "); 
02518   }
02519   else {
02520     fprintf(fp,".reset ");
02521   }
02522     
02523   Tbl_TableForEachInputVar(table,colNum,var){
02524     fprintf(fp,"%s ",Var_VariableReadName(var));
02525   }
02526   fprintf(fp,"->"); 
02527   Tbl_TableForEachOutputVar(table,colNum,var){
02528     fprintf(fp,"%s_bufin ",Var_VariableReadName(var));
02529   }
02530   fprintf(fp,"\n");
02531 
02532   if ((array_fetch(Tbl_Entry_t*, TblTableReadDefaults(table),0)) != NIL(Tbl_Entry_t)) {
02533     fprintf(fp,".default ");
02534     Tbl_TableForEachDefaultEntry(table,entry,colNum) {
02535       TblEntryWriteBlifMv(table,entry,fp);
02536       fprintf(fp," ");
02537     }
02538     fprintf(fp,"\n");
02539   }
02540 
02541    Tbl_TableForEachEntry(table, rowNum,colNum,i,entry) { 
02542     TblEntryWriteBlifMv(table,entry,fp);
02543     fprintf(fp," ");    
02544     if ((colNum == (Tbl_TableReadNumOutputs(table) -1))&&(i==1)) {
02545       fprintf(fp,"\n");
02546     }
02547   }
02548 }
02549 
02567 void
02568 Tbl_TableWriteBlifMvToFile(
02569     Tbl_Table_t *table,
02570     int flag,
02571     FILE *fp)
02572 {
02573   int rowNum, colNum,i;
02574   Tbl_Entry_t *entry;
02575   Var_Variable_t *var;
02576     
02577 
02578   if (flag == 0) {
02579     fprintf(fp,".table "); 
02580   }
02581   else if (flag == 1) {
02582     fprintf(fp,".reset ");
02583   }
02584 
02585   if (flag < 2) {
02586     Tbl_TableForEachInputVar(table,colNum,var){
02587       fprintf(fp,"%s ",Var_VariableReadName(var));
02588     }
02589     fprintf(fp,"->"); 
02590     Tbl_TableForEachOutputVar(table,colNum,var){
02591       fprintf(fp," %s",Var_VariableReadName(var));
02592     }
02593     fprintf(fp,"\n");
02594   }
02595 
02596   if ((array_fetch(Tbl_Entry_t*, TblTableReadDefaults(table),0)) != NIL(Tbl_Entry_t)) {
02597     fprintf(fp,".default");
02598     Tbl_TableForEachDefaultEntry(table,entry,colNum) {
02599       fprintf(fp," ");
02600       TblEntryWriteBlifMv(table,entry,fp);
02601     }
02602     fprintf(fp,"\n");
02603   }
02604 
02605    Tbl_TableForEachEntry(table,rowNum,colNum,i,entry) { 
02606     TblEntryWriteBlifMv(table,entry,fp);
02607     if ((colNum == (Tbl_TableReadNumOutputs(table) -1))&&(i==1)) {
02608       fprintf(fp,"\n");
02609     } else {
02610       fprintf(fp," ");    
02611     }
02612   }
02613 }
02614 
02631 void
02632 Tbl_TableWriteSmvToFile(
02633     Tbl_Table_t *table,
02634     int flag,
02635     FILE *fp)
02636 {
02637   int rowNum, colNum,i;
02638   Tbl_Entry_t *entry;
02639   Var_Variable_t *var;
02640 
02641   if (flag ==0) { 
02642     fprintf(fp,"\n-- Table for ");
02643   }
02644   else {
02645     fprintf(fp,"\n-- Reset table for ");
02646   }
02647   Tbl_TableForEachInputVar(table,colNum,var){
02648     fprintf(fp,"%s ",Var_VariableReadName(var));
02649   }
02650   fprintf(fp,"->"); 
02651   Tbl_TableForEachOutputVar(table,colNum,var){
02652     fprintf(fp,"%s ",Var_VariableReadName(var));
02653   }
02654   fprintf(fp,"\n");
02655 
02656   if (flag ==0) { 
02657 
02658     fprintf(fp, "INVAR\n( ");
02659 
02660     Tbl_TableForEachEntry(table, rowNum,colNum,i,entry) { 
02661       TblEntryWriteSmv(table,entry,0,fp);
02662       if ((colNum == (Tbl_TableReadNumOutputs(table) -1))&&(i==1)) {
02663         if(rowNum < Tbl_TableReadNumRows(table) -1) {
02664             fprintf(fp,") |\n( ");
02665         }
02666       } else {
02667         fprintf(fp,"& ");    
02668       }
02669     }
02670     
02671     if ((array_fetch(Tbl_Entry_t*, TblTableReadDefaults(table),0)) != NIL(Tbl_Entry_t)) {
02672       fprintf(fp,") |\n( ");
02673    
02674       if (Tbl_TableReadNumInputs(table) > 0) {
02675         fprintf(fp,"!( (");
02676       }
02677       Tbl_TableForEachInputEntry(table, rowNum,colNum,entry) { 
02678         TblEntryWriteSmv(table,entry,0,fp);
02679         if (colNum == (Tbl_TableReadNumInputs(table) -1)) {
02680           if(rowNum < Tbl_TableReadNumRows(table) -1) {
02681             fprintf(fp,") | ( ");
02682           }
02683         } else {
02684           fprintf(fp,"& ");    
02685         }
02686       }
02687       if (Tbl_TableReadNumInputs(table) > 0) {
02688         fprintf(fp,") ) & ");
02689       }
02690       
02691       Tbl_TableForEachDefaultEntry(table,entry,colNum) {
02692         TblEntryWriteSmv(table,entry,0,fp);
02693         if (colNum < (Tbl_TableReadNumOutputs(table) -1)) {
02694           fprintf(fp,"& ");    
02695         }
02696       }
02697     }
02698     fprintf(fp,")\n");
02699 
02700   } else {
02701 
02702     fprintf(fp,"case\n");
02703 
02704     Tbl_TableForEachEntry(table, rowNum,colNum,i,entry) { 
02705       TblEntryWriteSmv(table,entry,i,fp);
02706       if ((colNum == (Tbl_TableReadNumInputs(table) -1))&&(i==0)) {
02707         fprintf(fp,": ");
02708       } else if ((colNum == (Tbl_TableReadNumOutputs(table) -1))&&(i==1)) {
02709         fprintf(fp,";\n");    
02710       } else {
02711         fprintf(fp,"& ");    
02712       }
02713     }
02714     
02715     if ((array_fetch(Tbl_Entry_t*, TblTableReadDefaults(table),0)) != NIL(Tbl_Entry_t)) {
02716       fprintf(fp,"1 : ");
02717       
02718       Tbl_TableForEachDefaultEntry(table,entry,colNum) {
02719         TblEntryWriteSmv(table,entry,1,fp);
02720       }
02721       fprintf(fp,";\n");
02722     }
02723 
02724     fprintf(fp,"esac;\n");
02725   }
02726     
02727 }
02728 
02729  
02730 
02742 void
02743 Tbl_TableWriteBlifToFile(
02744   Tbl_Table_t *table,
02745   FILE *fp    
02746     )
02747 {                     
02748   int numInputs, numOutputs, numRows, colnum, i, j;
02749   Var_Variable_t *var;
02750   Tbl_Entry_t *entry;
02751   lsGen gen;
02752   Tbl_Range_t *range;
02753   int value, flag;
02754 
02755 
02756   fprintf(fp,".names ");     
02757   for (colnum=0; colnum < Tbl_TableReadNumInputs(table); colnum++) {
02758     var = Tbl_TableReadIndexVar(table, colnum, 0);
02759     fprintf(fp,"%s ",Var_VariableReadName(var));
02760   }
02761   for (colnum=0; colnum < Tbl_TableReadNumOutputs(table); colnum++) {
02762     var = Tbl_TableReadIndexVar(table, colnum, 1);
02763     fprintf(fp,"%s ",Var_VariableReadName(var));
02764   }
02765   fprintf(fp,"\n");
02766 
02767 
02768   numInputs = Tbl_TableReadNumInputs(table);
02769   numOutputs = Tbl_TableReadNumOutputs(table);
02770   numRows = Tbl_TableReadNumRows(table);
02771 
02772 
02773   for (i=0; i < numRows; i++) {
02774     flag =1;
02775   
02776     if (numOutputs == 1) {
02777       entry =  Tbl_TableReadEntry(table, i, 0, 1);
02778       if (Tbl_EntryReadNumValues(entry) ==1 ){
02779         Tbl_EntryForEachValue(entry,value,gen,range){
02780           if (value ==0) {
02781             flag = 0;
02782           }
02783         }
02784       }
02785     }
02786     if (flag ==1) {      
02787       for(j = 0; j < numInputs; j++){
02788         entry = Tbl_TableReadEntry(table, i, j, 0);
02789         TblEntryWriteBlif(table,entry,fp);
02790       }
02791       fprintf(fp," ");
02792     
02793       for(j = 0; j < numOutputs; j++){
02794         entry = Tbl_TableReadEntry(table, i, j, 1);
02795         TblEntryWriteBlif(table,entry,fp);
02796       }
02797       fprintf(fp,"\n");      
02798     }
02799   }
02800 }
02801 
02802 
02818 array_t*
02819 Tbl_TableReadDefaults(
02820     Tbl_Table_t * table)
02821 {
02822   return (table->data->defaults);
02823 }
02824 
02840 array_t*
02841 Tbl_TableReadInputVars(
02842     Tbl_Table_t * table)
02843 {
02844   return (table->inputNames);
02845 }
02846 
02862 array_t*
02863 Tbl_TableReadOutputVars(
02864     Tbl_Table_t * table)
02865 {
02866   return (table->outputNames);
02867 }
02868 
02869 
02882 boolean
02883 Tbl_RowInputIntersect(
02884   Tbl_Table_t * table,
02885   int a,
02886   int b)
02887 {
02888   int colNum, check;
02889   Tbl_Entry_t *entrya, *entryb;
02890   Tbl_Row_t *rowb;
02891   
02892   check = FALSE;
02893   rowb = TblTableReadRow(table,b);
02894   
02895   Tbl_RowForEachInputEntry(table,a, entrya, colNum){
02896     entryb = TblRowReadEntry(rowb,colNum,0);
02897     check = Tbl_EntryTestIntersectEntry(entrya,entryb);
02898 
02899     if (check == FALSE) {
02900       return FALSE;
02901     }    
02902   }
02903   return TRUE;    
02904 }
02905 
02906 
02919 boolean
02920 Tbl_RowOutputIntersect(
02921   Tbl_Table_t * table,
02922   int a,
02923   int b)
02924 {
02925   int colNum, check;
02926   Tbl_Entry_t *entrya, *entryb;
02927   Tbl_Row_t *rowb;
02928   
02929   check = FALSE;
02930   rowb = TblTableReadRow(table,b);
02931   
02932   Tbl_RowForEachOutputEntry(table,a, entrya, colNum){
02933     entryb = TblRowReadEntry(rowb,colNum,1);
02934     check = Tbl_EntryTestIntersectEntry(entrya,entryb);
02935 
02936     if (check == FALSE) {
02937       return FALSE;
02938     }    
02939   }
02940   return TRUE;    
02941 
02942 }
02943 
02944 /*---------------------------------------------------------------------------*/
02945 /* Definition of internal functions                                          */
02946 /*---------------------------------------------------------------------------*/
02959 void
02960 TblTableSetRow(
02961   Tbl_Table_t *table,
02962   Tbl_Row_t *row,
02963   int i)
02964 {
02965   array_insert(Tbl_Row_t*, TblTableReadData(table),i,row);
02966 }
02967 
02983 array_t*
02984 TblRowReadOutputs(
02985     Tbl_Row_t * row)
02986 {
02987   return (row->outputs);
02988 }
02989 
03005 array_t*
03006 TblRowReadInputs(
03007     Tbl_Row_t * row)
03008 {
03009   return (row->inputs);
03010 }
03011 
03024 Tbl_Row_t*
03025 TblTableReadRow(
03026   Tbl_Table_t *table,
03027   int rowNum)
03028 {
03029   return(array_fetch(Tbl_Row_t*,TblTableReadData(table),rowNum));
03030 }
03031 
03032 
03044 Tbl_Row_t*
03045 TblRowAlloc(void)
03046 {
03047   Tbl_Row_t *row;
03048 
03049   row = ALLOC(Tbl_Row_t,1);
03050   row->inputs = array_alloc(Tbl_Entry_t*,0);
03051   row->outputs = array_alloc(Tbl_Entry_t*,0);
03052 
03053   return row;
03054 }
03055 
03056 
03068 Tbl_Row_t*
03069 TblRowDup(
03070   Tbl_Row_t * row)
03071 {
03072   Tbl_Row_t *newrow;
03073   Tbl_Entry_t *newEntry, *entry;
03074   int i;
03075 
03076   newrow = TblRowAlloc();
03077 
03078   for (i=0; i < array_n(row->inputs); i++){
03079     entry = array_fetch(Tbl_Entry_t*,row->inputs,i);
03080     if (entry != NIL(Tbl_Entry_t)) {
03081       newEntry= Tbl_EntryDup(entry);
03082     }
03083     else {
03084       newEntry = NIL(Tbl_Entry_t);
03085     }
03086     TblRowSetEntry(newrow,newEntry,i,0);
03087   }
03088 
03089   for (i=0; i < array_n(row->outputs); i++){
03090     entry = array_fetch(Tbl_Entry_t*,row->outputs,i);    
03091     if (entry != NIL(Tbl_Entry_t)) {
03092       newEntry = Tbl_EntryDup(entry);
03093     }
03094     else {
03095       newEntry = NIL(Tbl_Entry_t);
03096     }      
03097     TblRowSetEntry(newrow,newEntry,i,1);
03098   }
03099   return newrow;
03100 }
03101 
03115 void
03116 TblRowSetEntry(
03117   Tbl_Row_t *row,
03118   Tbl_Entry_t * entry,
03119   int i,
03120   int flag)
03121 {
03122   array_t *carray;
03123   
03124   if (flag ==0) {
03125     carray = TblRowReadInputs(row);
03126   }
03127   else {
03128     carray = TblRowReadOutputs(row);
03129   }
03130     
03131   if (i < array_n(carray)){
03132     array_insert(Tbl_Entry_t*,carray,i,entry);
03133   }
03134   else {
03135     array_insert_last(Tbl_Entry_t*,carray,entry);
03136   }
03137 }
03138 
03151 void
03152 TblRowFree(
03153   Tbl_Row_t *row)
03154 {
03155   assert(row != NIL(Tbl_Row_t));
03156   array_free(row->inputs);
03157   array_free(row->outputs);
03158   FREE(row);
03159 }
03160 
03161 
03175 Tbl_Entry_t*
03176 TblRowReadEntry(
03177     Tbl_Row_t *row,
03178     int i,
03179     int flag)
03180 {
03181   
03182   if (flag==0) {
03183     return(array_fetch(Tbl_Entry_t*,TblRowReadInputs(row),i));
03184   }
03185   else {
03186     return(array_fetch(Tbl_Entry_t*, TblRowReadOutputs(row),i));
03187   }
03188 }
03189 
03190 
03191 /*---------------------------------------------------------------------------*/
03192 /* Definition of static functions                                            */
03193 /*---------------------------------------------------------------------------*/
03194 
03207 static int
03208 TableEntryComputeHashVal(
03209   Tbl_Table_t *table,
03210   Tbl_Entry_t *entry)
03211 {
03212   int numRows, numCols;
03213   lsGen gen;
03214   int value;
03215   Tbl_Range_t *range;
03216   int total;
03217 
03218   numRows = Tbl_TableReadNumRows(table);
03219   numCols = Tbl_TableReadNumInputs(table) + Tbl_TableReadNumOutputs(table) + numRows+1;
03220   total = 0;
03221 
03222   if(entry->type == Tbl_EntryNormal_c) {
03223     Tbl_EntryForEachValue(entry,value,gen,range) {
03224       total = total + (int) pow(numCols,value);
03225     }
03226   }
03227   else if(entry->type == Tbl_EntryEqual_c) {
03228     value = Var_VariableReadNumValues(Tbl_EntryReadActualVar(table,entry));
03229     total = total + (int) pow(numCols,value);
03230   }
03231   
03232   return total;
03233 }
03234 
03247 static array_t*
03248 TableCreatIntArray(
03249   int size)
03250 {
03251   array_t *result;
03252   int i;
03253   
03254   result = array_alloc(int,0);
03255   for (i=0; i < size; i++) {
03256     array_insert_last(int,result,-1);
03257   }
03258   return result;
03259 }
03260 
03261 
03274 static char*
03275 TableObtainSignature(Tbl_Table_t * table,
03276                      int outputColumn)
03277 {
03278   char *                signature;
03279   char *                sig;            /* Signature under construction */
03280 
03281   int                   row;            /* locations in the table */
03282   int                   column;
03283 
03284   Tbl_Entry_t *         entry;          /* Entry at row, column */
03285 
03286   int                   value;          /* Value of an entry */
03287   lsGen                 gen;            /* For Tbl_EntryForEachValue */
03288   Tbl_Range_t *         range;
03289 
03290   int                   varIndex;       /* Index of the column of this variable */
03291 
03292   /*
03293    * TODO: This is unsafe!
03294    */
03295 
03296   signature = ALLOC( char, 10000 );
03297   sig = signature;
03298 
03299   for ( row = Tbl_TableReadNumRows( table ) ; --row >=0 ; ) {
03300 
03301     /*
03302      * Print each of the inputs in this row
03303      */
03304 
03305     Tbl_RowForEachInputEntry( table, row, entry, column ) {
03306 
03307       switch ( Tbl_EntryReadType( entry ) ) {
03308 
03309         /*
03310          * An equality entry ("this column is equal to that column")
03311          */
03312 
03313       case Tbl_EntryEqual_c:
03314 
03315         /*
03316          * Find the column index, first assuming it's an input
03317          */
03318 
03319         varIndex = Tbl_EntryReadVarIndex(entry);
03320 
03321         sprintf( sig, "=%d", varIndex );
03322         sig += strlen( sig );
03323         break;
03324 
03325         /*
03326          * A normal range entry - print a comma-separated list of values
03327          */
03328 
03329       case Tbl_EntryNormal_c:
03330         Tbl_EntryForEachValue( entry, value, gen, range ) {
03331           sprintf(sig, "%d,", value );
03332           sig += strlen( sig );
03333         }
03334         break;
03335 
03336         /*
03337          * Unassigned -- append a "?"
03338          */
03339 
03340       case Tbl_EntryUnassigned_c:
03341         sig[0] = '?';
03342         sig++;
03343         break;
03344         /*
03345          * None of the Above -- we're in trouble
03346          */
03347 
03348       default:
03349         assert(0);
03350         break;
03351 
03352       }
03353       
03354       /*
03355        * Separate entries with spaces
03356        */
03357       
03358       sig[0] = ' ';
03359       sig++;
03360 
03361     }
03362 
03363     /*
03364      * Print the output column's entry
03365      */
03366 
03367     entry = Tbl_TableReadEntry( table, row, outputColumn, 1 );
03368 
03369     switch ( Tbl_EntryReadType( entry ) ) {
03370 
03371       /*
03372        * An equality entry ("this column is equal to that column")
03373        */
03374 
03375     case Tbl_EntryEqual_c:
03376 
03377       /*
03378        * Find the column index, first assuming it's an input
03379        */
03380 
03381       varIndex = Tbl_EntryReadVarIndex(entry);
03382 
03383       sprintf( sig, "=%d", varIndex );
03384       sig += strlen( sig );
03385       break;
03386       
03387       /*
03388        * A normal range entry - print a comma-separated list of values
03389        */
03390       
03391     case Tbl_EntryNormal_c:
03392       Tbl_EntryForEachValue( entry, value, gen, range ) {
03393         sprintf(sig, "%d,", value );
03394         sig += strlen( sig );
03395       }
03396       break;
03397       
03398       /*
03399        * Unassigned -- append a "?"
03400        */
03401       
03402     case Tbl_EntryUnassigned_c:
03403       sig[0] = '?';
03404       sig++;
03405       break;
03406       
03407       /*
03408        * None of the Above -- we're in trouble
03409        */
03410       
03411     default:
03412       assert(0);
03413       break;
03414       
03415     }
03416 
03417     /*
03418      * Separate rows with newlines
03419      */
03420 
03421     sig[0] = '\n';
03422     sig++;
03423 
03424   }
03425 
03426   /*
03427    * Terminate the signature string
03428    */
03429 
03430   sig[0] = '\0';
03431 
03432   return signature;
03433 }     
03434 
03435 
03448 static int
03449 varCompare(const void *x, const void *y)
03450 {
03451   Var_Ord_t *a = (Var_Ord_t *) x;
03452   Var_Ord_t *b = (Var_Ord_t *) y;
03453   return(a->rank - b->rank);
03454 }