VIS

src/io/ioTable.c

Go to the documentation of this file.
00001 
00037 #include "ioInt.h"
00038 
00039 static char rcsid[] UNUSED = "$Id: ioTable.c,v 1.8 2002/09/08 23:40:00 fabio Exp $";
00040 
00041 /*---------------------------------------------------------------------------*/
00042 /* Constant declarations                                                     */
00043 /*---------------------------------------------------------------------------*/
00044 
00045 
00046 /*---------------------------------------------------------------------------*/
00047 /* Type declarations                                                         */
00048 /*---------------------------------------------------------------------------*/
00049 
00050 
00051 /*---------------------------------------------------------------------------*/
00052 /* Stucture declarations                                                     */
00053 /*---------------------------------------------------------------------------*/
00054 
00055 
00056 /*---------------------------------------------------------------------------*/
00057 /* Variable declarations                                                     */
00058 /*---------------------------------------------------------------------------*/
00059 
00060 
00061 /*---------------------------------------------------------------------------*/
00062 /* Macro declarations                                                        */
00063 /*---------------------------------------------------------------------------*/
00064 
00065 
00068 /*---------------------------------------------------------------------------*/
00069 /* Static function prototypes                                                */
00070 /*---------------------------------------------------------------------------*/
00071 
00072 static void _IoSymValueFree(IoSymValue_t *value);
00073 static int _IoSymCubeInsertInTable(Tbl_Table_t *table, array_t *symCube, int numIp, int numOp);
00074 static int _IoDefaultSymCubeInsertInTable(Tbl_Table_t *table, array_t *symCube, int numOp);
00075 static Tbl_Entry_t * _IoSymValueTransformToEntry(IoSymValue_t *value, Var_Variable_t *var, Tbl_Table_t *table);
00076 static int VariableReadIndex(Var_Variable_t *var, char *value);
00077 
00081 /*---------------------------------------------------------------------------*/
00082 /* Definition of exported functions                                          */
00083 /*---------------------------------------------------------------------------*/
00084 
00085 /*---------------------------------------------------------------------------*/
00086 /* Definition of internal functions                                          */
00087 /*---------------------------------------------------------------------------*/
00088 
00105 Tbl_Table_t *
00106 IoPTableTransformToTable(
00107   Hrc_Model_t *model, 
00108   Hrc_Node_t *hnode, 
00109   IoPTable_t *pTable)
00110 {
00111   int i, numIo, numIp, numOp;
00112   char *input, *output;
00113   array_t *symCubes, *symCube;
00114   Tbl_Table_t *table;
00115   Var_Variable_t *var;
00116 
00117   symCubes = pTable->cubes;  
00118 
00119   /* if neither symCubes nor default is set, the table is illegal */
00120   if (symCubes == NIL(array_t) && pTable->defaultOutput == NIL(array_t)){
00121     error_append("Error: Table ");
00122     error_append(array_fetch(char *,pTable->outputs,0));
00123     error_append(" has neither relation nor default.\n");
00124     return NIL(Tbl_Table_t);
00125   }
00126 
00127   /* partial check to see if symCubes is properly set up */
00128   numIp = array_n(pTable->inputs);
00129   numOp = array_n(pTable->outputs);
00130   numIo = numIp + numOp;
00131   if (symCubes != NIL(array_t)){
00132     for (i=0; i < array_n(symCubes); i++){
00133       symCube = array_fetch(array_t *,symCubes,i);
00134       if (numIo != array_n(symCube)){
00135         error_append("Error: The number of columns in the table where output ");
00136         error_append(array_fetch(char *,pTable->outputs,0));
00137         error_append(" is defined is not equal to the number of input/output variables.\n");
00138         return NIL(Tbl_Table_t);
00139       }
00140     }
00141   }
00142 
00143   table = Tbl_TableAlloc();
00144 
00145   /* add input columns to the table */
00146   for (i=0; i < array_n(pTable->inputs); i++){
00147     input = array_fetch(char *,pTable->inputs,i);
00148     /* the following if should not fail due to the spec of IoVariableFindOrAllocByName() -- To be fixed */
00149     if ((var = IoVariableFindOrAllocByName(hnode,input)) == NIL(Var_Variable_t)){
00150       return NIL(Tbl_Table_t);
00151     }
00152     /* the following if should not fail due to the spec of Tbl_TableAddColumn() -- To be fixed */
00153     if (Tbl_TableAddColumn(table,var,0) == 0){
00154       return NIL(Tbl_Table_t);
00155     }
00156   }  
00157   /* add output columns to the table */
00158   for (i=0; i < array_n(pTable->outputs); i++){
00159     output = array_fetch(char *,pTable->outputs,i);
00160     /* the following if should not fail due to the spec of IoVariableFindOrAllocByName() -- To be fixed */
00161     if ((var = IoVariableFindOrAllocByName(hnode,output)) == NIL(Var_Variable_t)){
00162       return NIL(Tbl_Table_t);
00163     }
00164     /* the following if should not fail due to the spec of Tbl_TableAddColumn() -- To be fixed */
00165     if (Tbl_TableAddColumn(table,var,1) == 0){
00166       return NIL(Tbl_Table_t);
00167     }
00168   } 
00169 
00170   /* insert a cube one by one to the table */
00171   if (symCubes != NIL(array_t)){
00172     for (i=0; i < array_n(symCubes); i++){
00173       symCube = array_fetch(array_t *,symCubes,i);
00174       if (_IoSymCubeInsertInTable(table, symCube, numIp, numOp) == 0){
00175         Tbl_TableFree(table);
00176         return NIL(Tbl_Table_t);
00177       }
00178     }
00179   }
00180 
00181   /* check if the default and the output has the same number of variables */
00182   if (pTable->defaultOutput != NIL(array_t) && array_n(pTable->outputs) != array_n(pTable->defaultOutput)){
00183     error_append("Error: Default is not compatible with the number of outputs in output of ");
00184     error_append(array_fetch(char *,pTable->outputs,0));
00185     error_append("\n");
00186     Tbl_TableFree(table);
00187     return NIL(Tbl_Table_t);
00188   }
00189   /* insert the default cube to the table */
00190   if (_IoDefaultSymCubeInsertInTable(table, pTable->defaultOutput, numOp) == 0) {
00191     Tbl_TableFree(table);
00192     return NIL(Tbl_Table_t);
00193   }
00194 
00195   return table;
00196 }
00197 
00210 IoSymValue_t *
00211 IoSymValueAlloc(void)
00212 {
00213   return ALLOC(IoSymValue_t,1);
00214 }
00215 
00229 void
00230 IoSymValueArrayFree(array_t *valueArray)
00231 {
00232   int i;
00233 
00234   for (i=0; i < array_n(valueArray); i++){
00235     _IoSymValueFree(array_fetch(IoSymValue_t *,valueArray,i));
00236   }
00237   array_free(valueArray);
00238 }
00239 
00240 /*---------------------------------------------------------------------------*/
00241 /* Definition of static functions                                            */
00242 /*---------------------------------------------------------------------------*/
00243 
00256 static void
00257 _IoSymValueFree(IoSymValue_t *value)
00258 {
00259   IoSymValueType flag;
00260 
00261   /* if flag == IoUniverse_c, we have no extra work to do */
00262   if ((flag = value->flag) == IoLeaf_c ){
00263     FREE(value->left);
00264   }
00265   if (flag == IoRange_c){
00266     FREE(value->left);
00267     FREE(value->right);
00268   }
00269   if (flag == IoComplement_c){
00270     _IoSymValueFree(value->left);
00271   }
00272   if (flag == IoList_c){
00273     int i;
00274     IoSymValue_t *valueTmp;
00275     for (i=0; i < array_n(value->elements); i++){
00276       valueTmp = array_fetch(IoSymValue_t *,value->elements,i);
00277       _IoSymValueFree(valueTmp);
00278     } 
00279     array_free(value->elements);
00280   }
00281   if (flag == IoAssign_c){
00282     FREE(value->left);
00283   }
00284   FREE(value); 
00285 }
00286 
00303 static int
00304 _IoSymCubeInsertInTable(
00305   Tbl_Table_t *table, 
00306   array_t *symCube, 
00307   int numIp, 
00308   int numOp)
00309 {
00310   int index, i;
00311   IoSymValue_t *symValue;
00312   Tbl_Entry_t *entry;
00313 
00314   /* get a new row for the cube */
00315   index = Tbl_TableAddRow(table);
00316 
00317   for (i=0; i < numIp; i++){
00318     symValue = array_fetch(IoSymValue_t *,symCube,i);
00319     entry = _IoSymValueTransformToEntry(symValue,Tbl_TableReadIndexVar(table,i,0),table);
00320     if (entry == NIL(Tbl_Entry_t))
00321       return 0;
00322     Tbl_TableSetEntry(table,entry,index,i,0); 
00323   }
00324   for (i=0; i < numOp; i++){
00325     symValue = array_fetch(IoSymValue_t *,symCube, numIp+i);
00326     entry = _IoSymValueTransformToEntry(symValue,Tbl_TableReadIndexVar(table,i,1),table);
00327     if (entry == NIL(Tbl_Entry_t))
00328       return 0;
00329     Tbl_TableSetEntry(table,entry,index,i,1); 
00330   }
00331   return 1;
00332 }
00333 
00347 static int
00348 _IoDefaultSymCubeInsertInTable(
00349   Tbl_Table_t *table, 
00350   array_t *symCube, 
00351   int numOp)
00352 {
00353   int i;
00354   IoSymValue_t *symValue;
00355   Tbl_Entry_t *entry;
00356 
00357   /* no defaults is asserted. */
00358   if (symCube == NIL(array_t)){
00359     return 1;
00360   }
00361 
00362   for (i=0; i < array_n(symCube); i++){
00363     symValue = array_fetch(IoSymValue_t *,symCube, i);
00364     entry = _IoSymValueTransformToEntry(symValue,Tbl_TableReadIndexVar(table,i,1),table);
00365     if (entry == NIL(Tbl_Entry_t))
00366       return 0;
00367     Tbl_TableDefaultSetEntry(table,entry,i);
00368   }
00369   return 1;
00370 }
00371 
00391 static Tbl_Entry_t *
00392 _IoSymValueTransformToEntry(
00393   IoSymValue_t *value, 
00394   Var_Variable_t *var,
00395   Tbl_Table_t *table)
00396 {
00397   IoSymValueType flag;
00398   Tbl_Entry_t *entry;
00399 
00400   if ((flag = value->flag) == IoLeaf_c){
00401     int index;
00402     index = VariableReadIndex(var,(char *)(value->left));
00403     if (index == -1){
00404       return NIL(Tbl_Entry_t);
00405     }
00406     entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00407     Tbl_EntrySetValue(entry,index,index);
00408     return entry;
00409   }
00410   if (flag == IoUniverse_c){
00411     int range;
00412     range = Var_VariableReadNumValues(var);
00413     entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00414     Tbl_EntrySetValue(entry,0,range-1);
00415     return entry;
00416   }
00417   if (flag == IoRange_c){
00418     int indexFrom, indexTo;
00419     indexFrom = VariableReadIndex(var,(char *)(value->left));
00420     indexTo = VariableReadIndex(var,(char *)(value->right));
00421     if (indexFrom == -1 || indexTo == -1){
00422       return NIL(Tbl_Entry_t);
00423     }
00424     entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00425     Tbl_EntrySetValue(entry,indexFrom,indexTo);
00426     return entry;
00427   }
00428   if (flag == IoComplement_c){
00429     entry = _IoSymValueTransformToEntry(value->left,var,table);
00430     if (entry == NIL(Tbl_Entry_t)){
00431       return NIL(Tbl_Entry_t);
00432     }
00433     Tbl_EntryComplement(entry,0,Var_VariableReadNumValues(var)-1);
00434     return entry;
00435   }
00436   if (flag == IoList_c){
00437     int i;
00438     IoSymValue_t *valueTmp;
00439     Tbl_Entry_t *entryTmp, *entryUnion;
00440 
00441     entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00442     for (i=0; i < array_n(value->elements); i++){
00443       valueTmp = array_fetch(IoSymValue_t *,value->elements,i);
00444       entryTmp = _IoSymValueTransformToEntry(valueTmp,var,table);
00445       if (entryTmp == NIL(Tbl_Entry_t)){
00446         Tbl_EntryFree(entry);
00447         return NIL(Tbl_Entry_t);
00448       }
00449       entryUnion = Tbl_EntryMerge(entry,entryTmp);
00450       Tbl_EntryFree(entry);
00451       Tbl_EntryFree(entryTmp);
00452       entry = entryUnion;
00453     } 
00454     return entry;
00455   }
00456   if (flag == IoAssign_c){
00457     int i;
00458     Var_Variable_t *varCandidate = NIL(Var_Variable_t);
00459 
00460     entry = Tbl_EntryAlloc(Tbl_EntryEqual_c);
00461     for (i=0; i < Tbl_TableReadNumInputs(table); i++){
00462       varCandidate = Tbl_TableReadIndexVar(table,i,0);
00463       if (strcmp(Var_VariableReadName(varCandidate),(char *)value->left) == 0){
00464       /* found the variable referred in = construct as an input of the table */
00465         break;
00466       }
00467     }
00468     /* the following if-clause is only true when the above for-loop cannot
00469     find the variable referred in = construct */
00470     if (i == Tbl_TableReadNumInputs(table)){
00471       error_append("Variable ");
00472       error_append((char *)value->left);
00473       error_append(" is not an input of the table where ");
00474       error_append(Var_VariableReadName(var));
00475       error_append(" is an output. It cannot be used as an argument of = construct.\n");
00476       Tbl_EntryFree(entry);
00477       return NIL(Tbl_Entry_t);
00478     }
00479     /* check if the two variables connected with = construct have the same domain */
00480     if (Var_VariablesTestHaveSameDomain(var,varCandidate) == 0){
00481       error_append("Variables ");
00482       error_append((char *)value->left);
00483       error_append(" and ");
00484       error_append(Var_VariableReadName(var));
00485       error_append(" have different domains. Cannot be used in = construct.\n");
00486       Tbl_EntryFree(entry);
00487       return NIL(Tbl_Entry_t);
00488     }
00489     Tbl_EntrySetEqual(entry,i);
00490     return entry;
00491   }
00492   else {
00493     return NIL(Tbl_Entry_t);
00494   }
00495 }
00496 
00497 
00498 
00499 
00514 static int
00515 VariableReadIndex(
00516   Var_Variable_t *var,
00517   char *value)
00518 {
00519   int integer;
00520   if (Var_VariableTestIsEnumerative(var) == 1){
00521     integer = IoAtoi(value);
00522     if (integer == -1 || integer >= Var_VariableReadNumValues(var)){
00523       error_append("Value ");
00524       error_append(value);
00525       error_append(" is not a proper value for variable ");
00526       error_append(Var_VariableReadName(var));
00527       error_append("\n");
00528       return -1;
00529     }
00530     return integer;
00531   }
00532   /* var is now a symbolic variable */
00533   if ((integer = Var_VariableReadIndexFromSymbolicValue(var,value)) == -1){
00534     error_append("Value ");
00535     error_append(value);
00536     error_append(" is not a proper value for variable ");
00537     error_append(Var_VariableReadName(var));
00538     error_append("\n");
00539     return -1;
00540   }
00541   return integer;
00542 }
00543 
00544 
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 
00553 
00554