source: vis_dev/vis-2.3/src/tbl/tblEntryUtil.c @ 83

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

vis2.3

File size: 35.9 KB
RevLine 
[14]1/**CFile***********************************************************************
2
3  FileName    [tblEntryUtil.c]
4
5  PackageName [tbl]
6
7  Synopsis    [This package describes functions used to manipulate the
8               Tbl_Entry_t ,Tbl_Row_t and Tbl_Range_t structs]
9
10  Description []
11
12  SeeAlso     [tblUtil.c]
13
14  Author      [Gitanjali M. Swamy]
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 "tblInt.h"
38
39static char rcsid[] UNUSED = "$Id: tblEntryUtil.c,v 1.16 2009/04/11 02:01:29 fabio Exp $";
40
41/**AutomaticStart*************************************************************/
42
43/*---------------------------------------------------------------------------*/
44/* Static function prototypes                                                */
45/*---------------------------------------------------------------------------*/
46
47static int RangeCompare(lsGeneric entry1, lsGeneric entry2);
48static void EntryCanonicalize(Tbl_Entry_t * entry);
49static void EntryComplement(Tbl_Entry_t * entry, int min, int max);
50
51/**AutomaticEnd***************************************************************/
52/*---------------------------------------------------------------------------*/
53/* Definition of exported functions                                          */
54/*---------------------------------------------------------------------------*/
55
56/**Function********************************************************************
57
58  Synopsis    [This function allocates space for a table entry.]
59
60  Description [This function allocates space for a table entry and must be passed
61               the type of the entry (Tbl_EntryEqual_c or Tbl_EntryNormal_c) as a parameter]
62
63  SideEffects []
64
65  SeeAlso     [TblEntryFree]
66
67******************************************************************************/
68Tbl_Entry_t*
69Tbl_EntryAlloc(
70  Tbl_EntryType_t  type)
71{
72  Tbl_Entry_t *entry;
73
74  entry = ALLOC(Tbl_Entry_t,1);
75  entry->type = type;
76  if (type == Tbl_EntryEqual_c) {
77    entry->EntryData.var = -1;
78  }
79  else if (type == Tbl_EntryNormal_c) {
80    entry->EntryData.listOfRanges = lsCreate();
81  }
82  return entry;
83}
84
85/**Function********************************************************************
86
87  Synopsis    [This frees a given Tbl_Entry_t]
88
89  Description [This function frees the memory associated with a Tbl_Entry_t that
90               is given as input]
91
92  SideEffects [ The Var_Variable_t must be freed by the user]
93
94  SeeAlso     [TblEntryAlloc]
95
96******************************************************************************/
97void
98Tbl_EntryFree(
99  Tbl_Entry_t * entry)
100{
101  if (entry->type == Tbl_EntryNormal_c) {
102    lsDestroy(entry->EntryData.listOfRanges,(void (*)(lsGeneric))TblRangeFree);
103  }
104
105  FREE(entry);
106  entry = NIL(Tbl_Entry_t);
107}
108/**Function********************************************************************
109
110  Synopsis    [Duplicate a Tbl_Entry_t ]
111
112  Description [Given a Tbl_Entry_t, this function duplicates it. The new
113  entry does not belong to any table.]
114
115  SideEffects [Warning: For an entry of type Tbl_EntryEqual_c, this will
116  merely duplicate the column number of the equal type with no consistancy
117  checks. It is inadvisable to use this if you do not ensure that the
118  column variable corresponding to this id is what it is indeed equal to]
119
120  SeeAlso     [Tbl_TableSetEntry]
121
122******************************************************************************/
123Tbl_Entry_t *
124Tbl_EntryDup(
125  Tbl_Entry_t *entry)
126{
127  Tbl_Entry_t *newEntry;
128  lsGen gen;
129  Tbl_Range_t *range;
130
131  assert(entry != NIL(Tbl_Entry_t));
132  assert(entry->type != Tbl_EntryUnassigned_c);
133
134  newEntry = Tbl_EntryAlloc(entry->type);
135  newEntry->ioType = entry->ioType;
136  newEntry->varColNum = entry->varColNum;
137 
138  if (entry->type == Tbl_EntryNormal_c) {
139    lsForEachItem(entry->EntryData.listOfRanges, gen, range) {
140      Tbl_Range_t *newRange = ALLOC(Tbl_Range_t,1);
141      newRange->begin = range->begin;
142      newRange->end = range->end;
143      lsNewEnd(newEntry->EntryData.listOfRanges,(lsGeneric)newRange,LS_NH);     
144 
145    }
146  }
147  else if (entry->type == Tbl_EntryEqual_c) {
148    newEntry->EntryData.var = entry->EntryData.var;
149  }
150  return newEntry;
151}
152       
153
154/**Function********************************************************************
155
156  Synopsis    [Set value of entry to range val1-val2]
157
158  Description [Given an entry and a range designated by val1-val2, this function
159                sets the entry value to val1-val2. If the entry was already set
160                then it adds the value to the end, and also canonicalizes the list]
161
162  SideEffects [If the entry was already set then it adds the value to the end]
163
164  SeeAlso     []
165
166******************************************************************************/
167void
168Tbl_EntrySetValue(
169  Tbl_Entry_t *  entry,
170  int  val1,
171  int  val2)
172{
173  Tbl_Range_t *range;
174
175  assert(val2 >= val1);
176  assert(val1 >= 0);
177
178  entry->type = Tbl_EntryNormal_c;
179  range  = ALLOC(Tbl_Range_t,1);
180  range->begin = val1;
181  range->end = val2;
182  lsNewEnd(entry->EntryData.listOfRanges,(lsGeneric)range,LS_NH);
183  EntryCanonicalize(entry);
184}
185
186/**Function********************************************************************
187
188  Synopsis    [Given two Tbl_Entry_t's this function merges them into one.]
189
190  Description [Given two Tbl_entry_t* and b , this function  returns new
191  Tbl_Entry_t* that is the union of them.]
192
193  SideEffects [Both Tbl_Entries must be of the type Tbl_EntryNormal_c]
194
195  SeeAlso     []
196
197******************************************************************************/
198Tbl_Entry_t*
199Tbl_EntryMerge(
200    Tbl_Entry_t* entry1,
201    Tbl_Entry_t* entry2)
202{
203  lsGen gen, gen2,newGen;
204  Tbl_Range_t *range, *newRange;
205  Tbl_Entry_t *newEntry;
206   
207  if ((entry1->type == Tbl_EntryEqual_c)||(entry2->type ==
208                                            Tbl_EntryEqual_c)) {
209    return NIL(Tbl_Entry_t);
210  }
211
212  if ((entry1->type == Tbl_EntryUnassigned_c)||(entry2->type ==
213                                                 Tbl_EntryUnassigned_c)) {
214    return NIL(Tbl_Entry_t);
215  }
216
217  newEntry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
218  newGen = lsStart(newEntry->EntryData.listOfRanges);
219  lsForEachItem(entry1->EntryData.listOfRanges, gen, range) {
220    newRange = ALLOC(Tbl_Range_t,1);
221    newRange->begin = range->begin;
222    newRange->end = range->end;
223    lsInAfter(newGen,(lsGeneric)newRange,LS_NH);
224  }
225  lsForEachItem(entry2->EntryData.listOfRanges, gen2, range) {
226    newRange = ALLOC(Tbl_Range_t,1);
227    newRange->begin = range->begin;
228    newRange->end = range->end;
229    lsInAfter(newGen,(lsGeneric)newRange,LS_NH);
230  }
231  EntryCanonicalize(newEntry);
232  lsFinish(newGen);
233  return newEntry;
234}
235
236
237/**Function********************************************************************
238
239  Synopsis    [Complement the entry]
240
241  Description [Given an entry, and the associated minimum and maximum values of
242  the entry, this function  complements it]
243
244  SideEffects [Old entry is lost]
245
246  SeeAlso     []
247
248******************************************************************************/
249void
250Tbl_EntryComplement(
251  Tbl_Entry_t *  entry,
252  int min,
253  int max)
254{
255  EntryComplement(entry, min, max);
256  EntryCanonicalize(entry);
257}
258
259
260/**Function********************************************************************
261
262  Synopsis    [Sets entry equal to given Var]
263
264  Description [Given an Entry and an int, this sets the entry equal
265              to the column varCol. The Var must be part of the table]
266
267  SideEffects []
268
269  SeeAlso     []
270
271******************************************************************************/
272void
273Tbl_EntrySetEqual(
274  Tbl_Entry_t *  entry,
275/*  Var_Variable_t *  var*/
276  int varCol)
277{
278  entry->type=Tbl_EntryEqual_c;
279  entry->EntryData.var = varCol;   
280}
281
282/**Function********************************************************************
283
284  Synopsis    [Check if values in entry data are from val1-val2
285               alone.]
286
287  Description [Given an entry and a range val1-val2, then this function
288               returns a 1 if every value in the entry  is
289               in the range val1-val2.]
290
291  SideEffects []
292
293  SeeAlso     []
294
295******************************************************************************/
296boolean
297Tbl_EntryCheckRange(
298  Tbl_Entry_t *  entry,
299  int  val1,
300  int  val2)
301{
302  lsGen gen;
303  lsGeneric data;
304  Tbl_Range_t *range;
305 
306  gen = lsStart(entry->EntryData.listOfRanges);
307  while (lsNext(gen, &data, LS_NH) == LS_OK) {
308    range = (Tbl_Range_t*)data;
309    if (range->begin < val1) {
310      lsFinish(gen);
311      return FALSE;
312    }
313    if (range->end > val2) {
314      lsFinish(gen);     
315      return FALSE;
316    }
317  }
318  lsFinish(gen); 
319  return TRUE;
320}
321
322/**Function********************************************************************
323
324  Synopsis     [Test if entry is of type equal]
325
326  Description  [optional]
327
328  SideEffects  [required]
329
330  SeeAlso      [optional]
331
332******************************************************************************/
333boolean Tbl_EntryIsEqual(
334  Tbl_Entry_t *entry)
335{
336  return (entry->type==Tbl_EntryEqual_c);
337}
338
339
340
341/**Function********************************************************************
342
343  Synopsis    [return the actual variable associated with an entry]
344
345  Description [Given an entry and a table, this function will return the
346  actual Var_Variable_t in the table associated with this entry]
347
348  SideEffects []
349
350  SeeAlso     [Tbl_EntryReadVar]
351
352******************************************************************************/
353Var_Variable_t*
354Tbl_EntryReadActualVar(
355    Tbl_Table_t *table,
356    Tbl_Entry_t *entry)
357{
358  array_t *carray;
359
360  if (entry->ioType==0) {
361    carray = table->inputNames;
362  }
363  else if (entry->ioType==1) {
364    carray = table->outputNames;
365  }
366  else return NIL(Var_Variable_t);         
367   
368  return (array_fetch(Var_Variable_t*,carray,entry->varColNum));
369}
370
371
372/**Function********************************************************************
373
374  Synopsis    [return the equal variable associated with an entry]
375
376  Description [Given an entry and a table, this function will return the
377  Equal Var_Variable_t in the table associated with this entry]
378
379  SideEffects []
380
381  SeeAlso     [Tbl_EntryReadActualVar]
382
383******************************************************************************/
384Var_Variable_t*
385Tbl_EntryReadVar(
386    Tbl_Table_t *table,
387    Tbl_Entry_t *entry)
388{
389  array_t *carray;
390 
391  carray = table->inputNames;
392  if (array_n(carray) < Tbl_EntryReadVarIndex(entry)) {
393    fail(" FAIL: equal to output not supported\n");
394  }
395  return (array_fetch(Var_Variable_t*,carray,Tbl_EntryReadVarIndex(entry)));
396}
397
398/**Function********************************************************************
399
400  Synopsis    [This function returns  the index associated with the entry. The
401   entry must be of the type equal]
402
403  Description []
404
405  SideEffects []
406
407  SeeAlso     []
408
409******************************************************************************/
410int
411Tbl_EntryReadVarIndex(
412  Tbl_Entry_t * entry)
413{
414  assert(entry->type == Tbl_EntryEqual_c);
415  return (entry->EntryData.var);
416}
417
418/**Function********************************************************************
419
420  Synopsis    [Return Num of values in an entry]
421
422  Description [Given a Tbl_Entry_t, this function will return the number of
423  values that the variable in the entry actually takes. Note that the possible
424  number of values might be much larger]
425
426  SideEffects []
427
428  SeeAlso     []
429
430******************************************************************************/
431int
432Tbl_EntryReadNumValues(
433  Tbl_Entry_t * entry)
434{
435  lsGen gen;
436  int numOfValues;
437  Tbl_Range_t *range;
438
439  numOfValues = 0;
440  assert(entry->type == Tbl_EntryNormal_c);   
441  lsForEachItem(entry->EntryData.listOfRanges, gen, range) {
442    numOfValues = numOfValues + (range->end - range->begin + 1);
443  }
444  return (numOfValues);
445}
446
447/**Function********************************************************************
448
449  Synopsis    [Compare two entries]
450
451  Description [Given two  Tbl_Entry_t, this function will compare them to
452  see if they are equal. Both the entries must be canonical, and of the
453  type Tbl_EntryNormal_c]
454
455  SideEffects []
456
457  SeeAlso     []
458
459******************************************************************************/
460boolean
461Tbl_EntryTestEqualEntry(
462  Tbl_Entry_t * entrya,
463  Tbl_Entry_t * entryb)
464{
465  lsGen gena;
466  lsGen genb; 
467  Tbl_Range_t *rangea;
468  Tbl_Range_t *rangeb;
469  lsGeneric data;
470
471  assert(entrya->type == Tbl_EntryNormal_c);
472  assert(entryb->type == Tbl_EntryNormal_c);
473
474  if (lsLength(entrya->EntryData.listOfRanges) != \
475      lsLength(entryb->EntryData.listOfRanges))   {
476    return FALSE;
477  }
478
479  genb = lsStart(entryb->EntryData.listOfRanges); 
480  lsForEachItem(entrya->EntryData.listOfRanges, gena, rangea) {
481    if (lsNext(genb, &data,LS_NH) == LS_OK) {
482      rangeb = (Tbl_Range_t*)data;                       
483      if (rangea->begin != rangeb->begin) {
484        lsFinish(gena);
485        lsFinish(genb);
486        return FALSE;
487      }
488      if (rangea->end != rangeb->end){
489        lsFinish(gena);
490        lsFinish(genb);
491        return FALSE;
492      }
493    }
494    else {
495      return FALSE;
496    }
497  }
498  return TRUE;
499}
500
501/**Function********************************************************************
502
503  Synopsis    [Compare two entries to see if they intersect ]
504
505  Description [Given two  Tbl_Entry_t, this function will compare them to
506  see if they intersect. Both the entires must be canonical, and of the
507  type Tbl_EntryNormal_c. The function moves over both lists of ranges, and
508  checks to see if the begin of any range if less that or equal to the ]
509
510  SideEffects []
511
512  SeeAlso     []
513
514******************************************************************************/
515boolean
516Tbl_EntryTestIntersectEntry(
517  Tbl_Entry_t * entrya,
518  Tbl_Entry_t * entryb)
519{
520  lsGen gena;
521  lsGen genb; 
522  lsGeneric dataa;
523  lsGeneric datab; 
524  boolean checka, checkb;
525  Tbl_Range_t *rangea = NIL(Tbl_Range_t);
526  Tbl_Range_t *rangeb = NIL(Tbl_Range_t);
527
528  assert(entrya->type == Tbl_EntryNormal_c);
529  assert(entryb->type == Tbl_EntryNormal_c);
530
531  gena = lsStart(entrya->EntryData.listOfRanges);
532  genb = lsStart(entryb->EntryData.listOfRanges);
533
534  checka = TRUE;
535  checkb = TRUE; 
536  while((checka)||(checkb)) {
537    if (checka) {
538      if (lsNext(gena, &dataa,LS_NH) == LS_OK) {
539        rangea = (Tbl_Range_t*)dataa;
540      }
541      else {
542        lsFinish(gena);
543        lsFinish(genb);       
544        return FALSE;
545      }
546    }
547
548    if (checkb) {
549      if (lsNext(genb, &datab,LS_NH) == LS_OK) {
550        rangeb = (Tbl_Range_t*)datab;
551      }
552      else {
553        lsFinish(gena);
554        lsFinish(genb);       
555        return FALSE;
556      } 
557    }
558
559    if ((rangea->begin <= rangeb->end) &&(rangeb->begin <= rangea->end)) {     
560      lsFinish(gena);
561      lsFinish(genb);
562      return TRUE;
563    }
564    else if (rangea->end < rangeb->begin){
565      checka = TRUE;
566      checkb = FALSE;
567    }
568    else {
569      checka = FALSE;
570      checkb = TRUE;
571    }   
572  }
573  lsFinish(gena);
574  lsFinish(genb); 
575  return FALSE;   
576}
577
578/**Function********************************************************************
579
580  Synopsis    [Return lsList of values in an entry]
581
582  Description []
583
584  SideEffects [This list is NOT to be modified. The user is encouraged not
585  to use this function. It is exported so as to make the macros for iteration over
586  items in the entry possible. The user should use these macros for accessing data.
587  The macros that can be used are mentioned in the SeeAlso list]
588
589  SeeAlso     [Tbl_EntryForEachValue]
590
591******************************************************************************/
592lsList
593Tbl_EntryReadList(
594  Tbl_Entry_t * entry)
595{
596  return (entry->EntryData.listOfRanges);
597}
598
599
600/**Function********************************************************************
601
602  Synopsis    [Return the type of the given entry]
603
604  Description [Given a Tbl_Entry_t, this function returns its type,
605  either Tbl_EntryEqual_c or Tbl_EntryNormal_c.]
606
607  SideEffects []
608
609  SeeAlso     []
610
611******************************************************************************/
612Tbl_EntryType_t
613Tbl_EntryReadType(
614  Tbl_Entry_t *entry)
615{
616  return (entry->type);
617}
618
619
620/*---------------------------------------------------------------------------*/
621/* Definition of internal functions                                          */
622/*---------------------------------------------------------------------------*/
623
624/**Function********************************************************************
625
626  Synopsis    [Returns the mdd_t* for a table entry]
627
628  Description [Given an array of constituent mdd_t*, and a table entry, this returns
629  an mdd for the entry. The array of mdd_t's must contain an mdd_t for value i in
630  position i, for all values i.]
631
632  SideEffects []
633
634  SeeAlso     []
635
636******************************************************************************/
637mdd_t *
638TblEntryNormalConstructMdd(
639    mdd_manager *manager,
640    Tbl_Entry_t * entry,
641    array_t * mddArray)
642{
643  lsGen gen;
644  Tbl_Range_t *range;
645  int i;
646  mdd_t *result, *temp, *x;
647   
648  result = mdd_zero(manager);
649  lsForEachItem(entry->EntryData.listOfRanges, gen, range) {
650    for (i=range->begin; i< (range->end +1); i++) {
651      temp = result;
652      x = Mvf_FunctionObtainComponent(mddArray,i);
653      result = mdd_or(temp, x,1,1);
654      mdd_free(temp);
655      mdd_free(x);
656    }
657  }
658  return result;
659}
660
661
662/**Function********************************************************************
663
664  Synopsis    [Returns the mdd_t* for a table entry]
665
666  Description [Given an array of constituent mdd_t*, and a table entry, this returns
667  an mdd for the entry. The array of mdd_t's must contain an mdd_t for value i in
668  position i, for all values i.]
669
670  SideEffects []
671
672  SeeAlso     []
673
674******************************************************************************/
675mdd_t *
676TblEntryEqualConstructMdd(
677    mdd_manager *manager,
678    Tbl_Entry_t * entry,
679    Mvf_Function_t * mddArray,
680    Mvf_Function_t * mddEArray)
681{
682  lsGen gen;
683  Tbl_Range_t *range;
684  int i;
685  mdd_t *result, *temp, *x;
686
687  assert(entry->type == Tbl_EntryNormal_c);
688  result = mdd_zero(manager);
689  lsForEachItem(entry->EntryData.listOfRanges, gen, range) {
690    for (i=range->begin; i< (range->end +1); i++) {
691      temp = result;
692      x = Mvf_FunctionObtainComponent(mddArray,i);
693      result = mdd_or(temp, x,1,1);
694      mdd_free(temp);
695      temp = result;
696      x = Mvf_FunctionObtainComponent(mddEArray,i);
697      result = mdd_or(temp, x,1,1);
698      mdd_free(temp);
699    }
700  }
701  return result;
702}
703
704/**Function********************************************************************
705
706  Synopsis    [print an entry in symbolic form.]
707
708  Description [Given a Tbl_Entry_t , a fileptr and a table, this function prints
709  it in blif_mv format. This function accounts for variables with symbolic values]
710
711  SideEffects []
712
713  SeeAlso     [Tbl_TableWriteBlif]
714
715******************************************************************************/
716void
717TblEntryWriteBlifMv(
718    Tbl_Table_t *table,
719    Tbl_Entry_t *entry,
720    FILE *fp)
721{
722  lsGen gen;
723  Tbl_Range_t *range;
724  Var_Variable_t *var;
725  boolean test, testParen;
726  int i, itemNum, length;
727   
728  var = Tbl_EntryReadActualVar(table,entry);
729  test = Var_VariableTestIsSymbolic(var);
730  testParen = TRUE;
731 
732  if (entry != NIL(Tbl_Entry_t)) {
733    if (entry->type == Tbl_EntryNormal_c) {
734      length = lsLength(entry->EntryData.listOfRanges);
735     
736      if (length == 1){
737        var = Tbl_EntryReadActualVar(table,entry);
738        lsForEachItem(entry->EntryData.listOfRanges, gen, range) {
739          if ((range->begin ==0)&&(range->end == Var_VariableReadNumValues(var)-1)){
740            fprintf(fp,"-");
741          lsFinish(gen);           
742            return;
743          }
744        }
745      }
746     
747      itemNum = 1;
748      if (length ==1) {
749        testParen = FALSE;
750      }
751     
752      lsForEachItem(entry->EntryData.listOfRanges, gen, range) {
753        if (itemNum ==1) {
754          if (testParen) {
755              fprintf(fp,"(");
756          }
757        }
758         
759        if (itemNum < length) {
760          if (test == FALSE) {
761            if (range->end != range->begin) {
762              fprintf(fp,"{%d-%d},", range->begin, range->end);
763            }
764            else {
765              fprintf(fp,"%d,", range->end);
766            }
767          }
768          else {
769            if (range->end != range->begin) {
770                fprintf(fp,"(%s,",Var_VariableReadSymbolicValueFromIndex(var,range->begin));
771                for (i= range->begin+1; i < range->end ; i++) {
772                fprintf(fp,"%s,",Var_VariableReadSymbolicValueFromIndex(var,i));
773              }
774                       
775              fprintf(fp,"%s),",Var_VariableReadSymbolicValueFromIndex(var,range->end));
776            }
777            else {
778              fprintf(fp,"%s,",Var_VariableReadSymbolicValueFromIndex(var,range->end));
779            }
780          }
781        }
782        else {
783          if (test == FALSE) {
784            if (range->end != range->begin)
785              fprintf(fp,"{%d-%d}", range->begin, range->end);
786            else fprintf(fp,"%d", range->end);
787          }
788          else {
789            if (range->end != range->begin) {
790                fprintf(fp,"(%s,",Var_VariableReadSymbolicValueFromIndex(var,range->begin));
791                for (i= range->begin+1; i < range->end ; i++) {
792                fprintf(fp,"%s,",Var_VariableReadSymbolicValueFromIndex(var,i));
793              }
794                       
795              fprintf(fp,"%s)",Var_VariableReadSymbolicValueFromIndex(var,range->end));
796            }
797            else {
798              fprintf(fp,"%s",Var_VariableReadSymbolicValueFromIndex(var,range->end));
799            }
800          }   
801        }
802      itemNum++;       
803      }
804      if (testParen) {     
805        fprintf(fp,")");
806      }
807    }
808    else if (entry->type == Tbl_EntryEqual_c) {
809      fprintf(fp,"=%s", Var_VariableReadName(Tbl_EntryReadVar(table,entry)));
810    }
811  }
812  else printf("NIL Entry ");
813}
814
815/**Function********************************************************************
816 
817  Synopsis    [print an entry in symbolic form.]
818
819  Description [Given a Tbl_Entry_t , a fileptr and a table, this function prints
820  it in smv format. This function accounts for variables with symbolic values]
821
822  SideEffects []
823
824  SeeAlso     [Tbl_TableWriteBlif, Tbl_TableWriteBlifMv]
825
826******************************************************************************/
827void
828TblEntryWriteSmv(
829    Tbl_Table_t *table,
830    Tbl_Entry_t *entry,
831    boolean varnameflag,
832    FILE *fp)
833{
834  lsGen gen;
835  Tbl_Range_t *range;
836  Var_Variable_t *var;
837  boolean symbolic, testParen;
838  int i, itemNum, length;
839   
840  var = Tbl_EntryReadActualVar(table,entry);
841  symbolic = Var_VariableTestIsSymbolic(var);
842  testParen = TRUE;
843 
844  if (entry != NIL(Tbl_Entry_t)) {
845    if (entry->type == Tbl_EntryNormal_c) {
846      length = lsLength(entry->EntryData.listOfRanges);
847     
848      if (length == 1){
849        var = Tbl_EntryReadActualVar(table,entry);
850        lsForEachItem(entry->EntryData.listOfRanges, gen, range) {
851          if ((range->begin ==0)&&(range->end == Var_VariableReadNumValues(var)-1)){
852            fprintf(fp,"1"); /* A don't-care is always true */
853          lsFinish(gen);           
854            return;
855          }
856        }
857      }
858     
859      if (!varnameflag) {
860        fprintf(fp,"(");
861        Io_SmvPrintVar(fp,var);
862      }
863      itemNum = 1;
864      if (length ==1) {
865        testParen = FALSE;
866      }
867     
868      lsForEachItem(entry->EntryData.listOfRanges, gen, range) {
869        if (!varnameflag) {
870          if (itemNum ==1) {
871            if (testParen) {
872              fprintf(fp," IN {");
873            } else {
874              fprintf(fp, "=");
875            }
876          }
877        }
878       
879        if (itemNum < length) {
880          if (symbolic == FALSE) {
881            if (range->end != range->begin) {
882              for (i= range->begin; i < range->end ; i++)
883                fprintf(fp,"%d,",i);
884            }
885            fprintf(fp,"%d,", range->end);
886          }
887          else {
888            if (range->end != range->begin) {
889                fprintf(fp,"%s,",Var_VariableReadSymbolicValueFromIndex(var,range->begin));
890                for (i= range->begin+1; i < range->end ; i++) {
891                  fprintf(fp,"%s,",Var_VariableReadSymbolicValueFromIndex(var,i));
892                }
893                       
894                fprintf(fp,"%s,",Var_VariableReadSymbolicValueFromIndex(var,range->end));
895            }
896            else {
897              fprintf(fp,"%s,",Var_VariableReadSymbolicValueFromIndex(var,range->end));
898            }
899          }
900        }
901        else {
902          if (symbolic == FALSE) {
903            if (range->end != range->begin) {
904              for (i= range->begin; i < range->end ; i++)
905                fprintf(fp,"%d,",i);
906            }
907            fprintf(fp,"%d", range->end);
908          }
909          else {
910            if (range->end != range->begin) {
911                fprintf(fp,"%s,",Var_VariableReadSymbolicValueFromIndex(var,range->begin));
912                for (i= range->begin+1; i < range->end ; i++) {
913                fprintf(fp,"%s,",Var_VariableReadSymbolicValueFromIndex(var,i));
914              }
915                       
916              fprintf(fp,"%s",Var_VariableReadSymbolicValueFromIndex(var,range->end));
917            }
918            else {
919              fprintf(fp,"%s",Var_VariableReadSymbolicValueFromIndex(var,range->end));
920            }
921          }   
922        }
923      itemNum++;       
924      }
925      if (testParen) {     
926        fprintf(fp,"} ");
927      }
928      if (!varnameflag) {
929        fprintf(fp, ") ");
930      }
931    }
932    else if (entry->type == Tbl_EntryEqual_c) {
933      if (!varnameflag) {
934        Io_SmvPrintVar(fp, var);
935        fprintf(fp,"=");
936      }
937      Io_SmvPrintVar(fp, Tbl_EntryReadVar(table,entry));
938    }
939  }
940  else printf("NIL Entry ");
941}
942
943
944/**Function********************************************************************
945
946  Synopsis    [print an entry in blif form.]
947
948  Description [Given a Tbl_Entry_t , a fileptr and a table, this function prints
949  it in blif format.]
950
951  SideEffects []
952
953  SeeAlso     []
954
955******************************************************************************/
956void
957TblEntryWriteBlif(
958    Tbl_Table_t *table,
959    Tbl_Entry_t *entry,
960    FILE *fp)
961{
962  lsGen gen;
963  Tbl_Range_t *range;
964  Var_Variable_t *var;
965  boolean test;
966  int i, itemNum, length;
967   
968  var = Tbl_EntryReadActualVar(table,entry);
969  test = Var_VariableTestIsSymbolic(var);
970  if (entry != NIL(Tbl_Entry_t)) {
971    if (entry->type == Tbl_EntryNormal_c) {
972      length = lsLength(entry->EntryData.listOfRanges);     
973      if (length == 1){
974        var = Tbl_EntryReadActualVar(table,entry);
975        lsForEachItem(entry->EntryData.listOfRanges, gen, range) {
976          if ((range->begin ==0)&&(range->end == Var_VariableReadNumValues(var)-1)){
977            fprintf(fp,"-");
978          lsFinish(gen);           
979            return;
980          }
981        }
982      }
983
984      length = lsLength(entry->EntryData.listOfRanges);
985      itemNum = 1;
986      lsForEachItem(entry->EntryData.listOfRanges, gen, range) {
987        if (itemNum < length) {
988          if (test == FALSE) {
989            if (range->end != range->begin) {
990              fprintf(fp,"{%d-%d},", range->begin, range->end);
991            }
992            else {
993              fprintf(fp,"%d,", range->end);
994            }
995          }
996          else {
997            if (range->end != range->begin) {
998              for (i= range->begin; i < range->end ; i++) {
999                fprintf(fp,"%s,",Var_VariableReadSymbolicValueFromIndex(var,i));
1000              }
1001                       
1002              fprintf(fp,"%s",Var_VariableReadSymbolicValueFromIndex(var,range->end));
1003            }
1004            else {
1005              fprintf(fp,"%s,",Var_VariableReadSymbolicValueFromIndex(var,range->end));
1006            }
1007          }
1008        }
1009        else {
1010          if (test == FALSE) {
1011            if (range->end != range->begin)
1012              fprintf(fp,"{%d-%d}", range->begin, range->end);
1013            else fprintf(fp,"%d", range->end);
1014          }
1015          else {
1016            if (range->end != range->begin) {
1017              for (i= range->begin; i < range->end ; i++) {
1018                fprintf(fp,"%s,",Var_VariableReadSymbolicValueFromIndex(var,i));
1019              }
1020                       
1021              fprintf(fp,"%s",Var_VariableReadSymbolicValueFromIndex(var,range->end));
1022            }
1023            else {
1024              fprintf(fp,"%s",Var_VariableReadSymbolicValueFromIndex(var,range->end));
1025            }   
1026          }
1027        }
1028        itemNum++;       
1029      }
1030    }
1031    else if (entry->type == Tbl_EntryEqual_c) {
1032      fprintf(fp," =%s ",Var_VariableReadName(Tbl_EntryReadVar(table,entry)));
1033    }
1034  }
1035  else printf("NIL Entry ");
1036}
1037
1038/**Function********************************************************************
1039
1040  Synopsis    [This frees a given Tbl_Entry_t]
1041
1042  Description [This function frees the memory assocated with a Tbl_Entry_t that
1043               is given as input]
1044
1045  SideEffects [ The Var_Variable_t must be freed by the user]
1046
1047  SeeAlso     [TblEntryAlloc]
1048
1049******************************************************************************/
1050void
1051TblRangeFree(
1052  Tbl_Range_t * range)
1053{
1054  FREE(range);
1055}
1056
1057/**Function********************************************************************
1058
1059  Synopsis    [return the begin value of a Tbl_Range_t]
1060
1061  Description []
1062
1063  SideEffects [The user is encouraged not
1064  to use this function. It is exported so as to make the macros for iteration over
1065  items in the table possible. The user should use these macros for accessing data.
1066  The macros that can be used are mentioned in the SeeAlso list]
1067
1068  SeeAlso     []
1069
1070******************************************************************************/
1071int
1072Tbl_RangeBegin(
1073  Tbl_Range_t *range)
1074{
1075  return(range->begin);
1076}
1077
1078/**Function********************************************************************
1079
1080  Synopsis    [return the end value of a Tbl_Range_t]
1081
1082  Description []
1083
1084  SideEffects [The user is encouraged not
1085  to use this function. It is exported so as to make the macros for iteration over
1086  items in the table possible. The user should use these macros for accessing data.
1087  The macros that can be used are mentioned in the SeeAlso list]
1088
1089  SeeAlso     []
1090
1091******************************************************************************/
1092int
1093Tbl_RangeEnd(
1094  Tbl_Range_t *range)
1095{
1096  return(range->end);
1097}
1098
1099/*---------------------------------------------------------------------------*/
1100/* Definition of static functions                                            */
1101/*---------------------------------------------------------------------------*/
1102
1103/**Function********************************************************************
1104
1105  Synopsis    [A function for comparing 2 ranges]
1106
1107  Description [This function return a -1 if range1 is subset of
1108               range2, a 1 if range1 is a superset of range2, and 0 if
1109               neither statement is true]
1110
1111  SideEffects []
1112
1113  SeeAlso     [EntryCanonicalize]
1114
1115******************************************************************************/
1116static int
1117RangeCompare(
1118  lsGeneric entry1,
1119  lsGeneric entry2)
1120{
1121  Tbl_Range_t * range1 = (Tbl_Range_t *) entry1;
1122  Tbl_Range_t * range2 = (Tbl_Range_t *) entry2;
1123  int value = 0;
1124
1125  if (range1->begin > range2->begin) {
1126    value = 1;
1127  }
1128  else if (range1->begin < range2->begin) {
1129    value = -1;
1130  }
1131  else if (range1->begin == range2->begin) {
1132    if (range1->end > range2->end) {
1133      value = 1;
1134    }
1135    else if (range1->end <  range2->end) {
1136      value = -1;
1137    }
1138  }
1139  return value;
1140}
1141
1142/**Function********************************************************************
1143
1144  Synopsis    [Canonicalize a table entry]
1145
1146  Description [Given a table entry, this canonicalizes the lsList of
1147               ranges by sorting and merging the ranges. If the entry
1148               is of Tbl_EntryEqual_c type, it returns without making
1149               any changes. Note that the gen in the list package has
1150               positions in between prev and next items, and hence
1151               after each deletion its position has to be re-adjusted.
1152
1153               This function iterates over the entire list of ranges
1154               and checks to see if two sucessive ranges overlap. If
1155               they do, this function creates a larger list containing
1156               bothe ranges, adds it to the list and subtracts the
1157               other two.]
1158
1159  SideEffects [The old table list of ranges is lost]
1160
1161  SeeAlso     []
1162
1163******************************************************************************/
1164static void
1165EntryCanonicalize(
1166  Tbl_Entry_t *  entry)
1167{
1168  lsGen gen;
1169  Tbl_Range_t *range, *newRange, *nextRange;
1170  lsGeneric data;
1171
1172  if (entry->type == Tbl_EntryEqual_c) {
1173    return;
1174  }
1175
1176  if (entry->type == Tbl_EntryUnassigned_c) {
1177    return;
1178  }
1179
1180  if (lsLength(entry->EntryData.listOfRanges)  > 1) {
1181    lsSort(entry->EntryData.listOfRanges,RangeCompare);
1182    lsForEachItem(entry->EntryData.listOfRanges, gen, range) {
1183      if (lsNext(gen, &data,LS_NH) == LS_OK) {
1184        nextRange = (Tbl_Range_t*)data;
1185        if (nextRange->begin < (range->end + 2)) {
1186          if (nextRange->end > range->end) {
1187            newRange = ALLOC(Tbl_Range_t,1);
1188            newRange->begin = range->begin;
1189            newRange->end = nextRange->end;
1190            lsInAfter(gen,(lsGeneric)newRange,LS_NH);
1191            lsDelBefore(gen,(lsGeneric*)nextRange);
1192            TblRangeFree(nextRange);
1193            lsDelBefore(gen,(lsGeneric*)range);
1194            TblRangeFree(range);
1195          }
1196          else {
1197            lsDelBefore(gen,(lsGeneric*)nextRange);
1198            TblRangeFree(nextRange);
1199            if (lsPrev(gen,&data,LS_NH)!= LS_OK) {
1200              (void) lsFinish(gen);
1201            }
1202          }
1203        }
1204        else {
1205          lsPrev(gen,&data,LS_NH);
1206        }
1207      }
1208    }
1209  }
1210}
1211
1212
1213/**Function********************************************************************
1214
1215  Synopsis    [Complement the entry of a table]
1216
1217  Description [Given a table entry, this complement the entry by
1218               getting the complement list of ranges. Note that the
1219               list must be canonical.  The list that is returned is
1220               canonical by construction. Notice that the min and max
1221               values for the Var_Variable_t associated with the entry
1222               must be provided.]
1223               
1224  SideEffects [The old table list of ranges is lost.]
1225
1226  SeeAlso     []
1227
1228******************************************************************************/
1229static void
1230EntryComplement(
1231  Tbl_Entry_t *  entry,
1232  int min,
1233  int max)
1234{
1235  lsGen gen, newGen;
1236  Tbl_Range_t *range, *newRange, *nextRange;
1237  lsList newRangeList;
1238  int listMin, listMax;
1239  lsGeneric data;
1240   
1241  if (entry->type == Tbl_EntryEqual_c) {
1242    return;
1243  }
1244
1245  if (entry->type == Tbl_EntryUnassigned_c) {
1246    return;
1247  }
1248
1249  listMin = max;
1250  listMax = min;
1251  newRangeList = lsCreate();
1252  newGen = lsStart(newRangeList);
1253  lsForEachItem(entry->EntryData.listOfRanges, gen, range) {
1254    if (lsNext(gen, &data, LS_NH) == LS_OK) {
1255      nextRange = (Tbl_Range_t*)data;
1256      newRange = ALLOC(Tbl_Range_t,1);
1257      newRange->begin = range->end +1;
1258      newRange->end = nextRange->begin -1;
1259      lsInAfter(newGen,(lsGeneric)newRange,LS_NH);
1260      lsPrev(gen, &data, LS_NH);
1261    }     
1262    if (listMin > range->begin) listMin = range->begin;
1263    if (listMax < range->end) listMax = range->end;
1264  }
1265  lsFinish(newGen);
1266  if (min < listMin) {
1267    newRange = ALLOC(Tbl_Range_t,1);
1268    newRange->begin = min;
1269    newRange->end = listMin -1;
1270    lsNewBegin(newRangeList,(lsGeneric)newRange,LS_NH);
1271  }
1272  if (listMax < max) {
1273    newRange = ALLOC(Tbl_Range_t,1);
1274    newRange->begin = listMax +1;
1275    newRange->end = max;
1276    lsNewEnd(newRangeList,(lsGeneric)newRange,LS_NH);
1277  }
1278  lsDestroy(entry->EntryData.listOfRanges,(void (*)(lsGeneric))TblRangeFree);
1279  entry->EntryData.listOfRanges = newRangeList;
1280}
Note: See TracBrowser for help on using the repository browser.