source: vis_dev/glu-2.1/src/cuBdd/cuddApa.c @ 8

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

src glu

File size: 26.8 KB
Line 
1/**CFile***********************************************************************
2
3  FileName    [cuddApa.c]
4
5  PackageName [cudd]
6
7  Synopsis    [Arbitrary precision arithmetic functions.]
8
9  Description [External procedures included in this module:
10                <ul>
11                <li>
12                </ul>
13        Internal procedures included in this module:
14                <ul>
15                <li> ()
16                </ul>
17        Static procedures included in this module:
18                <ul>
19                <li> ()
20                </ul>]
21
22  Author      [Fabio Somenzi]
23
24  Copyright   [Copyright (c) 1995-2004, Regents of the University of Colorado
25
26  All rights reserved.
27
28  Redistribution and use in source and binary forms, with or without
29  modification, are permitted provided that the following conditions
30  are met:
31
32  Redistributions of source code must retain the above copyright
33  notice, this list of conditions and the following disclaimer.
34
35  Redistributions in binary form must reproduce the above copyright
36  notice, this list of conditions and the following disclaimer in the
37  documentation and/or other materials provided with the distribution.
38
39  Neither the name of the University of Colorado nor the names of its
40  contributors may be used to endorse or promote products derived from
41  this software without specific prior written permission.
42
43  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
46  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
47  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
48  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
49  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
51  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
53  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
54  POSSIBILITY OF SUCH DAMAGE.]
55
56******************************************************************************/
57
58#include "util.h"
59#include "cuddInt.h"
60
61/*---------------------------------------------------------------------------*/
62/* Constant declarations                                                     */
63/*---------------------------------------------------------------------------*/
64
65/*---------------------------------------------------------------------------*/
66/* Stucture declarations                                                     */
67/*---------------------------------------------------------------------------*/
68
69/*---------------------------------------------------------------------------*/
70/* Type declarations                                                         */
71/*---------------------------------------------------------------------------*/
72
73/*---------------------------------------------------------------------------*/
74/* Variable declarations                                                     */
75/*---------------------------------------------------------------------------*/
76
77#ifndef lint
78static char rcsid[] DD_UNUSED = "$Id: cuddApa.c,v 1.16 2004/08/13 18:04:46 fabio Exp $";
79#endif
80
81static  DdNode  *background, *zero;
82
83/*---------------------------------------------------------------------------*/
84/* Macro declarations                                                        */
85/*---------------------------------------------------------------------------*/
86
87#ifdef __cplusplus
88extern "C" {
89#endif
90
91/**AutomaticStart*************************************************************/
92
93/*---------------------------------------------------------------------------*/
94/* Static function prototypes                                                */
95/*---------------------------------------------------------------------------*/
96
97static DdApaNumber cuddApaCountMintermAux (DdNode * node, int digits, DdApaNumber max, DdApaNumber min, st_table * table);
98static enum st_retval cuddApaStCountfree (char * key, char * value, char * arg);
99
100/**AutomaticEnd***************************************************************/
101
102#ifdef __cplusplus
103} /* end of extern "C" */
104#endif
105
106
107/*---------------------------------------------------------------------------*/
108/* Definition of exported functions                                          */
109/*---------------------------------------------------------------------------*/
110
111
112/**Function********************************************************************
113
114  Synopsis    [Finds the number of digits for an arbitrary precision
115  integer.]
116
117  Description [Finds the number of digits for an arbitrary precision
118  integer given the maximum number of binary digits.  The number of
119  binary digits should be positive. Returns the number of digits if
120  successful; 0 otherwise.]
121
122  SideEffects [None]
123
124  SeeAlso     []
125
126******************************************************************************/
127int
128Cudd_ApaNumberOfDigits(
129  int  binaryDigits)
130{
131    int digits;
132
133    digits = binaryDigits / DD_APA_BITS;
134    if ((digits * DD_APA_BITS) != binaryDigits)
135        digits++;
136    return(digits);
137
138} /* end of Cudd_ApaNumberOfDigits */
139           
140
141/**Function********************************************************************
142
143  Synopsis    [Allocates memory for an arbitrary precision integer.]
144
145  Description [Allocates memory for an arbitrary precision
146  integer. Returns a pointer to the allocated memory if successful;
147  NULL otherwise.]
148
149  SideEffects [None]
150
151  SeeAlso     []
152
153******************************************************************************/
154DdApaNumber
155Cudd_NewApaNumber(
156  int  digits)
157{
158    return(ALLOC(DdApaDigit, digits));
159
160} /* end of Cudd_NewApaNumber */
161
162
163/**Function********************************************************************
164
165  Synopsis    [Makes a copy of an arbitrary precision integer.]
166
167  Description [Makes a copy of an arbitrary precision integer.]
168
169  SideEffects [Changes parameter <code>dest</code>.]
170
171  SeeAlso     []
172
173******************************************************************************/
174void
175Cudd_ApaCopy(
176  int  digits,
177  DdApaNumber  source,
178  DdApaNumber  dest)
179{
180    int i;
181
182    for (i = 0; i < digits; i++) {
183        dest[i] = source[i];
184    }
185
186} /* end of Cudd_ApaCopy */
187
188
189/**Function********************************************************************
190
191  Synopsis    [Adds two arbitrary precision integers.]
192
193  Description [Adds two arbitrary precision integers.  Returns the
194  carry out of the most significant digit.]
195
196  SideEffects [The result of the sum is stored in parameter <code>sum</code>.]
197
198  SeeAlso     []
199
200******************************************************************************/
201DdApaDigit
202Cudd_ApaAdd(
203  int  digits,
204  DdApaNumber  a,
205  DdApaNumber  b,
206  DdApaNumber  sum)
207{
208    int i;
209    DdApaDoubleDigit partial = 0;
210
211    for (i = digits - 1; i >= 0; i--) {
212        partial = a[i] + b[i] + DD_MSDIGIT(partial);
213        sum[i] = (DdApaDigit) DD_LSDIGIT(partial);
214    }
215    return((DdApaDigit) DD_MSDIGIT(partial));
216
217} /* end of Cudd_ApaAdd */
218
219
220/**Function********************************************************************
221
222  Synopsis    [Subtracts two arbitrary precision integers.]
223
224  Description [Subtracts two arbitrary precision integers.  Returns the
225  borrow out of the most significant digit.]
226
227  SideEffects [The result of the subtraction is stored in parameter
228  <code>diff</code>.]
229
230  SeeAlso     []
231
232******************************************************************************/
233DdApaDigit
234Cudd_ApaSubtract(
235  int  digits,
236  DdApaNumber  a,
237  DdApaNumber  b,
238  DdApaNumber  diff)
239{
240    int i;
241    DdApaDoubleDigit partial = DD_APA_BASE;
242
243    for (i = digits - 1; i >= 0; i--) {
244        partial = a[i] - b[i] + DD_MSDIGIT(partial) + DD_APA_MASK;
245        diff[i] = (DdApaDigit) DD_LSDIGIT(partial);
246    }
247    return((DdApaDigit) DD_MSDIGIT(partial) - 1);
248
249} /* end of Cudd_ApaSubtract */
250
251
252/**Function********************************************************************
253
254  Synopsis    [Divides an arbitrary precision integer by a digit.]
255
256  Description [Divides an arbitrary precision integer by a digit.]
257
258  SideEffects [The quotient is returned in parameter <code>quotient</code>.]
259
260  SeeAlso     []
261
262******************************************************************************/
263DdApaDigit
264Cudd_ApaShortDivision(
265  int  digits,
266  DdApaNumber  dividend,
267  DdApaDigit  divisor,
268  DdApaNumber  quotient)
269{
270    int i;
271    DdApaDigit remainder;
272    DdApaDoubleDigit partial;
273
274    remainder = 0;
275    for (i = 0; i < digits; i++) {
276        partial = remainder * DD_APA_BASE + dividend[i];
277        quotient[i] = (DdApaDigit) (partial/(DdApaDoubleDigit)divisor);
278        remainder = (DdApaDigit) (partial % divisor);
279    }
280
281    return(remainder);
282
283} /* end of Cudd_ApaShortDivision */
284
285
286/**Function********************************************************************
287
288  Synopsis    [Divides an arbitrary precision integer by an integer.]
289
290  Description [Divides an arbitrary precision integer by a 32-bit
291  unsigned integer. Returns the remainder of the division. This
292  procedure relies on the assumption that the number of bits of a
293  DdApaDigit plus the number of bits of an unsigned int is less the
294  number of bits of the mantissa of a double. This guarantees that the
295  product of a DdApaDigit and an unsigned int can be represented
296  without loss of precision by a double. On machines where this
297  assumption is not satisfied, this procedure will malfunction.]
298
299  SideEffects [The quotient is returned in parameter <code>quotient</code>.]
300
301  SeeAlso     [Cudd_ApaShortDivision]
302
303******************************************************************************/
304unsigned int
305Cudd_ApaIntDivision(
306  int  digits,
307  DdApaNumber dividend,
308  unsigned int divisor,
309  DdApaNumber quotient)
310{
311    int i;
312    double partial;
313    unsigned int remainder = 0;
314    double ddiv = (double) divisor;
315
316    for (i = 0; i < digits; i++) {
317        partial = (double) remainder * DD_APA_BASE + dividend[i];
318        quotient[i] = (DdApaDigit) (partial / ddiv);
319        remainder = (unsigned int) (partial - ((double)quotient[i] * ddiv));
320    }
321
322    return(remainder);
323
324} /* end of Cudd_ApaIntDivision */
325
326
327/**Function********************************************************************
328
329  Synopsis [Shifts right an arbitrary precision integer by one binary
330  place.]
331
332  Description [Shifts right an arbitrary precision integer by one
333  binary place. The most significant binary digit of the result is
334  taken from parameter <code>in</code>.]
335
336  SideEffects [The result is returned in parameter <code>b</code>.]
337
338  SeeAlso     []
339
340******************************************************************************/
341void
342Cudd_ApaShiftRight(
343  int  digits,
344  DdApaDigit  in,
345  DdApaNumber  a,
346  DdApaNumber  b)
347{
348    int i;
349
350    for (i = digits - 1; i > 0; i--) {
351        b[i] = (a[i] >> 1) | ((a[i-1] & 1) << (DD_APA_BITS - 1));
352    }
353    b[0] = (a[0] >> 1) | (in << (DD_APA_BITS - 1));
354
355} /* end of Cudd_ApaShiftRight */
356
357
358/**Function********************************************************************
359
360  Synopsis    [Sets an arbitrary precision integer to a one-digit literal.]
361
362  Description [Sets an arbitrary precision integer to a one-digit literal.]
363
364  SideEffects [The result is returned in parameter <code>number</code>.]
365
366  SeeAlso     []
367
368******************************************************************************/
369void
370Cudd_ApaSetToLiteral(
371  int  digits,
372  DdApaNumber  number,
373  DdApaDigit  literal)
374{
375    int i;
376
377    for (i = 0; i < digits - 1; i++)
378        number[i] = 0;
379    number[digits - 1] = literal;
380
381} /* end of Cudd_ApaSetToLiteral */
382
383
384/**Function********************************************************************
385
386  Synopsis    [Sets an arbitrary precision integer to a power of two.]
387
388  Description [Sets an arbitrary precision integer to a power of
389  two. If the power of two is too large to be represented, the number
390  is set to 0.]
391
392  SideEffects [The result is returned in parameter <code>number</code>.]
393
394  SeeAlso     []
395
396******************************************************************************/
397void
398Cudd_ApaPowerOfTwo(
399  int  digits,
400  DdApaNumber  number,
401  int  power)
402{
403    int i;
404    int index;
405
406    for (i = 0; i < digits; i++)
407        number[i] = 0;
408    i = digits - 1 - power / DD_APA_BITS;
409    if (i < 0) return;
410    index = power & (DD_APA_BITS - 1);
411    number[i] = 1 << index;
412
413} /* end of Cudd_ApaPowerOfTwo */
414
415
416/**Function********************************************************************
417
418  Synopsis    [Compares two arbitrary precision integers.]
419
420  Description [Compares two arbitrary precision integers. Returns 1 if
421  the first number is larger; 0 if they are equal; -1 if the second
422  number is larger.]
423
424  SideEffects [None]
425
426  SeeAlso     []
427
428******************************************************************************/
429int
430Cudd_ApaCompare(
431  int digitsFirst,
432  DdApaNumber  first,
433  int digitsSecond,
434  DdApaNumber  second)
435{
436    int i;
437    int firstNZ, secondNZ;
438
439    /* Find first non-zero in both numbers. */
440    for (firstNZ = 0; firstNZ < digitsFirst; firstNZ++)
441        if (first[firstNZ] != 0) break;
442    for (secondNZ = 0; secondNZ < digitsSecond; secondNZ++)
443        if (second[secondNZ] != 0) break;
444    if (digitsFirst - firstNZ > digitsSecond - secondNZ) return(1);
445    else if (digitsFirst - firstNZ < digitsSecond - secondNZ) return(-1);
446    for (i = 0; i < digitsFirst - firstNZ; i++) {
447        if (first[firstNZ + i] > second[secondNZ + i]) return(1);
448        else if (first[firstNZ + i] < second[secondNZ + i]) return(-1);
449    }
450    return(0);
451
452} /* end of Cudd_ApaCompare */
453
454
455/**Function********************************************************************
456
457  Synopsis    [Compares the ratios of two arbitrary precision integers to two
458  unsigned ints.]
459
460  Description [Compares the ratios of two arbitrary precision integers
461  to two unsigned ints. Returns 1 if the first number is larger; 0 if
462  they are equal; -1 if the second number is larger.]
463
464  SideEffects [None]
465
466  SeeAlso     []
467
468******************************************************************************/
469int
470Cudd_ApaCompareRatios(
471  int digitsFirst,
472  DdApaNumber firstNum,
473  unsigned int firstDen,
474  int digitsSecond,
475  DdApaNumber secondNum,
476  unsigned int secondDen)
477{
478    int result;
479    DdApaNumber first, second;
480    unsigned int firstRem, secondRem;
481
482    first = Cudd_NewApaNumber(digitsFirst);
483    firstRem = Cudd_ApaIntDivision(digitsFirst,firstNum,firstDen,first);
484    second = Cudd_NewApaNumber(digitsSecond);
485    secondRem = Cudd_ApaIntDivision(digitsSecond,secondNum,secondDen,second);
486    result = Cudd_ApaCompare(digitsFirst,first,digitsSecond,second);
487    if (result == 0) {
488        if ((double)firstRem/firstDen > (double)secondRem/secondDen)
489            return(1);
490        else if ((double)firstRem/firstDen < (double)secondRem/secondDen)
491            return(-1);
492    }
493    return(result);
494
495} /* end of Cudd_ApaCompareRatios */
496
497
498/**Function********************************************************************
499
500  Synopsis    [Prints an arbitrary precision integer in hexadecimal format.]
501
502  Description [Prints an arbitrary precision integer in hexadecimal format.
503  Returns 1 if successful; 0 otherwise.]
504
505  SideEffects [None]
506
507  SeeAlso     [Cudd_ApaPrintDecimal Cudd_ApaPrintExponential]
508
509******************************************************************************/
510int
511Cudd_ApaPrintHex(
512  FILE * fp,
513  int  digits,
514  DdApaNumber  number)
515{
516    int i, result;
517
518    for (i = 0; i < digits; i++) {
519        result = fprintf(fp,DD_APA_HEXPRINT,number[i]);
520        if (result == EOF)
521            return(0);
522    }
523    return(1);
524
525} /* end of Cudd_ApaPrintHex */
526
527
528/**Function********************************************************************
529
530  Synopsis    [Prints an arbitrary precision integer in decimal format.]
531
532  Description [Prints an arbitrary precision integer in decimal format.
533  Returns 1 if successful; 0 otherwise.]
534
535  SideEffects [None]
536
537  SeeAlso     [Cudd_ApaPrintHex Cudd_ApaPrintExponential]
538
539******************************************************************************/
540int
541Cudd_ApaPrintDecimal(
542  FILE * fp,
543  int  digits,
544  DdApaNumber  number)
545{
546    int i, result;
547    DdApaDigit remainder;
548    DdApaNumber work;
549    unsigned char *decimal;
550    int leadingzero;
551    int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1;
552   
553    work = Cudd_NewApaNumber(digits);
554    if (work == NULL)
555        return(0);
556    decimal = ALLOC(unsigned char, decimalDigits);
557    if (decimal == NULL) {
558        FREE(work);
559        return(0);
560    }
561    Cudd_ApaCopy(digits,number,work);
562    for (i = decimalDigits - 1; i >= 0; i--) {
563        remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work);
564        decimal[i] = remainder;
565    }
566    FREE(work);
567
568    leadingzero = 1;
569    for (i = 0; i < decimalDigits; i++) {
570        leadingzero = leadingzero && (decimal[i] == 0);
571        if ((!leadingzero) || (i == (decimalDigits - 1))) {
572            result = fprintf(fp,"%1d",decimal[i]);
573            if (result == EOF) {
574                FREE(decimal);
575                return(0);
576            }
577        }
578    }
579    FREE(decimal);
580    return(1);
581
582} /* end of Cudd_ApaPrintDecimal */
583
584
585/**Function********************************************************************
586
587  Synopsis    [Prints an arbitrary precision integer in exponential format.]
588
589  Description [Prints an arbitrary precision integer in exponential format.
590  Returns 1 if successful; 0 otherwise.]
591
592  SideEffects [None]
593
594  SeeAlso     [Cudd_ApaPrintHex Cudd_ApaPrintDecimal]
595
596******************************************************************************/
597int
598Cudd_ApaPrintExponential(
599  FILE * fp,
600  int  digits,
601  DdApaNumber  number,
602  int precision)
603{
604    int i, first, last, result;
605    DdApaDigit remainder;
606    DdApaNumber work;
607    unsigned char *decimal;
608    int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1;
609   
610    work = Cudd_NewApaNumber(digits);
611    if (work == NULL)
612        return(0);
613    decimal = ALLOC(unsigned char, decimalDigits);
614    if (decimal == NULL) {
615        FREE(work);
616        return(0);
617    }
618    Cudd_ApaCopy(digits,number,work);
619    first = decimalDigits - 1;
620    for (i = decimalDigits - 1; i >= 0; i--) {
621        remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work);
622        decimal[i] = remainder;
623        if (remainder != 0) first = i; /* keep track of MS non-zero */
624    }
625    FREE(work);
626    last = ddMin(first + precision, decimalDigits);
627
628    for (i = first; i < last; i++) {
629        result = fprintf(fp,"%s%1d",i == first+1 ? "." : "", decimal[i]);
630        if (result == EOF) {
631            FREE(decimal);
632            return(0);
633        }
634    }
635    FREE(decimal);
636    result = fprintf(fp,"e+%d",decimalDigits - first - 1);
637    if (result == EOF) {
638        return(0);
639    }
640    return(1);
641
642} /* end of Cudd_ApaPrintExponential */
643
644
645/**Function********************************************************************
646
647  Synopsis    [Counts the number of minterms of a DD.]
648
649  Description [Counts the number of minterms of a DD. The function is
650  assumed to depend on nvars variables. The minterm count is
651  represented as an arbitrary precision unsigned integer, to allow for
652  any number of variables CUDD supports.  Returns a pointer to the
653  array representing the number of minterms of the function rooted at
654  node if successful; NULL otherwise.]
655
656  SideEffects [The number of digits of the result is returned in
657  parameter <code>digits</code>.]
658
659  SeeAlso     [Cudd_CountMinterm]
660
661******************************************************************************/
662DdApaNumber
663Cudd_ApaCountMinterm(
664  DdManager * manager,
665  DdNode * node,
666  int  nvars,
667  int * digits)
668{
669    DdApaNumber max, min;
670    st_table    *table;
671    DdApaNumber i,count;       
672
673    background = manager->background;
674    zero = Cudd_Not(manager->one);
675
676    *digits = Cudd_ApaNumberOfDigits(nvars+1);
677    max = Cudd_NewApaNumber(*digits);
678    if (max == NULL) {
679        return(NULL);
680    }
681    Cudd_ApaPowerOfTwo(*digits,max,nvars);
682    min = Cudd_NewApaNumber(*digits);
683    if (min == NULL) {
684        FREE(max);
685        return(NULL);
686    }
687    Cudd_ApaSetToLiteral(*digits,min,0);
688    table = st_init_table(st_ptrcmp,st_ptrhash);
689    if (table == NULL) {
690        FREE(max);
691        FREE(min);
692        return(NULL);
693    }
694    i = cuddApaCountMintermAux(Cudd_Regular(node),*digits,max,min,table);
695    if (i == NULL) {
696        FREE(max);
697        FREE(min);
698        st_foreach(table, cuddApaStCountfree, NULL);
699        st_free_table(table);
700        return(NULL);
701    }
702    count = Cudd_NewApaNumber(*digits);
703    if (count == NULL) {
704        FREE(max);
705        FREE(min);
706        st_foreach(table, cuddApaStCountfree, NULL);
707        st_free_table(table);
708        if (Cudd_Regular(node)->ref == 1) FREE(i);
709        return(NULL);
710    }
711    if (Cudd_IsComplement(node)) {
712        (void) Cudd_ApaSubtract(*digits,max,i,count);
713    } else {
714        Cudd_ApaCopy(*digits,i,count);
715    }
716    FREE(max);
717    FREE(min);
718    st_foreach(table, cuddApaStCountfree, NULL);
719    st_free_table(table);
720    if (Cudd_Regular(node)->ref == 1) FREE(i);
721    return(count);
722
723} /* end of Cudd_ApaCountMinterm */
724
725
726/**Function********************************************************************
727
728  Synopsis    [Prints the number of minterms of a BDD or ADD using
729  arbitrary precision arithmetic.]
730
731  Description [Prints the number of minterms of a BDD or ADD using
732  arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.]
733
734  SideEffects [None]
735
736  SeeAlso     [Cudd_ApaPrintMintermExp]
737
738******************************************************************************/
739int
740Cudd_ApaPrintMinterm(
741  FILE * fp,
742  DdManager * dd,
743  DdNode * node,
744  int  nvars)
745{
746    int digits;
747    int result;
748    DdApaNumber count;
749
750    count = Cudd_ApaCountMinterm(dd,node,nvars,&digits);
751    if (count == NULL)
752        return(0);
753    result = Cudd_ApaPrintDecimal(fp,digits,count);
754    FREE(count);
755    if (fprintf(fp,"\n") == EOF) {
756        return(0);
757    }
758    return(result);
759
760} /* end of Cudd_ApaPrintMinterm */
761
762
763/**Function********************************************************************
764
765  Synopsis    [Prints the number of minterms of a BDD or ADD in exponential
766  format using arbitrary precision arithmetic.]
767
768  Description [Prints the number of minterms of a BDD or ADD in
769  exponential format using arbitrary precision arithmetic. Parameter
770  precision controls the number of signficant digits printed. Returns
771  1 if successful; 0 otherwise.]
772
773  SideEffects [None]
774
775  SeeAlso     [Cudd_ApaPrintMinterm]
776
777******************************************************************************/
778int
779Cudd_ApaPrintMintermExp(
780  FILE * fp,
781  DdManager * dd,
782  DdNode * node,
783  int  nvars,
784  int precision)
785{
786    int digits;
787    int result;
788    DdApaNumber count;
789
790    count = Cudd_ApaCountMinterm(dd,node,nvars,&digits);
791    if (count == NULL)
792        return(0);
793    result = Cudd_ApaPrintExponential(fp,digits,count,precision);
794    FREE(count);
795    if (fprintf(fp,"\n") == EOF) {
796        return(0);
797    }
798    return(result);
799
800} /* end of Cudd_ApaPrintMintermExp */
801
802
803/**Function********************************************************************
804
805  Synopsis    [Prints the density of a BDD or ADD using
806  arbitrary precision arithmetic.]
807
808  Description [Prints the density of a BDD or ADD using
809  arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.]
810
811  SideEffects [None]
812
813  SeeAlso     []
814
815******************************************************************************/
816int
817Cudd_ApaPrintDensity(
818  FILE * fp,
819  DdManager * dd,
820  DdNode * node,
821  int  nvars)
822{
823    int digits;
824    int result;
825    DdApaNumber count,density;
826    unsigned int size, remainder, fractional;
827
828    count = Cudd_ApaCountMinterm(dd,node,nvars,&digits);
829    if (count == NULL)
830        return(0);
831    size = Cudd_DagSize(node);
832    density = Cudd_NewApaNumber(digits);
833    remainder = Cudd_ApaIntDivision(digits,count,size,density);
834    result = Cudd_ApaPrintDecimal(fp,digits,density);
835    FREE(count);
836    FREE(density);
837    fractional = (unsigned int)((double)remainder / size * 1000000);
838    if (fprintf(fp,".%u\n", fractional) == EOF) {
839        return(0);
840    }
841    return(result);
842
843} /* end of Cudd_ApaPrintDensity */
844
845
846/*---------------------------------------------------------------------------*/
847/* Definition of internal functions                                          */
848/*---------------------------------------------------------------------------*/
849
850
851/*---------------------------------------------------------------------------*/
852/* Definition of static functions                                            */
853/*---------------------------------------------------------------------------*/
854
855
856/**Function********************************************************************
857
858  Synopsis    [Performs the recursive step of Cudd_ApaCountMinterm.]
859
860  Description [Performs the recursive step of Cudd_ApaCountMinterm.
861  It is based on the following identity. Let |f| be the
862  number of minterms of f. Then:
863  <xmp>
864    |f| = (|f0|+|f1|)/2
865  </xmp>
866  where f0 and f1 are the two cofactors of f.
867  Uses the identity <code>|f'| = max - |f|</code>.
868  The procedure expects the argument "node" to be a regular pointer, and
869  guarantees this condition is met in the recursive calls.
870  For efficiency, the result of a call is cached only if the node has
871  a reference count greater than 1.
872  Returns the number of minterms of the function rooted at node.]
873
874  SideEffects [None]
875
876******************************************************************************/
877static DdApaNumber
878cuddApaCountMintermAux(
879  DdNode * node,
880  int  digits,
881  DdApaNumber  max,
882  DdApaNumber  min,
883  st_table * table)
884{
885    DdNode      *Nt, *Ne;
886    DdApaNumber mint, mint1, mint2;
887    DdApaDigit  carryout;
888
889    if (cuddIsConstant(node)) {
890        if (node == background || node == zero) {
891            return(min);
892        } else {
893            return(max);
894        }
895    }
896    if (node->ref > 1 && st_lookup(table, node, &mint)) {
897        return(mint);
898    }
899
900    Nt = cuddT(node); Ne = cuddE(node);
901
902    mint1 = cuddApaCountMintermAux(Nt,  digits, max, min, table);
903    if (mint1 == NULL) return(NULL);
904    mint2 = cuddApaCountMintermAux(Cudd_Regular(Ne), digits, max, min, table);
905    if (mint2 == NULL) {
906        if (Nt->ref == 1) FREE(mint1);
907        return(NULL);
908    }
909    mint = Cudd_NewApaNumber(digits);
910    if (mint == NULL) {
911        if (Nt->ref == 1) FREE(mint1);
912        if (Cudd_Regular(Ne)->ref == 1) FREE(mint2);
913        return(NULL);
914    }
915    if (Cudd_IsComplement(Ne)) {
916        (void) Cudd_ApaSubtract(digits,max,mint2,mint);
917        carryout = Cudd_ApaAdd(digits,mint1,mint,mint);
918    } else {
919        carryout = Cudd_ApaAdd(digits,mint1,mint2,mint);
920    }
921    Cudd_ApaShiftRight(digits,carryout,mint,mint);
922    /* If the refernce count of a child is 1, its minterm count
923    ** hasn't been stored in table.  Therefore, it must be explicitly
924    ** freed here. */
925    if (Nt->ref == 1) FREE(mint1);
926    if (Cudd_Regular(Ne)->ref == 1) FREE(mint2);
927   
928    if (node->ref > 1) {
929        if (st_insert(table, (char *)node, (char *)mint) == ST_OUT_OF_MEM) {
930            FREE(mint);
931            return(NULL);
932        }
933    }
934    return(mint);
935
936} /* end of cuddApaCountMintermAux */
937
938
939/**Function********************************************************************
940
941  Synopsis [Frees the memory used to store the minterm counts recorded
942  in the visited table.]
943
944  Description [Frees the memory used to store the minterm counts
945  recorded in the visited table. Returns ST_CONTINUE.]
946
947  SideEffects [None]
948
949******************************************************************************/
950static enum st_retval
951cuddApaStCountfree(
952  char * key,
953  char * value,
954  char * arg)
955{
956    DdApaNumber d;
957
958    d = (DdApaNumber) value;
959    FREE(d);
960    return(ST_CONTINUE);
961
962} /* end of cuddApaStCountfree */
963
964
Note: See TracBrowser for help on using the repository browser.