VIS
|
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 }