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