VIS
|
00001 00033 #include "tblInt.h" 00034 00035 static char rcsid[] UNUSED = "$Id: tblSweep.c,v 1.12 2009/04/11 18:26:45 fabio Exp $"; 00036 00039 /*---------------------------------------------------------------------------*/ 00040 /* Static function prototypes */ 00041 /*---------------------------------------------------------------------------*/ 00042 00043 static void SetAdjustedEntry(Tbl_Table_t *table, Tbl_Entry_t *entry, int index, int rownum, int colnum, boolean flag); 00044 static void SetEntry(Tbl_Table_t *newTable, Tbl_Entry_t *entry1, Tbl_Entry_t *entry2, int rownum, int colnum, int index, boolean flag); 00045 00049 /*---------------------------------------------------------------------------*/ 00050 /* Definition of exported functions */ 00051 /*---------------------------------------------------------------------------*/ 00078 Tbl_Table_t* 00079 Tbl_TableCollapse(Tbl_Table_t* table1, Tbl_Table_t* table2,int index) 00080 { 00081 int rownum, realRowNum, colnum,eqcolnum,count,check; 00082 Var_Variable_t *var; 00083 Tbl_Table_t *newTable; 00084 Tbl_Entry_t *entry1, *entry2; 00085 Tbl_Entry_t *testEntry; 00086 00087 if (Tbl_TableReadNumOutputs(table2)==1){ 00088 newTable = Tbl_TableAlloc(); 00089 00090 if (Tbl_TableReadNumRows(table2) !=0) { 00091 entry2 = Tbl_TableReadEntry(table2,0,0,1); 00092 } 00093 else { 00094 entry2 = Tbl_TableDefaultReadEntry(table2,0); 00095 } 00096 /* add every input column except collapsing input */ 00097 for(colnum=0;colnum < Tbl_TableReadNumInputs(table1); colnum++) { 00098 if (colnum != index) { 00099 var = Tbl_TableReadIndexVar(table1,colnum,0); 00100 Tbl_TableAddColumn(newTable,var,0); 00101 } 00102 } 00103 for(colnum=0;colnum < Tbl_TableReadNumOutputs(table1); colnum++) { 00104 var = Tbl_TableReadIndexVar(table1,colnum,1); 00105 Tbl_TableAddColumn(newTable,var,1); 00106 } 00107 /* (void) Tbl_TableAddRow(newTable); */ 00108 00109 00110 realRowNum =0; 00111 eqcolnum = index; 00112 00113 /* row by row, check if var has given constant value */ 00114 for(rownum=0; rownum< Tbl_TableReadNumRows(table1); rownum++) { 00115 testEntry = Tbl_TableReadEntry(table1,rownum,index,0); 00116 assert(entry2->type == Tbl_EntryNormal_c); 00117 00118 /* input column by column */ 00119 if (testEntry->type == Tbl_EntryNormal_c){ 00120 if (Tbl_EntryTestIntersectEntry(testEntry,entry2)){ 00121 (void) Tbl_TableAddRow(newTable); 00122 00123 for(colnum=0;colnum < Tbl_TableReadNumInputs(table1); colnum++) { 00124 entry1= Tbl_TableReadEntry(table1,rownum,colnum,0); 00125 SetEntry(newTable,entry1,entry2,realRowNum,colnum,index,0); 00126 } 00127 00128 /* do outputs */ 00129 for(colnum=0;colnum < Tbl_TableReadNumOutputs(table1); colnum++) { 00130 entry1= Tbl_TableReadEntry(table1,rownum,colnum,1); 00131 SetEntry(newTable,entry1,entry2,realRowNum,colnum,index,1); 00132 } 00133 realRowNum++; 00134 } 00135 } 00136 else if (testEntry->type == Tbl_EntryEqual_c){ 00137 count = 0; 00138 check = 0; 00139 while(count<= Tbl_TableReadNumInputs(table1)){ 00140 00141 /* Find out the column the entry equal to 00142 * and set that column entry to constant value if 00143 * its is of type Equal. This gets propagated by the while count 00144 * loop until you find a non-equal entry, and then it checks 00145 * for an intersection. If no intersection, then it 00146 * nullifies the row. Alas, there was no easier way */ 00147 if (testEntry->type == Tbl_EntryNormal_c){ 00148 if (Tbl_EntryTestIntersectEntry(testEntry,entry2)){ 00149 check = 1; 00150 } 00151 count = Tbl_TableReadNumInputs(table1)+1; 00152 } 00153 else { 00154 eqcolnum = Tbl_EntryReadVarIndex(testEntry); 00155 testEntry = Tbl_TableReadEntry(table1,rownum,eqcolnum,0); 00156 } 00157 if (count == Tbl_TableReadNumInputs(table1)){ 00158 check = 1; 00159 } 00160 count ++; 00161 } 00162 00163 if (check == 1) { 00164 (void) Tbl_TableAddRow(newTable); 00165 count = 0; 00166 eqcolnum = index; 00167 testEntry = Tbl_TableReadEntry(table1,rownum,index,0); 00168 while(count<= Tbl_TableReadNumInputs(table1)){ 00169 if (testEntry->type == Tbl_EntryNormal_c){ 00170 SetEntry(newTable,entry2,entry2,realRowNum,eqcolnum,index,0); 00171 count = Tbl_TableReadNumInputs(table1)+1 ; 00172 } 00173 else { 00174 eqcolnum = Tbl_EntryReadVarIndex(testEntry); 00175 testEntry = Tbl_TableReadEntry(table1,rownum,eqcolnum,0); 00176 count ++; 00177 } 00178 } 00179 /* end of while */ 00180 /* fill in zero entries */ 00181 for(colnum=0;colnum < Tbl_TableReadNumInputs(table1); colnum++) { 00182 entry1= Tbl_TableReadEntry(table1,rownum,colnum,0); 00183 SetAdjustedEntry(newTable,Tbl_EntryDup(entry1),index,rownum,colnum,0); 00184 } 00185 /* do outputs */ 00186 for(colnum=0;colnum < Tbl_TableReadNumOutputs(table1); colnum++) { 00187 entry1= Tbl_TableReadEntry(table1,rownum,colnum,1); 00188 SetEntry(newTable,entry1,entry2,realRowNum,colnum,index,1); 00189 00190 } 00191 } 00192 realRowNum++; 00193 } 00194 } 00195 Tbl_TableForEachDefaultEntry(table1,entry1,colnum) { 00196 entry2 = NIL(Tbl_Entry_t); 00197 00198 if (entry1 != NIL(Tbl_Entry_t)) { 00199 if (entry1->type != Tbl_EntryEqual_c) { 00200 entry2 = Tbl_EntryDup(entry1); 00201 } 00202 else{ 00203 eqcolnum = Tbl_EntryReadVarIndex(entry1); 00204 if ( eqcolnum < index) { 00205 entry2 = Tbl_EntryDup(entry1); 00206 } 00207 else { 00208 if ( eqcolnum > index) { 00209 entry2 = Tbl_EntryDup(entry1); 00210 Tbl_EntrySetEqual(entry2, eqcolnum -1); 00211 } 00212 else { 00213 entry2 = Tbl_EntryDup(Tbl_TableReadEntry(table2,0,0,1)); 00214 } 00215 } 00216 } 00217 } 00218 (void) Tbl_TableDefaultSetEntry(newTable,entry2,colnum); 00219 } 00220 return newTable; 00221 } 00222 else { 00223 fail("The table is not constant\n"); 00224 return NIL(Tbl_Table_t); /* not reached */ 00225 } 00226 } 00227 00228 00244 Tbl_Table_t * 00245 Tbl_TableInvertBinaryInputColumn( 00246 Tbl_Table_t *table, 00247 int index 00248 ) 00249 { 00250 int rowNum, colNum; 00251 Tbl_Entry_t *entry; 00252 Tbl_Table_t *newTable; 00253 Var_Variable_t *var; 00254 00255 var = Tbl_TableReadIndexVar(table, index, 0); 00256 if (Var_VariableReadNumValues(var) != 2 || 00257 Var_VariableTestIsSymbolic(var)) return NIL(Tbl_Table_t); 00258 00259 /* Check default entries. We give up if any variable points to the column 00260 * to be complemented, because it's a rare case and it does not seem worth 00261 * the effort. 00262 */ 00263 Tbl_TableForEachDefaultEntry(table, entry, colNum) { 00264 if (entry != NIL(Tbl_Entry_t) && Tbl_EntryIsEqual(entry)) { 00265 int eqColNum = Tbl_EntryReadVarIndex(entry); 00266 if (eqColNum == index) { 00267 return NIL(Tbl_Table_t); 00268 } 00269 } 00270 } 00271 00272 newTable = Tbl_TableHardDup(table); 00273 00274 Tbl_TableForEachInputVar(table, colNum, var) { 00275 Tbl_TableSetVar(newTable, colNum, var, 0); 00276 } 00277 00278 Tbl_TableForEachOutputVar(table, colNum, var) { 00279 Tbl_TableSetVar(newTable, colNum, var, 1); 00280 } 00281 00282 /* Get rid of equal entries in the output part that point to the 00283 * column to be negated. We do not currently deal with equal 00284 * entries in the input part. If we find one, we give up. 00285 */ 00286 Tbl_TableForEachOutputEntry(newTable, rowNum, colNum, entry) { 00287 if (Tbl_EntryIsEqual(entry)) { 00288 int eqColNum = Tbl_EntryReadVarIndex(entry); 00289 if (eqColNum == index) { 00290 Tbl_Entry_t *eqEntry = Tbl_TableReadEntry(newTable, rowNum, index, 0); 00291 if (Tbl_EntryIsEqual(eqEntry) || 00292 Tbl_EntryReadNumValues(eqEntry) == 0) { 00293 /* Tricky case: we give up. */ 00294 Tbl_TableFree(newTable); 00295 return NIL(Tbl_Table_t); 00296 } else if (Tbl_EntryReadNumValues(eqEntry) == 1) { 00297 /* Downgrade the equality to a constant value. */ 00298 Tbl_Entry_t *entry2 = Tbl_EntryDup(eqEntry); 00299 Tbl_TableSetEntry(newTable, entry2, rowNum, colNum, 1); 00300 } else { 00301 int i, j; 00302 Tbl_Entry_t *entry2; 00303 i = Tbl_TableAddRow(newTable); 00304 Tbl_RowForEachInputEntry(newTable, rowNum, entry2, j) { 00305 if (j == index) { 00306 Tbl_Entry_t *entry3 = Tbl_EntryAlloc(Tbl_EntryNormal_c); 00307 Tbl_Entry_t *entry4 = Tbl_EntryAlloc(Tbl_EntryNormal_c); 00308 Tbl_EntrySetValue(entry3, 0, 0); 00309 Tbl_EntrySetValue(entry4, 1, 1); 00310 Tbl_TableSetEntry(newTable, entry3, rowNum, j, 0); 00311 Tbl_TableSetEntry(newTable, entry4, i, j, 0); 00312 } else { 00313 Tbl_TableSetEntry(newTable, Tbl_EntryDup(entry2), i, j, 0); 00314 } 00315 } 00316 Tbl_RowForEachOutputEntry(newTable, rowNum, entry2, j) { 00317 if (Tbl_EntryIsEqual(entry2) && 00318 Tbl_EntryReadVarIndex(entry) == index) { 00319 Tbl_Entry_t *entry3 = Tbl_EntryAlloc(Tbl_EntryNormal_c); 00320 Tbl_Entry_t *entry4 = Tbl_EntryAlloc(Tbl_EntryNormal_c); 00321 Tbl_EntrySetValue(entry3, 0, 0); 00322 Tbl_EntrySetValue(entry4, 1, 1); 00323 Tbl_TableSetEntry(newTable, entry3, rowNum, j, 1); 00324 Tbl_TableSetEntry(newTable, entry4, i, j, 1); 00325 } else { 00326 Tbl_TableSetEntry(newTable, Tbl_EntryDup(entry2), i, j, 1); 00327 } 00328 } 00329 continue; 00330 } 00331 } 00332 } 00333 } 00334 00335 Tbl_TableForEachInputEntry(newTable, rowNum, colNum, entry) { 00336 if (Tbl_EntryIsEqual(entry)) { 00337 if (colNum == index) { 00338 Tbl_TableFree(newTable); 00339 return NIL(Tbl_Table_t); 00340 } else { 00341 int eqColNum = Tbl_EntryReadVarIndex(entry); 00342 if (eqColNum == index) { 00343 Tbl_TableFree(newTable); 00344 return NIL(Tbl_Table_t); 00345 } 00346 } 00347 } else if (colNum == index) { 00348 if (Tbl_EntryReadNumValues(entry) == 1) { 00349 Tbl_EntryComplement(entry, 0, 1); 00350 } 00351 } 00352 } 00353 00354 return newTable; 00355 00356 } /* Tbl_TableInvertBinaryInputColumn */ 00357 00358 00359 /*---------------------------------------------------------------------------*/ 00360 /* Definition of internal functions */ 00361 /*---------------------------------------------------------------------------*/ 00362 00374 boolean 00375 TblTableDeleteLastRow( 00376 Tbl_Table_t* table) 00377 { 00378 array_t *dataArray; 00379 Tbl_Row_t *row; 00380 int rowNum; 00381 00382 dataArray = array_dup(TblTableReadData(table)); 00383 array_free(TblTableReadData(table)); 00384 TblTableReadData(table)= array_alloc(Tbl_Row_t*,0); 00385 for(rowNum=0; rowNum < (array_n(dataArray)-1); rowNum++) { 00386 row = array_fetch(Tbl_Row_t*,dataArray,rowNum); 00387 array_insert_last(Tbl_Row_t*,TblTableReadData(table),row); 00388 } 00389 return TRUE; 00390 } 00391 00392 /*---------------------------------------------------------------------------*/ 00393 /* Definition of static functions */ 00394 /*---------------------------------------------------------------------------*/ 00395 00396 00409 static void SetAdjustedEntry( 00410 Tbl_Table_t *table, 00411 Tbl_Entry_t *entry, 00412 int index, 00413 int rownum, 00414 int colnum, 00415 boolean flag) 00416 { 00417 Tbl_Entry_t *newEntry; 00418 00419 if (flag ==0) { 00420 if (colnum < index) { 00421 /* should free if necessary */ 00422 newEntry = Tbl_TableReadEntry(table,rownum,colnum,0); 00423 if (newEntry==NIL(Tbl_Entry_t)) { 00424 Tbl_TableSetEntry(table,entry,rownum,colnum,0); 00425 } 00426 else { 00427 Tbl_EntryFree(entry); 00428 } 00429 } 00430 else if (colnum > index) { 00431 /* should free if necessary */ 00432 newEntry = Tbl_TableReadEntry(table,rownum,colnum-1,0); 00433 if (newEntry==NIL(Tbl_Entry_t)) { 00434 Tbl_TableSetEntry(table,entry,rownum,colnum-1,0); 00435 } 00436 else { 00437 Tbl_EntryFree(entry); 00438 } 00439 } 00440 else { 00441 Tbl_EntryFree(entry); 00442 } 00443 } 00444 else { 00445 newEntry = Tbl_TableReadEntry(table,rownum,colnum,1); 00446 if (newEntry== NIL(Tbl_Entry_t)) { 00447 Tbl_TableSetEntry(table,entry,rownum,colnum,1); 00448 } 00449 else { 00450 Tbl_EntryFree(newEntry); 00451 Tbl_TableSetEntry(table,entry,rownum,colnum,1); 00452 00453 } 00454 } 00455 } 00456 00469 static void SetEntry( 00470 Tbl_Table_t *newTable, 00471 Tbl_Entry_t *entry1, 00472 Tbl_Entry_t *entry2, 00473 int rownum, 00474 int colnum, 00475 int index, 00476 boolean flag) 00477 { 00478 int varcolnum; 00479 Tbl_Entry_t *newEntry; 00480 00481 00482 if (entry1->type == Tbl_EntryNormal_c) { 00483 SetAdjustedEntry(newTable,Tbl_EntryDup(entry1),index,rownum,colnum, flag); 00484 } 00485 else { 00486 /* its of type equal */ 00487 varcolnum = Tbl_EntryReadVarIndex(entry1); 00488 if (varcolnum < index) { 00489 SetAdjustedEntry(newTable,Tbl_EntryDup(entry1),index,rownum,colnum, flag); 00490 } 00491 else { 00492 if (varcolnum > index) { 00493 newEntry = Tbl_EntryDup(entry1); 00494 Tbl_EntrySetEqual(newEntry,varcolnum-1); 00495 SetAdjustedEntry(newTable,newEntry,index,rownum,colnum,flag); 00496 00497 } 00498 else { 00499 SetAdjustedEntry(newTable,Tbl_EntryDup(entry2),index,rownum,colnum, flag); 00500 } 00501 } 00502 } 00503 }