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 |
---|
78 | static char rcsid[] DD_UNUSED = "$Id: cuddApa.c,v 1.16 2004/08/13 18:04:46 fabio Exp $"; |
---|
79 | #endif |
---|
80 | |
---|
81 | static DdNode *background, *zero; |
---|
82 | |
---|
83 | /*---------------------------------------------------------------------------*/ |
---|
84 | /* Macro declarations */ |
---|
85 | /*---------------------------------------------------------------------------*/ |
---|
86 | |
---|
87 | #ifdef __cplusplus |
---|
88 | extern "C" { |
---|
89 | #endif |
---|
90 | |
---|
91 | /**AutomaticStart*************************************************************/ |
---|
92 | |
---|
93 | /*---------------------------------------------------------------------------*/ |
---|
94 | /* Static function prototypes */ |
---|
95 | /*---------------------------------------------------------------------------*/ |
---|
96 | |
---|
97 | static DdApaNumber cuddApaCountMintermAux (DdNode * node, int digits, DdApaNumber max, DdApaNumber min, st_table * table); |
---|
98 | static 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 | ******************************************************************************/ |
---|
127 | int |
---|
128 | Cudd_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 | ******************************************************************************/ |
---|
154 | DdApaNumber |
---|
155 | Cudd_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 | ******************************************************************************/ |
---|
174 | void |
---|
175 | Cudd_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 | ******************************************************************************/ |
---|
201 | DdApaDigit |
---|
202 | Cudd_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 | ******************************************************************************/ |
---|
233 | DdApaDigit |
---|
234 | Cudd_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 | ******************************************************************************/ |
---|
263 | DdApaDigit |
---|
264 | Cudd_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 | ******************************************************************************/ |
---|
304 | unsigned int |
---|
305 | Cudd_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 | ******************************************************************************/ |
---|
341 | void |
---|
342 | Cudd_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 | ******************************************************************************/ |
---|
369 | void |
---|
370 | Cudd_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 | ******************************************************************************/ |
---|
397 | void |
---|
398 | Cudd_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 | ******************************************************************************/ |
---|
429 | int |
---|
430 | Cudd_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 | ******************************************************************************/ |
---|
469 | int |
---|
470 | Cudd_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 | ******************************************************************************/ |
---|
510 | int |
---|
511 | Cudd_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 | ******************************************************************************/ |
---|
540 | int |
---|
541 | Cudd_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 | ******************************************************************************/ |
---|
597 | int |
---|
598 | Cudd_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 | ******************************************************************************/ |
---|
662 | DdApaNumber |
---|
663 | Cudd_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 | ******************************************************************************/ |
---|
739 | int |
---|
740 | Cudd_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 | ******************************************************************************/ |
---|
778 | int |
---|
779 | Cudd_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 | ******************************************************************************/ |
---|
816 | int |
---|
817 | Cudd_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 | ******************************************************************************/ |
---|
877 | static DdApaNumber |
---|
878 | cuddApaCountMintermAux( |
---|
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 | ******************************************************************************/ |
---|
950 | static enum st_retval |
---|
951 | cuddApaStCountfree( |
---|
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 | |
---|