source: vis_dev/vis-2.3/src/io/ioTable.c @ 84

Last change on this file since 84 was 14, checked in by cecile, 13 years ago

vis2.3

File size: 17.6 KB
RevLine 
[14]1/**CFile***********************************************************************
2
3  FileName    [ioTable.c]
4
5  PackageName [io]
6
7  Synopsis    [Routines for generating the table data structure from
8               textual information. Used in the parser.]
9
10  Description []
11
12  SeeAlso     []
13
14  Author      [Yuji Kukimoto, Rajeev Ranjan, Huey-Yih Wang]
15
16  Copyright   [Copyright (c) 1994-1996 The Regents of the Univ. of California.
17  All rights reserved.
18
19  Permission is hereby granted, without written agreement and without license
20  or royalty fees, to use, copy, modify, and distribute this software and its
21  documentation for any purpose, provided that the above copyright notice and
22  the following two paragraphs appear in all copies of this software.
23
24  IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
25  DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
26  OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
27  CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29  THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
30  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31  FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN
32  "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE
33  MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.]
34
35******************************************************************************/
36
37#include "ioInt.h"
38
39static char rcsid[] UNUSED = "$Id: ioTable.c,v 1.8 2002/09/08 23:40:00 fabio Exp $";
40
41/*---------------------------------------------------------------------------*/
42/* Constant declarations                                                     */
43/*---------------------------------------------------------------------------*/
44
45
46/*---------------------------------------------------------------------------*/
47/* Type declarations                                                         */
48/*---------------------------------------------------------------------------*/
49
50
51/*---------------------------------------------------------------------------*/
52/* Stucture declarations                                                     */
53/*---------------------------------------------------------------------------*/
54
55
56/*---------------------------------------------------------------------------*/
57/* Variable declarations                                                     */
58/*---------------------------------------------------------------------------*/
59
60
61/*---------------------------------------------------------------------------*/
62/* Macro declarations                                                        */
63/*---------------------------------------------------------------------------*/
64
65
66/**AutomaticStart*************************************************************/
67
68/*---------------------------------------------------------------------------*/
69/* Static function prototypes                                                */
70/*---------------------------------------------------------------------------*/
71
72static void _IoSymValueFree(IoSymValue_t *value);
73static int _IoSymCubeInsertInTable(Tbl_Table_t *table, array_t *symCube, int numIp, int numOp);
74static int _IoDefaultSymCubeInsertInTable(Tbl_Table_t *table, array_t *symCube, int numOp);
75static Tbl_Entry_t * _IoSymValueTransformToEntry(IoSymValue_t *value, Var_Variable_t *var, Tbl_Table_t *table);
76static int VariableReadIndex(Var_Variable_t *var, char *value);
77
78/**AutomaticEnd***************************************************************/
79
80
81/*---------------------------------------------------------------------------*/
82/* Definition of exported functions                                          */
83/*---------------------------------------------------------------------------*/
84
85/*---------------------------------------------------------------------------*/
86/* Definition of internal functions                                          */
87/*---------------------------------------------------------------------------*/
88
89/**Function********************************************************************
90
91  Synopsis    [Transforms table information stored in a special data structure
92  IoPTable_t used by the parser to the table data structure.]
93
94  Description [Transforms table information stored in a special data structure
95  IoPTable_t used by the parser to the table data structure. The second and
96  the third arguments and the model and the corresponding master hnode
97  being parsed.]
98
99  SideEffects []
100
101  SeeAlso     []
102
103******************************************************************************/
104
105Tbl_Table_t *
106IoPTableTransformToTable(
107  Hrc_Model_t *model, 
108  Hrc_Node_t *hnode, 
109  IoPTable_t *pTable)
110{
111  int i, numIo, numIp, numOp;
112  char *input, *output;
113  array_t *symCubes, *symCube;
114  Tbl_Table_t *table;
115  Var_Variable_t *var;
116
117  symCubes = pTable->cubes; 
118
119  /* if neither symCubes nor default is set, the table is illegal */
120  if (symCubes == NIL(array_t) && pTable->defaultOutput == NIL(array_t)){
121    error_append("Error: Table ");
122    error_append(array_fetch(char *,pTable->outputs,0));
123    error_append(" has neither relation nor default.\n");
124    return NIL(Tbl_Table_t);
125  }
126
127  /* partial check to see if symCubes is properly set up */
128  numIp = array_n(pTable->inputs);
129  numOp = array_n(pTable->outputs);
130  numIo = numIp + numOp;
131  if (symCubes != NIL(array_t)){
132    for (i=0; i < array_n(symCubes); i++){
133      symCube = array_fetch(array_t *,symCubes,i);
134      if (numIo != array_n(symCube)){
135        error_append("Error: The number of columns in the table where output ");
136        error_append(array_fetch(char *,pTable->outputs,0));
137        error_append(" is defined is not equal to the number of input/output variables.\n");
138        return NIL(Tbl_Table_t);
139      }
140    }
141  }
142
143  table = Tbl_TableAlloc();
144
145  /* add input columns to the table */
146  for (i=0; i < array_n(pTable->inputs); i++){
147    input = array_fetch(char *,pTable->inputs,i);
148    /* the following if should not fail due to the spec of IoVariableFindOrAllocByName() -- To be fixed */
149    if ((var = IoVariableFindOrAllocByName(hnode,input)) == NIL(Var_Variable_t)){
150      return NIL(Tbl_Table_t);
151    }
152    /* the following if should not fail due to the spec of Tbl_TableAddColumn() -- To be fixed */
153    if (Tbl_TableAddColumn(table,var,0) == 0){
154      return NIL(Tbl_Table_t);
155    }
156  } 
157  /* add output columns to the table */
158  for (i=0; i < array_n(pTable->outputs); i++){
159    output = array_fetch(char *,pTable->outputs,i);
160    /* the following if should not fail due to the spec of IoVariableFindOrAllocByName() -- To be fixed */
161    if ((var = IoVariableFindOrAllocByName(hnode,output)) == NIL(Var_Variable_t)){
162      return NIL(Tbl_Table_t);
163    }
164    /* the following if should not fail due to the spec of Tbl_TableAddColumn() -- To be fixed */
165    if (Tbl_TableAddColumn(table,var,1) == 0){
166      return NIL(Tbl_Table_t);
167    }
168  } 
169
170  /* insert a cube one by one to the table */
171  if (symCubes != NIL(array_t)){
172    for (i=0; i < array_n(symCubes); i++){
173      symCube = array_fetch(array_t *,symCubes,i);
174      if (_IoSymCubeInsertInTable(table, symCube, numIp, numOp) == 0){
175        Tbl_TableFree(table);
176        return NIL(Tbl_Table_t);
177      }
178    }
179  }
180
181  /* check if the default and the output has the same number of variables */
182  if (pTable->defaultOutput != NIL(array_t) && array_n(pTable->outputs) != array_n(pTable->defaultOutput)){
183    error_append("Error: Default is not compatible with the number of outputs in output of ");
184    error_append(array_fetch(char *,pTable->outputs,0));
185    error_append("\n");
186    Tbl_TableFree(table);
187    return NIL(Tbl_Table_t);
188  }
189  /* insert the default cube to the table */
190  if (_IoDefaultSymCubeInsertInTable(table, pTable->defaultOutput, numOp) == 0) {
191    Tbl_TableFree(table);
192    return NIL(Tbl_Table_t);
193  }
194
195  return table;
196}
197
198/**Function********************************************************************
199
200  Synopsis    [Allocates a IoSymValue_t.]
201
202  Description []
203
204  SideEffects []
205
206  SeeAlso     []
207
208******************************************************************************/
209
210IoSymValue_t *
211IoSymValueAlloc(void)
212{
213  return ALLOC(IoSymValue_t,1);
214}
215
216/**Function********************************************************************
217
218  Synopsis    [Frees an array of the IoSymValue_t data structure.]
219
220  Description [Frees an array of the IoSymValue_t data structure.
221  All the elements of the array are also freed.]
222
223  SideEffects []
224
225  SeeAlso     []
226
227******************************************************************************/
228
229void
230IoSymValueArrayFree(array_t *valueArray)
231{
232  int i;
233
234  for (i=0; i < array_n(valueArray); i++){
235    _IoSymValueFree(array_fetch(IoSymValue_t *,valueArray,i));
236  }
237  array_free(valueArray);
238}
239
240/*---------------------------------------------------------------------------*/
241/* Definition of static functions                                            */
242/*---------------------------------------------------------------------------*/
243
244/**Function********************************************************************
245
246  Synopsis    [Frees the IoSymValue_t data structure.]
247
248  Description []
249
250  SideEffects []
251
252  SeeAlso     []
253
254******************************************************************************/
255
256static void
257_IoSymValueFree(IoSymValue_t *value)
258{
259  IoSymValueType flag;
260
261  /* if flag == IoUniverse_c, we have no extra work to do */
262  if ((flag = value->flag) == IoLeaf_c ){
263    FREE(value->left);
264  }
265  if (flag == IoRange_c){
266    FREE(value->left);
267    FREE(value->right);
268  }
269  if (flag == IoComplement_c){
270    _IoSymValueFree(value->left);
271  }
272  if (flag == IoList_c){
273    int i;
274    IoSymValue_t *valueTmp;
275    for (i=0; i < array_n(value->elements); i++){
276      valueTmp = array_fetch(IoSymValue_t *,value->elements,i);
277      _IoSymValueFree(valueTmp);
278    } 
279    array_free(value->elements);
280  }
281  if (flag == IoAssign_c){
282    FREE(value->left);
283  }
284  FREE(value); 
285}
286
287/**Function********************************************************************
288
289  Synopsis    [Given a symbolic cube in textual format and a table, updates
290  the table by adding the cube.]
291
292  Description [Given a symbolic cube in textual format and a table, updates
293  the table by adding the cube. The arguments are a pointer to the working
294  table, a cube to be inserted in textual format, the number of inputs of
295  the table, and the number of outputs of the table.]
296
297  SideEffects [The new cube represented in symCube is inserted in the table.]
298
299  SeeAlso     []
300
301******************************************************************************/
302
303static int
304_IoSymCubeInsertInTable(
305  Tbl_Table_t *table, 
306  array_t *symCube, 
307  int numIp, 
308  int numOp)
309{
310  int index, i;
311  IoSymValue_t *symValue;
312  Tbl_Entry_t *entry;
313
314  /* get a new row for the cube */
315  index = Tbl_TableAddRow(table);
316
317  for (i=0; i < numIp; i++){
318    symValue = array_fetch(IoSymValue_t *,symCube,i);
319    entry = _IoSymValueTransformToEntry(symValue,Tbl_TableReadIndexVar(table,i,0),table);
320    if (entry == NIL(Tbl_Entry_t))
321      return 0;
322    Tbl_TableSetEntry(table,entry,index,i,0); 
323  }
324  for (i=0; i < numOp; i++){
325    symValue = array_fetch(IoSymValue_t *,symCube, numIp+i);
326    entry = _IoSymValueTransformToEntry(symValue,Tbl_TableReadIndexVar(table,i,1),table);
327    if (entry == NIL(Tbl_Entry_t))
328      return 0;
329    Tbl_TableSetEntry(table,entry,index,i,1); 
330  }
331  return 1;
332}
333
334/**Function********************************************************************
335
336  Synopsis    [Given a default symbolic cube in textual format and a table,
337  updates the table by adding the cube.]
338
339  Description []
340
341  SideEffects [The default cube is added to the table.]
342
343  SeeAlso     []
344
345******************************************************************************/
346
347static int
348_IoDefaultSymCubeInsertInTable(
349  Tbl_Table_t *table, 
350  array_t *symCube, 
351  int numOp)
352{
353  int i;
354  IoSymValue_t *symValue;
355  Tbl_Entry_t *entry;
356
357  /* no defaults is asserted. */
358  if (symCube == NIL(array_t)){
359    return 1;
360  }
361
362  for (i=0; i < array_n(symCube); i++){
363    symValue = array_fetch(IoSymValue_t *,symCube, i);
364    entry = _IoSymValueTransformToEntry(symValue,Tbl_TableReadIndexVar(table,i,1),table);
365    if (entry == NIL(Tbl_Entry_t))
366      return 0;
367    Tbl_TableDefaultSetEntry(table,entry,i);
368  }
369  return 1;
370}
371
372/**Function********************************************************************
373
374  Synopsis    [Generates a set of ranges used in the table data structure
375               from textual representation of symbolic values.]
376
377  Description [Generates a set of ranges used in the table data structure
378  from textual representation of symbolic values. Symbolic values are
379  representations which can be put into an entry of a table, i.e.
380  a symbolic element in a row. The arguments of the function are
381  a symbolic value in IoSymValue_t *, a pointer to the corresponding variable,
382  and the table we are working on. The last argument is needed to
383  resolve = constructs.]
384
385  SideEffects []
386
387  SeeAlso     []
388
389******************************************************************************/
390
391static Tbl_Entry_t *
392_IoSymValueTransformToEntry(
393  IoSymValue_t *value, 
394  Var_Variable_t *var,
395  Tbl_Table_t *table)
396{
397  IoSymValueType flag;
398  Tbl_Entry_t *entry;
399
400  if ((flag = value->flag) == IoLeaf_c){
401    int index;
402    index = VariableReadIndex(var,(char *)(value->left));
403    if (index == -1){
404      return NIL(Tbl_Entry_t);
405    }
406    entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
407    Tbl_EntrySetValue(entry,index,index);
408    return entry;
409  }
410  if (flag == IoUniverse_c){
411    int range;
412    range = Var_VariableReadNumValues(var);
413    entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
414    Tbl_EntrySetValue(entry,0,range-1);
415    return entry;
416  }
417  if (flag == IoRange_c){
418    int indexFrom, indexTo;
419    indexFrom = VariableReadIndex(var,(char *)(value->left));
420    indexTo = VariableReadIndex(var,(char *)(value->right));
421    if (indexFrom == -1 || indexTo == -1){
422      return NIL(Tbl_Entry_t);
423    }
424    entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
425    Tbl_EntrySetValue(entry,indexFrom,indexTo);
426    return entry;
427  }
428  if (flag == IoComplement_c){
429    entry = _IoSymValueTransformToEntry(value->left,var,table);
430    if (entry == NIL(Tbl_Entry_t)){
431      return NIL(Tbl_Entry_t);
432    }
433    Tbl_EntryComplement(entry,0,Var_VariableReadNumValues(var)-1);
434    return entry;
435  }
436  if (flag == IoList_c){
437    int i;
438    IoSymValue_t *valueTmp;
439    Tbl_Entry_t *entryTmp, *entryUnion;
440
441    entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
442    for (i=0; i < array_n(value->elements); i++){
443      valueTmp = array_fetch(IoSymValue_t *,value->elements,i);
444      entryTmp = _IoSymValueTransformToEntry(valueTmp,var,table);
445      if (entryTmp == NIL(Tbl_Entry_t)){
446        Tbl_EntryFree(entry);
447        return NIL(Tbl_Entry_t);
448      }
449      entryUnion = Tbl_EntryMerge(entry,entryTmp);
450      Tbl_EntryFree(entry);
451      Tbl_EntryFree(entryTmp);
452      entry = entryUnion;
453    } 
454    return entry;
455  }
456  if (flag == IoAssign_c){
457    int i;
458    Var_Variable_t *varCandidate = NIL(Var_Variable_t);
459
460    entry = Tbl_EntryAlloc(Tbl_EntryEqual_c);
461    for (i=0; i < Tbl_TableReadNumInputs(table); i++){
462      varCandidate = Tbl_TableReadIndexVar(table,i,0);
463      if (strcmp(Var_VariableReadName(varCandidate),(char *)value->left) == 0){
464      /* found the variable referred in = construct as an input of the table */
465        break;
466      }
467    }
468    /* the following if-clause is only true when the above for-loop cannot
469    find the variable referred in = construct */
470    if (i == Tbl_TableReadNumInputs(table)){
471      error_append("Variable ");
472      error_append((char *)value->left);
473      error_append(" is not an input of the table where ");
474      error_append(Var_VariableReadName(var));
475      error_append(" is an output. It cannot be used as an argument of = construct.\n");
476      Tbl_EntryFree(entry);
477      return NIL(Tbl_Entry_t);
478    }
479    /* check if the two variables connected with = construct have the same domain */
480    if (Var_VariablesTestHaveSameDomain(var,varCandidate) == 0){
481      error_append("Variables ");
482      error_append((char *)value->left);
483      error_append(" and ");
484      error_append(Var_VariableReadName(var));
485      error_append(" have different domains. Cannot be used in = construct.\n");
486      Tbl_EntryFree(entry);
487      return NIL(Tbl_Entry_t);
488    }
489    Tbl_EntrySetEqual(entry,i);
490    return entry;
491  }
492  else {
493    return NIL(Tbl_Entry_t);
494  }
495}
496
497
498
499
500/**Function********************************************************************
501
502  Synopsis    [Returns the integer index given a value.]
503
504  Description [Returns the integer index given a value. The value is either
505  an integer or a symbolic name. If the latter is the case,
506  it is transformed into the corresponding integer. If
507  a given symbolic name is not valid, the routine returns -1.]
508
509  SideEffects []
510
511  SeeAlso     []
512
513******************************************************************************/
514static int
515VariableReadIndex(
516  Var_Variable_t *var,
517  char *value)
518{
519  int integer;
520  if (Var_VariableTestIsEnumerative(var) == 1){
521    integer = IoAtoi(value);
522    if (integer == -1 || integer >= Var_VariableReadNumValues(var)){
523      error_append("Value ");
524      error_append(value);
525      error_append(" is not a proper value for variable ");
526      error_append(Var_VariableReadName(var));
527      error_append("\n");
528      return -1;
529    }
530    return integer;
531  }
532  /* var is now a symbolic variable */
533  if ((integer = Var_VariableReadIndexFromSymbolicValue(var,value)) == -1){
534    error_append("Value ");
535    error_append(value);
536    error_append(" is not a proper value for variable ");
537    error_append(Var_VariableReadName(var));
538    error_append("\n");
539    return -1;
540  }
541  return integer;
542}
543
544
545
546
547
548
549
550
551
552
553
554
Note: See TracBrowser for help on using the repository browser.