VIS

src/tbl/tblSweep.c

Go to the documentation of this file.
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 }