modify default solver parameters
[cl-cudd.git] / distr / cudd / cuddApa.c
blob6903d071b96ab1945d5be086f4fe590747490fa1
1 /**CFile***********************************************************************
3 FileName [cuddApa.c]
5 PackageName [cudd]
7 Synopsis [Arbitrary precision arithmetic functions.]
9 Description [External procedures included in this module:
10 <ul>
11 <li> Cudd_ApaNumberOfDigits()
12 <li> Cudd_NewApaNumber()
13 <li> Cudd_ApaCopy()
14 <li> Cudd_ApaAdd()
15 <li> Cudd_ApaSubtract()
16 <li> Cudd_ApaShortDivision()
17 <li> Cudd_ApaIntDivision()
18 <li> Cudd_ApaShiftRight()
19 <li> Cudd_ApaSetToLiteral()
20 <li> Cudd_ApaPowerOfTwo()
21 <li> Cudd_ApaCompare()
22 <li> Cudd_ApaCompareRatios()
23 <li> Cudd_ApaPrintHex()
24 <li> Cudd_ApaPrintDecimal()
25 <li> Cudd_ApaPrintExponential()
26 <li> Cudd_ApaCountMinterm()
27 <li> Cudd_ApaPrintMinterm()
28 <li> Cudd_ApaPrintMintermExp()
29 <li> Cudd_ApaPrintDensity()
30 </ul>
31 Static procedures included in this module:
32 <ul>
33 <li> cuddApaCountMintermAux()
34 <li> cuddApaStCountfree()
35 </ul>]
37 Author [Fabio Somenzi]
39 Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
41 All rights reserved.
43 Redistribution and use in source and binary forms, with or without
44 modification, are permitted provided that the following conditions
45 are met:
47 Redistributions of source code must retain the above copyright
48 notice, this list of conditions and the following disclaimer.
50 Redistributions in binary form must reproduce the above copyright
51 notice, this list of conditions and the following disclaimer in the
52 documentation and/or other materials provided with the distribution.
54 Neither the name of the University of Colorado nor the names of its
55 contributors may be used to endorse or promote products derived from
56 this software without specific prior written permission.
58 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
59 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
60 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
61 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
62 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
63 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
64 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
65 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
66 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
68 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
69 POSSIBILITY OF SUCH DAMAGE.]
71 ******************************************************************************/
73 #include "util.h"
74 #include "cuddInt.h"
76 /*---------------------------------------------------------------------------*/
77 /* Constant declarations */
78 /*---------------------------------------------------------------------------*/
80 /*---------------------------------------------------------------------------*/
81 /* Stucture declarations */
82 /*---------------------------------------------------------------------------*/
84 /*---------------------------------------------------------------------------*/
85 /* Type declarations */
86 /*---------------------------------------------------------------------------*/
88 /*---------------------------------------------------------------------------*/
89 /* Variable declarations */
90 /*---------------------------------------------------------------------------*/
92 #ifndef lint
93 static char rcsid[] DD_UNUSED = "$Id: cuddApa.c,v 1.19 2009/03/08 01:27:50 fabio Exp $";
94 #endif
96 static DdNode *background, *zero;
98 /*---------------------------------------------------------------------------*/
99 /* Macro declarations */
100 /*---------------------------------------------------------------------------*/
102 #ifdef __cplusplus
103 extern "C" {
104 #endif
106 /**AutomaticStart*************************************************************/
108 /*---------------------------------------------------------------------------*/
109 /* Static function prototypes */
110 /*---------------------------------------------------------------------------*/
112 static DdApaNumber cuddApaCountMintermAux (DdNode * node, int digits, DdApaNumber max, DdApaNumber min, st_table * table);
113 static enum st_retval cuddApaStCountfree (char * key, char * value, char * arg);
115 /**AutomaticEnd***************************************************************/
117 #ifdef __cplusplus
118 } /* end of extern "C" */
119 #endif
122 /*---------------------------------------------------------------------------*/
123 /* Definition of exported functions */
124 /*---------------------------------------------------------------------------*/
127 /**Function********************************************************************
129 Synopsis [Finds the number of digits for an arbitrary precision
130 integer.]
132 Description [Finds the number of digits for an arbitrary precision
133 integer given the maximum number of binary digits. The number of
134 binary digits should be positive. Returns the number of digits if
135 successful; 0 otherwise.]
137 SideEffects [None]
139 SeeAlso []
141 ******************************************************************************/
143 Cudd_ApaNumberOfDigits(
144 int binaryDigits)
146 int digits;
148 digits = binaryDigits / DD_APA_BITS;
149 if ((digits * DD_APA_BITS) != binaryDigits)
150 digits++;
151 return(digits);
153 } /* end of Cudd_ApaNumberOfDigits */
156 /**Function********************************************************************
158 Synopsis [Allocates memory for an arbitrary precision integer.]
160 Description [Allocates memory for an arbitrary precision
161 integer. Returns a pointer to the allocated memory if successful;
162 NULL otherwise.]
164 SideEffects [None]
166 SeeAlso []
168 ******************************************************************************/
169 DdApaNumber
170 Cudd_NewApaNumber(
171 int digits)
173 return(ALLOC(DdApaDigit, digits));
175 } /* end of Cudd_NewApaNumber */
178 /**Function********************************************************************
180 Synopsis [Makes a copy of an arbitrary precision integer.]
182 Description [Makes a copy of an arbitrary precision integer.]
184 SideEffects [Changes parameter <code>dest</code>.]
186 SeeAlso []
188 ******************************************************************************/
189 void
190 Cudd_ApaCopy(
191 int digits,
192 DdApaNumber source,
193 DdApaNumber dest)
195 int i;
197 for (i = 0; i < digits; i++) {
198 dest[i] = source[i];
201 } /* end of Cudd_ApaCopy */
204 /**Function********************************************************************
206 Synopsis [Adds two arbitrary precision integers.]
208 Description [Adds two arbitrary precision integers. Returns the
209 carry out of the most significant digit.]
211 SideEffects [The result of the sum is stored in parameter <code>sum</code>.]
213 SeeAlso []
215 ******************************************************************************/
216 DdApaDigit
217 Cudd_ApaAdd(
218 int digits,
219 DdApaNumber a,
220 DdApaNumber b,
221 DdApaNumber sum)
223 int i;
224 DdApaDoubleDigit partial = 0;
226 for (i = digits - 1; i >= 0; i--) {
227 partial = a[i] + b[i] + DD_MSDIGIT(partial);
228 sum[i] = (DdApaDigit) DD_LSDIGIT(partial);
230 return((DdApaDigit) DD_MSDIGIT(partial));
232 } /* end of Cudd_ApaAdd */
235 /**Function********************************************************************
237 Synopsis [Subtracts two arbitrary precision integers.]
239 Description [Subtracts two arbitrary precision integers. Returns the
240 borrow out of the most significant digit.]
242 SideEffects [The result of the subtraction is stored in parameter
243 <code>diff</code>.]
245 SeeAlso []
247 ******************************************************************************/
248 DdApaDigit
249 Cudd_ApaSubtract(
250 int digits,
251 DdApaNumber a,
252 DdApaNumber b,
253 DdApaNumber diff)
255 int i;
256 DdApaDoubleDigit partial = DD_APA_BASE;
258 for (i = digits - 1; i >= 0; i--) {
259 partial = DD_MSDIGIT(partial) + DD_APA_MASK + a[i] - b[i];
260 diff[i] = (DdApaDigit) DD_LSDIGIT(partial);
262 return((DdApaDigit) DD_MSDIGIT(partial) - 1);
264 } /* end of Cudd_ApaSubtract */
267 /**Function********************************************************************
269 Synopsis [Divides an arbitrary precision integer by a digit.]
271 Description [Divides an arbitrary precision integer by a digit.]
273 SideEffects [The quotient is returned in parameter <code>quotient</code>.]
275 SeeAlso []
277 ******************************************************************************/
278 DdApaDigit
279 Cudd_ApaShortDivision(
280 int digits,
281 DdApaNumber dividend,
282 DdApaDigit divisor,
283 DdApaNumber quotient)
285 int i;
286 DdApaDigit remainder;
287 DdApaDoubleDigit partial;
289 remainder = 0;
290 for (i = 0; i < digits; i++) {
291 partial = remainder * DD_APA_BASE + dividend[i];
292 quotient[i] = (DdApaDigit) (partial/(DdApaDoubleDigit)divisor);
293 remainder = (DdApaDigit) (partial % divisor);
296 return(remainder);
298 } /* end of Cudd_ApaShortDivision */
301 /**Function********************************************************************
303 Synopsis [Divides an arbitrary precision integer by an integer.]
305 Description [Divides an arbitrary precision integer by a 32-bit
306 unsigned integer. Returns the remainder of the division. This
307 procedure relies on the assumption that the number of bits of a
308 DdApaDigit plus the number of bits of an unsigned int is less the
309 number of bits of the mantissa of a double. This guarantees that the
310 product of a DdApaDigit and an unsigned int can be represented
311 without loss of precision by a double. On machines where this
312 assumption is not satisfied, this procedure will malfunction.]
314 SideEffects [The quotient is returned in parameter <code>quotient</code>.]
316 SeeAlso [Cudd_ApaShortDivision]
318 ******************************************************************************/
319 unsigned int
320 Cudd_ApaIntDivision(
321 int digits,
322 DdApaNumber dividend,
323 unsigned int divisor,
324 DdApaNumber quotient)
326 int i;
327 double partial;
328 unsigned int remainder = 0;
329 double ddiv = (double) divisor;
331 for (i = 0; i < digits; i++) {
332 partial = (double) remainder * DD_APA_BASE + dividend[i];
333 quotient[i] = (DdApaDigit) (partial / ddiv);
334 remainder = (unsigned int) (partial - ((double)quotient[i] * ddiv));
337 return(remainder);
339 } /* end of Cudd_ApaIntDivision */
342 /**Function********************************************************************
344 Synopsis [Shifts right an arbitrary precision integer by one binary
345 place.]
347 Description [Shifts right an arbitrary precision integer by one
348 binary place. The most significant binary digit of the result is
349 taken from parameter <code>in</code>.]
351 SideEffects [The result is returned in parameter <code>b</code>.]
353 SeeAlso []
355 ******************************************************************************/
356 void
357 Cudd_ApaShiftRight(
358 int digits,
359 DdApaDigit in,
360 DdApaNumber a,
361 DdApaNumber b)
363 int i;
365 for (i = digits - 1; i > 0; i--) {
366 b[i] = (a[i] >> 1) | ((a[i-1] & 1) << (DD_APA_BITS - 1));
368 b[0] = (a[0] >> 1) | (in << (DD_APA_BITS - 1));
370 } /* end of Cudd_ApaShiftRight */
373 /**Function********************************************************************
375 Synopsis [Sets an arbitrary precision integer to a one-digit literal.]
377 Description [Sets an arbitrary precision integer to a one-digit literal.]
379 SideEffects [The result is returned in parameter <code>number</code>.]
381 SeeAlso []
383 ******************************************************************************/
384 void
385 Cudd_ApaSetToLiteral(
386 int digits,
387 DdApaNumber number,
388 DdApaDigit literal)
390 int i;
392 for (i = 0; i < digits - 1; i++)
393 number[i] = 0;
394 number[digits - 1] = literal;
396 } /* end of Cudd_ApaSetToLiteral */
399 /**Function********************************************************************
401 Synopsis [Sets an arbitrary precision integer to a power of two.]
403 Description [Sets an arbitrary precision integer to a power of
404 two. If the power of two is too large to be represented, the number
405 is set to 0.]
407 SideEffects [The result is returned in parameter <code>number</code>.]
409 SeeAlso []
411 ******************************************************************************/
412 void
413 Cudd_ApaPowerOfTwo(
414 int digits,
415 DdApaNumber number,
416 int power)
418 int i;
419 int index;
421 for (i = 0; i < digits; i++)
422 number[i] = 0;
423 i = digits - 1 - power / DD_APA_BITS;
424 if (i < 0) return;
425 index = power & (DD_APA_BITS - 1);
426 number[i] = 1 << index;
428 } /* end of Cudd_ApaPowerOfTwo */
431 /**Function********************************************************************
433 Synopsis [Compares two arbitrary precision integers.]
435 Description [Compares two arbitrary precision integers. Returns 1 if
436 the first number is larger; 0 if they are equal; -1 if the second
437 number is larger.]
439 SideEffects [None]
441 SeeAlso []
443 ******************************************************************************/
445 Cudd_ApaCompare(
446 int digitsFirst,
447 DdApaNumber first,
448 int digitsSecond,
449 DdApaNumber second)
451 int i;
452 int firstNZ, secondNZ;
454 /* Find first non-zero in both numbers. */
455 for (firstNZ = 0; firstNZ < digitsFirst; firstNZ++)
456 if (first[firstNZ] != 0) break;
457 for (secondNZ = 0; secondNZ < digitsSecond; secondNZ++)
458 if (second[secondNZ] != 0) break;
459 if (digitsFirst - firstNZ > digitsSecond - secondNZ) return(1);
460 else if (digitsFirst - firstNZ < digitsSecond - secondNZ) return(-1);
461 for (i = 0; i < digitsFirst - firstNZ; i++) {
462 if (first[firstNZ + i] > second[secondNZ + i]) return(1);
463 else if (first[firstNZ + i] < second[secondNZ + i]) return(-1);
465 return(0);
467 } /* end of Cudd_ApaCompare */
470 /**Function********************************************************************
472 Synopsis [Compares the ratios of two arbitrary precision integers to two
473 unsigned ints.]
475 Description [Compares the ratios of two arbitrary precision integers
476 to two unsigned ints. Returns 1 if the first number is larger; 0 if
477 they are equal; -1 if the second number is larger.]
479 SideEffects [None]
481 SeeAlso []
483 ******************************************************************************/
485 Cudd_ApaCompareRatios(
486 int digitsFirst,
487 DdApaNumber firstNum,
488 unsigned int firstDen,
489 int digitsSecond,
490 DdApaNumber secondNum,
491 unsigned int secondDen)
493 int result;
494 DdApaNumber first, second;
495 unsigned int firstRem, secondRem;
497 first = Cudd_NewApaNumber(digitsFirst);
498 firstRem = Cudd_ApaIntDivision(digitsFirst,firstNum,firstDen,first);
499 second = Cudd_NewApaNumber(digitsSecond);
500 secondRem = Cudd_ApaIntDivision(digitsSecond,secondNum,secondDen,second);
501 result = Cudd_ApaCompare(digitsFirst,first,digitsSecond,second);
502 FREE(first);
503 FREE(second);
504 if (result == 0) {
505 if ((double)firstRem/firstDen > (double)secondRem/secondDen)
506 return(1);
507 else if ((double)firstRem/firstDen < (double)secondRem/secondDen)
508 return(-1);
510 return(result);
512 } /* end of Cudd_ApaCompareRatios */
515 /**Function********************************************************************
517 Synopsis [Prints an arbitrary precision integer in hexadecimal format.]
519 Description [Prints an arbitrary precision integer in hexadecimal format.
520 Returns 1 if successful; 0 otherwise.]
522 SideEffects [None]
524 SeeAlso [Cudd_ApaPrintDecimal Cudd_ApaPrintExponential]
526 ******************************************************************************/
528 Cudd_ApaPrintHex(
529 FILE * fp,
530 int digits,
531 DdApaNumber number)
533 int i, result;
535 for (i = 0; i < digits; i++) {
536 result = fprintf(fp,DD_APA_HEXPRINT,number[i]);
537 if (result == EOF)
538 return(0);
540 return(1);
542 } /* end of Cudd_ApaPrintHex */
545 /**Function********************************************************************
547 Synopsis [Prints an arbitrary precision integer in decimal format.]
549 Description [Prints an arbitrary precision integer in decimal format.
550 Returns 1 if successful; 0 otherwise.]
552 SideEffects [None]
554 SeeAlso [Cudd_ApaPrintHex Cudd_ApaPrintExponential]
556 ******************************************************************************/
558 Cudd_ApaPrintDecimal(
559 FILE * fp,
560 int digits,
561 DdApaNumber number)
563 int i, result;
564 DdApaDigit remainder;
565 DdApaNumber work;
566 unsigned char *decimal;
567 int leadingzero;
568 int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1;
570 work = Cudd_NewApaNumber(digits);
571 if (work == NULL)
572 return(0);
573 decimal = ALLOC(unsigned char, decimalDigits);
574 if (decimal == NULL) {
575 FREE(work);
576 return(0);
578 Cudd_ApaCopy(digits,number,work);
579 for (i = decimalDigits - 1; i >= 0; i--) {
580 remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work);
581 decimal[i] = (unsigned char) remainder;
583 FREE(work);
585 leadingzero = 1;
586 for (i = 0; i < decimalDigits; i++) {
587 leadingzero = leadingzero && (decimal[i] == 0);
588 if ((!leadingzero) || (i == (decimalDigits - 1))) {
589 result = fprintf(fp,"%1d",decimal[i]);
590 if (result == EOF) {
591 FREE(decimal);
592 return(0);
596 FREE(decimal);
597 return(1);
599 } /* end of Cudd_ApaPrintDecimal */
602 /**Function********************************************************************
604 Synopsis [Prints an arbitrary precision integer in exponential format.]
606 Description [Prints an arbitrary precision integer in exponential format.
607 Returns 1 if successful; 0 otherwise.]
609 SideEffects [None]
611 SeeAlso [Cudd_ApaPrintHex Cudd_ApaPrintDecimal]
613 ******************************************************************************/
615 Cudd_ApaPrintExponential(
616 FILE * fp,
617 int digits,
618 DdApaNumber number,
619 int precision)
621 int i, first, last, result;
622 DdApaDigit remainder;
623 DdApaNumber work;
624 unsigned char *decimal;
625 int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1;
627 work = Cudd_NewApaNumber(digits);
628 if (work == NULL)
629 return(0);
630 decimal = ALLOC(unsigned char, decimalDigits);
631 if (decimal == NULL) {
632 FREE(work);
633 return(0);
635 Cudd_ApaCopy(digits,number,work);
636 first = decimalDigits - 1;
637 for (i = decimalDigits - 1; i >= 0; i--) {
638 remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work);
639 decimal[i] = (unsigned char) remainder;
640 if (remainder != 0) first = i; /* keep track of MS non-zero */
642 FREE(work);
643 last = ddMin(first + precision, decimalDigits);
645 for (i = first; i < last; i++) {
646 result = fprintf(fp,"%s%1d",i == first+1 ? "." : "", decimal[i]);
647 if (result == EOF) {
648 FREE(decimal);
649 return(0);
652 FREE(decimal);
653 result = fprintf(fp,"e+%d",decimalDigits - first - 1);
654 if (result == EOF) {
655 return(0);
657 return(1);
659 } /* end of Cudd_ApaPrintExponential */
662 /**Function********************************************************************
664 Synopsis [Counts the number of minterms of a DD.]
666 Description [Counts the number of minterms of a DD. The function is
667 assumed to depend on nvars variables. The minterm count is
668 represented as an arbitrary precision unsigned integer, to allow for
669 any number of variables CUDD supports. Returns a pointer to the
670 array representing the number of minterms of the function rooted at
671 node if successful; NULL otherwise.]
673 SideEffects [The number of digits of the result is returned in
674 parameter <code>digits</code>.]
676 SeeAlso [Cudd_CountMinterm]
678 ******************************************************************************/
679 DdApaNumber
680 Cudd_ApaCountMinterm(
681 DdManager * manager,
682 DdNode * node,
683 int nvars,
684 int * digits)
686 DdApaNumber max, min;
687 st_table *table;
688 DdApaNumber i,count;
690 background = manager->background;
691 zero = Cudd_Not(manager->one);
693 *digits = Cudd_ApaNumberOfDigits(nvars+1);
694 max = Cudd_NewApaNumber(*digits);
695 if (max == NULL) {
696 return(NULL);
698 Cudd_ApaPowerOfTwo(*digits,max,nvars);
699 min = Cudd_NewApaNumber(*digits);
700 if (min == NULL) {
701 FREE(max);
702 return(NULL);
704 Cudd_ApaSetToLiteral(*digits,min,0);
705 table = st_init_table(st_ptrcmp,st_ptrhash);
706 if (table == NULL) {
707 FREE(max);
708 FREE(min);
709 return(NULL);
711 i = cuddApaCountMintermAux(Cudd_Regular(node),*digits,max,min,table);
712 if (i == NULL) {
713 FREE(max);
714 FREE(min);
715 st_foreach(table, cuddApaStCountfree, NULL);
716 st_free_table(table);
717 return(NULL);
719 count = Cudd_NewApaNumber(*digits);
720 if (count == NULL) {
721 FREE(max);
722 FREE(min);
723 st_foreach(table, cuddApaStCountfree, NULL);
724 st_free_table(table);
725 if (Cudd_Regular(node)->ref == 1) FREE(i);
726 return(NULL);
728 if (Cudd_IsComplement(node)) {
729 (void) Cudd_ApaSubtract(*digits,max,i,count);
730 } else {
731 Cudd_ApaCopy(*digits,i,count);
733 FREE(max);
734 FREE(min);
735 st_foreach(table, cuddApaStCountfree, NULL);
736 st_free_table(table);
737 if (Cudd_Regular(node)->ref == 1) FREE(i);
738 return(count);
740 } /* end of Cudd_ApaCountMinterm */
743 /**Function********************************************************************
745 Synopsis [Prints the number of minterms of a BDD or ADD using
746 arbitrary precision arithmetic.]
748 Description [Prints the number of minterms of a BDD or ADD using
749 arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.]
751 SideEffects [None]
753 SeeAlso [Cudd_ApaPrintMintermExp]
755 ******************************************************************************/
757 Cudd_ApaPrintMinterm(
758 FILE * fp,
759 DdManager * dd,
760 DdNode * node,
761 int nvars)
763 int digits;
764 int result;
765 DdApaNumber count;
767 count = Cudd_ApaCountMinterm(dd,node,nvars,&digits);
768 if (count == NULL)
769 return(0);
770 result = Cudd_ApaPrintDecimal(fp,digits,count);
771 FREE(count);
772 if (fprintf(fp,"\n") == EOF) {
773 return(0);
775 return(result);
777 } /* end of Cudd_ApaPrintMinterm */
780 /**Function********************************************************************
782 Synopsis [Prints the number of minterms of a BDD or ADD in exponential
783 format using arbitrary precision arithmetic.]
785 Description [Prints the number of minterms of a BDD or ADD in
786 exponential format using arbitrary precision arithmetic. Parameter
787 precision controls the number of signficant digits printed. Returns
788 1 if successful; 0 otherwise.]
790 SideEffects [None]
792 SeeAlso [Cudd_ApaPrintMinterm]
794 ******************************************************************************/
796 Cudd_ApaPrintMintermExp(
797 FILE * fp,
798 DdManager * dd,
799 DdNode * node,
800 int nvars,
801 int precision)
803 int digits;
804 int result;
805 DdApaNumber count;
807 count = Cudd_ApaCountMinterm(dd,node,nvars,&digits);
808 if (count == NULL)
809 return(0);
810 result = Cudd_ApaPrintExponential(fp,digits,count,precision);
811 FREE(count);
812 if (fprintf(fp,"\n") == EOF) {
813 return(0);
815 return(result);
817 } /* end of Cudd_ApaPrintMintermExp */
820 /**Function********************************************************************
822 Synopsis [Prints the density of a BDD or ADD using
823 arbitrary precision arithmetic.]
825 Description [Prints the density of a BDD or ADD using
826 arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.]
828 SideEffects [None]
830 SeeAlso []
832 ******************************************************************************/
834 Cudd_ApaPrintDensity(
835 FILE * fp,
836 DdManager * dd,
837 DdNode * node,
838 int nvars)
840 int digits;
841 int result;
842 DdApaNumber count,density;
843 unsigned int size, remainder, fractional;
845 count = Cudd_ApaCountMinterm(dd,node,nvars,&digits);
846 if (count == NULL)
847 return(0);
848 size = Cudd_DagSize(node);
849 density = Cudd_NewApaNumber(digits);
850 remainder = Cudd_ApaIntDivision(digits,count,size,density);
851 result = Cudd_ApaPrintDecimal(fp,digits,density);
852 FREE(count);
853 FREE(density);
854 fractional = (unsigned int)((double)remainder / size * 1000000);
855 if (fprintf(fp,".%u\n", fractional) == EOF) {
856 return(0);
858 return(result);
860 } /* end of Cudd_ApaPrintDensity */
863 /*---------------------------------------------------------------------------*/
864 /* Definition of internal functions */
865 /*---------------------------------------------------------------------------*/
868 /*---------------------------------------------------------------------------*/
869 /* Definition of static functions */
870 /*---------------------------------------------------------------------------*/
873 /**Function********************************************************************
875 Synopsis [Performs the recursive step of Cudd_ApaCountMinterm.]
877 Description [Performs the recursive step of Cudd_ApaCountMinterm.
878 It is based on the following identity. Let |f| be the
879 number of minterms of f. Then:
880 <xmp>
881 |f| = (|f0|+|f1|)/2
882 </xmp>
883 where f0 and f1 are the two cofactors of f.
884 Uses the identity <code>|f'| = max - |f|</code>.
885 The procedure expects the argument "node" to be a regular pointer, and
886 guarantees this condition is met in the recursive calls.
887 For efficiency, the result of a call is cached only if the node has
888 a reference count greater than 1.
889 Returns the number of minterms of the function rooted at node.]
891 SideEffects [None]
893 ******************************************************************************/
894 static DdApaNumber
895 cuddApaCountMintermAux(
896 DdNode * node,
897 int digits,
898 DdApaNumber max,
899 DdApaNumber min,
900 st_table * table)
902 DdNode *Nt, *Ne;
903 DdApaNumber mint, mint1, mint2;
904 DdApaDigit carryout;
906 if (cuddIsConstant(node)) {
907 if (node == background || node == zero) {
908 return(min);
909 } else {
910 return(max);
913 if (node->ref > 1 && st_lookup(table, node, &mint)) {
914 return(mint);
917 Nt = cuddT(node); Ne = cuddE(node);
919 mint1 = cuddApaCountMintermAux(Nt, digits, max, min, table);
920 if (mint1 == NULL) return(NULL);
921 mint2 = cuddApaCountMintermAux(Cudd_Regular(Ne), digits, max, min, table);
922 if (mint2 == NULL) {
923 if (Nt->ref == 1) FREE(mint1);
924 return(NULL);
926 mint = Cudd_NewApaNumber(digits);
927 if (mint == NULL) {
928 if (Nt->ref == 1) FREE(mint1);
929 if (Cudd_Regular(Ne)->ref == 1) FREE(mint2);
930 return(NULL);
932 if (Cudd_IsComplement(Ne)) {
933 (void) Cudd_ApaSubtract(digits,max,mint2,mint);
934 carryout = Cudd_ApaAdd(digits,mint1,mint,mint);
935 } else {
936 carryout = Cudd_ApaAdd(digits,mint1,mint2,mint);
938 Cudd_ApaShiftRight(digits,carryout,mint,mint);
939 /* If the refernce count of a child is 1, its minterm count
940 ** hasn't been stored in table. Therefore, it must be explicitly
941 ** freed here. */
942 if (Nt->ref == 1) FREE(mint1);
943 if (Cudd_Regular(Ne)->ref == 1) FREE(mint2);
945 if (node->ref > 1) {
946 if (st_insert(table, (char *)node, (char *)mint) == ST_OUT_OF_MEM) {
947 FREE(mint);
948 return(NULL);
951 return(mint);
953 } /* end of cuddApaCountMintermAux */
956 /**Function********************************************************************
958 Synopsis [Frees the memory used to store the minterm counts recorded
959 in the visited table.]
961 Description [Frees the memory used to store the minterm counts
962 recorded in the visited table. Returns ST_CONTINUE.]
964 SideEffects [None]
966 ******************************************************************************/
967 static enum st_retval
968 cuddApaStCountfree(
969 char * key,
970 char * value,
971 char * arg)
973 DdApaNumber d;
975 d = (DdApaNumber) value;
976 FREE(d);
977 return(ST_CONTINUE);
979 } /* end of cuddApaStCountfree */