abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddAddApply.c
Go to the documentation of this file.
1 /**CFile***********************************************************************
2 
3  FileName [cuddAddApply.c]
4 
5  PackageName [cudd]
6 
7  Synopsis [Apply functions for ADDs and their operators.]
8 
9  Description [External procedures included in this module:
10  <ul>
11  <li> Cudd_addApply()
12  <li> Cudd_addMonadicApply()
13  <li> Cudd_addPlus()
14  <li> Cudd_addTimes()
15  <li> Cudd_addThreshold()
16  <li> Cudd_addSetNZ()
17  <li> Cudd_addDivide()
18  <li> Cudd_addMinus()
19  <li> Cudd_addMinimum()
20  <li> Cudd_addMaximum()
21  <li> Cudd_addOneZeroMaximum()
22  <li> Cudd_addDiff()
23  <li> Cudd_addAgreement()
24  <li> Cudd_addOr()
25  <li> Cudd_addNand()
26  <li> Cudd_addNor()
27  <li> Cudd_addXor()
28  <li> Cudd_addXnor()
29  </ul>
30  Internal procedures included in this module:
31  <ul>
32  <li> cuddAddApplyRecur()
33  <li> cuddAddMonadicApplyRecur()
34  </ul>]
35 
36  Author [Fabio Somenzi]
37 
38  Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
39 
40  All rights reserved.
41 
42  Redistribution and use in source and binary forms, with or without
43  modification, are permitted provided that the following conditions
44  are met:
45 
46  Redistributions of source code must retain the above copyright
47  notice, this list of conditions and the following disclaimer.
48 
49  Redistributions in binary form must reproduce the above copyright
50  notice, this list of conditions and the following disclaimer in the
51  documentation and/or other materials provided with the distribution.
52 
53  Neither the name of the University of Colorado nor the names of its
54  contributors may be used to endorse or promote products derived from
55  this software without specific prior written permission.
56 
57  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
58  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
59  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
60  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
61  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
62  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
63  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
65  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
67  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
68  POSSIBILITY OF SUCH DAMAGE.]
69 
70 ******************************************************************************/
71 
72 #include "misc/util/util_hack.h"
73 #include "cuddInt.h"
74 
76 
77 
78 
79 /*---------------------------------------------------------------------------*/
80 /* Constant declarations */
81 /*---------------------------------------------------------------------------*/
82 
83 
84 /*---------------------------------------------------------------------------*/
85 /* Stucture declarations */
86 /*---------------------------------------------------------------------------*/
87 
88 
89 /*---------------------------------------------------------------------------*/
90 /* Type declarations */
91 /*---------------------------------------------------------------------------*/
92 
93 
94 /*---------------------------------------------------------------------------*/
95 /* Variable declarations */
96 /*---------------------------------------------------------------------------*/
97 
98 #ifndef lint
99 static char rcsid[] DD_UNUSED = "$Id: cuddAddApply.c,v 1.18 2009/02/19 16:15:26 fabio Exp $";
100 #endif
101 
102 
103 /*---------------------------------------------------------------------------*/
104 /* Macro declarations */
105 /*---------------------------------------------------------------------------*/
106 
107 
108 /**AutomaticStart*************************************************************/
109 
110 /*---------------------------------------------------------------------------*/
111 /* Static function prototypes */
112 /*---------------------------------------------------------------------------*/
113 
114 
115 /**AutomaticEnd***************************************************************/
116 
117 
118 /*---------------------------------------------------------------------------*/
119 /* Definition of exported functions */
120 /*---------------------------------------------------------------------------*/
121 
122 /**Function********************************************************************
123 
124  Synopsis [Applies op to the corresponding discriminants of f and g.]
125 
126  Description [Applies op to the corresponding discriminants of f and g.
127  Returns a pointer to the result if succssful; NULL otherwise.]
128 
129  SideEffects [None]
130 
131  SeeAlso [Cudd_addMonadicApply Cudd_addPlus Cudd_addTimes
132  Cudd_addThreshold Cudd_addSetNZ Cudd_addDivide Cudd_addMinus Cudd_addMinimum
133  Cudd_addMaximum Cudd_addOneZeroMaximum Cudd_addDiff Cudd_addAgreement
134  Cudd_addOr Cudd_addNand Cudd_addNor Cudd_addXor Cudd_addXnor]
135 
136 ******************************************************************************/
137 DdNode *
139  DdManager * dd,
140  DD_AOP op,
141  DdNode * f,
142  DdNode * g)
143 {
144  DdNode *res;
145 
146  do {
147  dd->reordered = 0;
148  res = cuddAddApplyRecur(dd,op,f,g);
149  } while (dd->reordered == 1);
150  return(res);
151 
152 } /* end of Cudd_addApply */
153 
154 
155 /**Function********************************************************************
156 
157  Synopsis [Integer and floating point addition.]
158 
159  Description [Integer and floating point addition. Returns NULL if not
160  a terminal case; f+g otherwise.]
161 
162  SideEffects [None]
163 
164  SeeAlso [Cudd_addApply]
165 
166 ******************************************************************************/
167 DdNode *
169  DdManager * dd,
170  DdNode ** f,
171  DdNode ** g)
172 {
173  DdNode *res;
174  DdNode *F, *G;
176 
177  F = *f; G = *g;
178  if (F == DD_ZERO(dd)) return(G);
179  if (G == DD_ZERO(dd)) return(F);
180  if (cuddIsConstant(F) && cuddIsConstant(G)) {
181  value = cuddV(F)+cuddV(G);
182  res = cuddUniqueConst(dd,value);
183  return(res);
184  }
185  if (F > G) { /* swap f and g */
186  *f = G;
187  *g = F;
188  }
189  return(NULL);
190 
191 } /* end of Cudd_addPlus */
192 
193 
194 /**Function********************************************************************
195 
196  Synopsis [Integer and floating point multiplication.]
197 
198  Description [Integer and floating point multiplication. Returns NULL
199  if not a terminal case; f * g otherwise. This function can be used also
200  to take the AND of two 0-1 ADDs.]
201 
202  SideEffects [None]
203 
204  SeeAlso [Cudd_addApply]
205 
206 ******************************************************************************/
207 DdNode *
209  DdManager * dd,
210  DdNode ** f,
211  DdNode ** g)
212 {
213  DdNode *res;
214  DdNode *F, *G;
216 
217  F = *f; G = *g;
218  if (F == DD_ZERO(dd) || G == DD_ZERO(dd)) return(DD_ZERO(dd));
219  if (F == DD_ONE(dd)) return(G);
220  if (G == DD_ONE(dd)) return(F);
221  if (cuddIsConstant(F) && cuddIsConstant(G)) {
222  value = cuddV(F)*cuddV(G);
223  res = cuddUniqueConst(dd,value);
224  return(res);
225  }
226  if (F > G) { /* swap f and g */
227  *f = G;
228  *g = F;
229  }
230  return(NULL);
231 
232 } /* end of Cudd_addTimes */
233 
234 
235 /**Function********************************************************************
236 
237  Synopsis [f if f&gt;=g; 0 if f&lt;g.]
238 
239  Description [Threshold operator for Apply (f if f &gt;=g; 0 if f&lt;g).
240  Returns NULL if not a terminal case; f op g otherwise.]
241 
242  SideEffects [None]
243 
244  SeeAlso [Cudd_addApply]
245 
246 ******************************************************************************/
247 DdNode *
249  DdManager * dd,
250  DdNode ** f,
251  DdNode ** g)
252 {
253  DdNode *F, *G;
254 
255  F = *f; G = *g;
256  if (F == G || F == DD_PLUS_INFINITY(dd)) return(F);
257  if (cuddIsConstant(F) && cuddIsConstant(G)) {
258  if (cuddV(F) >= cuddV(G)) {
259  return(F);
260  } else {
261  return(DD_ZERO(dd));
262  }
263  }
264  return(NULL);
265 
266 } /* end of Cudd_addThreshold */
267 
268 
269 /**Function********************************************************************
270 
271  Synopsis [This operator sets f to the value of g wherever g != 0.]
272 
273  Description [This operator sets f to the value of g wherever g != 0.
274  Returns NULL if not a terminal case; f op g otherwise.]
275 
276  SideEffects [None]
277 
278  SeeAlso [Cudd_addApply]
279 
280 ******************************************************************************/
281 DdNode *
283  DdManager * dd,
284  DdNode ** f,
285  DdNode ** g)
286 {
287  DdNode *F, *G;
288 
289  F = *f; G = *g;
290  if (F == G) return(F);
291  if (F == DD_ZERO(dd)) return(G);
292  if (G == DD_ZERO(dd)) return(F);
293  if (cuddIsConstant(G)) return(G);
294  return(NULL);
295 
296 } /* end of Cudd_addSetNZ */
297 
298 
299 /**Function********************************************************************
300 
301  Synopsis [Integer and floating point division.]
302 
303  Description [Integer and floating point division. Returns NULL if not
304  a terminal case; f / g otherwise.]
305 
306  SideEffects [None]
307 
308  SeeAlso [Cudd_addApply]
309 
310 ******************************************************************************/
311 DdNode *
313  DdManager * dd,
314  DdNode ** f,
315  DdNode ** g)
316 {
317  DdNode *res;
318  DdNode *F, *G;
320 
321  F = *f; G = *g;
322  /* We would like to use F == G -> F/G == 1, but F and G may
323  ** contain zeroes. */
324  if (F == DD_ZERO(dd)) return(DD_ZERO(dd));
325  if (G == DD_ONE(dd)) return(F);
326  if (cuddIsConstant(F) && cuddIsConstant(G)) {
327  value = cuddV(F)/cuddV(G);
328  res = cuddUniqueConst(dd,value);
329  return(res);
330  }
331  return(NULL);
332 
333 } /* end of Cudd_addDivide */
334 
335 
336 /**Function********************************************************************
337 
338  Synopsis [Integer and floating point subtraction.]
339 
340  Description [Integer and floating point subtraction. Returns NULL if
341  not a terminal case; f - g otherwise.]
342 
343  SideEffects [None]
344 
345  SeeAlso [Cudd_addApply]
346 
347 ******************************************************************************/
348 DdNode *
350  DdManager * dd,
351  DdNode ** f,
352  DdNode ** g)
353 {
354  DdNode *res;
355  DdNode *F, *G;
357 
358  F = *f; G = *g;
359  if (F == G) return(DD_ZERO(dd));
360  if (F == DD_ZERO(dd)) return(cuddAddNegateRecur(dd,G));
361  if (G == DD_ZERO(dd)) return(F);
362  if (cuddIsConstant(F) && cuddIsConstant(G)) {
363  value = cuddV(F)-cuddV(G);
364  res = cuddUniqueConst(dd,value);
365  return(res);
366  }
367  return(NULL);
368 
369 } /* end of Cudd_addMinus */
370 
371 
372 /**Function********************************************************************
373 
374  Synopsis [Integer and floating point min.]
375 
376  Description [Integer and floating point min for Cudd_addApply.
377  Returns NULL if not a terminal case; min(f,g) otherwise.]
378 
379  SideEffects [None]
380 
381  SeeAlso [Cudd_addApply]
382 
383 ******************************************************************************/
384 DdNode *
386  DdManager * dd,
387  DdNode ** f,
388  DdNode ** g)
389 {
390  DdNode *F, *G;
391 
392  F = *f; G = *g;
393  if (F == DD_PLUS_INFINITY(dd)) return(G);
394  if (G == DD_PLUS_INFINITY(dd)) return(F);
395  if (F == G) return(F);
396 #if 0
397  /* These special cases probably do not pay off. */
398  if (F == DD_MINUS_INFINITY(dd)) return(F);
399  if (G == DD_MINUS_INFINITY(dd)) return(G);
400 #endif
401  if (cuddIsConstant(F) && cuddIsConstant(G)) {
402  if (cuddV(F) <= cuddV(G)) {
403  return(F);
404  } else {
405  return(G);
406  }
407  }
408  if (F > G) { /* swap f and g */
409  *f = G;
410  *g = F;
411  }
412  return(NULL);
413 
414 } /* end of Cudd_addMinimum */
415 
416 
417 /**Function********************************************************************
418 
419  Synopsis [Integer and floating point max.]
420 
421  Description [Integer and floating point max for Cudd_addApply.
422  Returns NULL if not a terminal case; max(f,g) otherwise.]
423 
424  SideEffects [None]
425 
426  SeeAlso [Cudd_addApply]
427 
428 ******************************************************************************/
429 DdNode *
431  DdManager * dd,
432  DdNode ** f,
433  DdNode ** g)
434 {
435  DdNode *F, *G;
436 
437  F = *f; G = *g;
438  if (F == G) return(F);
439  if (F == DD_MINUS_INFINITY(dd)) return(G);
440  if (G == DD_MINUS_INFINITY(dd)) return(F);
441 #if 0
442  /* These special cases probably do not pay off. */
443  if (F == DD_PLUS_INFINITY(dd)) return(F);
444  if (G == DD_PLUS_INFINITY(dd)) return(G);
445 #endif
446  if (cuddIsConstant(F) && cuddIsConstant(G)) {
447  if (cuddV(F) >= cuddV(G)) {
448  return(F);
449  } else {
450  return(G);
451  }
452  }
453  if (F > G) { /* swap f and g */
454  *f = G;
455  *g = F;
456  }
457  return(NULL);
458 
459 } /* end of Cudd_addMaximum */
460 
461 
462 /**Function********************************************************************
463 
464  Synopsis [Returns 1 if f &gt; g and 0 otherwise.]
465 
466  Description [Returns 1 if f &gt; g and 0 otherwise. Used in
467  conjunction with Cudd_addApply. Returns NULL if not a terminal
468  case.]
469 
470  SideEffects [None]
471 
472  SeeAlso [Cudd_addApply]
473 
474 ******************************************************************************/
475 DdNode *
477  DdManager * dd,
478  DdNode ** f,
479  DdNode ** g)
480 {
481 
482  if (*f == *g) return(DD_ZERO(dd));
483  if (*g == DD_PLUS_INFINITY(dd))
484  return DD_ZERO(dd);
485  if (cuddIsConstant(*f) && cuddIsConstant(*g)) {
486  if (cuddV(*f) > cuddV(*g)) {
487  return(DD_ONE(dd));
488  } else {
489  return(DD_ZERO(dd));
490  }
491  }
492 
493  return(NULL);
494 
495 } /* end of Cudd_addOneZeroMaximum */
496 
497 
498 /**Function********************************************************************
499 
500  Synopsis [Returns plusinfinity if f=g; returns min(f,g) if f!=g.]
501 
502  Description [Returns NULL if not a terminal case; f op g otherwise,
503  where f op g is plusinfinity if f=g; min(f,g) if f!=g.]
504 
505  SideEffects [None]
506 
507  SeeAlso [Cudd_addApply]
508 
509 ******************************************************************************/
510 DdNode *
512  DdManager * dd,
513  DdNode ** f,
514  DdNode ** g)
515 {
516  DdNode *F, *G;
517 
518  F = *f; G = *g;
519  if (F == G) return(DD_PLUS_INFINITY(dd));
520  if (F == DD_PLUS_INFINITY(dd)) return(G);
521  if (G == DD_PLUS_INFINITY(dd)) return(F);
522  if (cuddIsConstant(F) && cuddIsConstant(G)) {
523  if (cuddV(F) != cuddV(G)) {
524  if (cuddV(F) < cuddV(G)) {
525  return(F);
526  } else {
527  return(G);
528  }
529  } else {
530  return(DD_PLUS_INFINITY(dd));
531  }
532  }
533  return(NULL);
534 
535 } /* end of Cudd_addDiff */
536 
537 
538 /**Function********************************************************************
539 
540  Synopsis [f if f==g; background if f!=g.]
541 
542  Description [Returns NULL if not a terminal case; f op g otherwise,
543  where f op g is f if f==g; background if f!=g.]
544 
545  SideEffects [None]
546 
547  SeeAlso [Cudd_addApply]
548 
549 ******************************************************************************/
550 DdNode *
552  DdManager * dd,
553  DdNode ** f,
554  DdNode ** g)
555 {
556  DdNode *F, *G;
557 
558  F = *f; G = *g;
559  if (F == G) return(F);
560  if (F == dd->background) return(F);
561  if (G == dd->background) return(G);
562  if (cuddIsConstant(F) && cuddIsConstant(G)) return(dd->background);
563  return(NULL);
564 
565 } /* end of Cudd_addAgreement */
566 
567 
568 /**Function********************************************************************
569 
570  Synopsis [Disjunction of two 0-1 ADDs.]
571 
572  Description [Disjunction of two 0-1 ADDs. Returns NULL
573  if not a terminal case; f OR g otherwise.]
574 
575  SideEffects [None]
576 
577  SeeAlso [Cudd_addApply]
578 
579 ******************************************************************************/
580 DdNode *
582  DdManager * dd,
583  DdNode ** f,
584  DdNode ** g)
585 {
586  DdNode *F, *G;
587 
588  F = *f; G = *g;
589  if (F == DD_ONE(dd) || G == DD_ONE(dd)) return(DD_ONE(dd));
590  if (cuddIsConstant(F)) return(G);
591  if (cuddIsConstant(G)) return(F);
592  if (F == G) return(F);
593  if (F > G) { /* swap f and g */
594  *f = G;
595  *g = F;
596  }
597  return(NULL);
598 
599 } /* end of Cudd_addOr */
600 
601 
602 /**Function********************************************************************
603 
604  Synopsis [NAND of two 0-1 ADDs.]
605 
606  Description [NAND of two 0-1 ADDs. Returns NULL
607  if not a terminal case; f NAND g otherwise.]
608 
609  SideEffects [None]
610 
611  SeeAlso [Cudd_addApply]
612 
613 ******************************************************************************/
614 DdNode *
616  DdManager * dd,
617  DdNode ** f,
618  DdNode ** g)
619 {
620  DdNode *F, *G;
621 
622  F = *f; G = *g;
623  if (F == DD_ZERO(dd) || G == DD_ZERO(dd)) return(DD_ONE(dd));
624  if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd));
625  if (F > G) { /* swap f and g */
626  *f = G;
627  *g = F;
628  }
629  return(NULL);
630 
631 } /* end of Cudd_addNand */
632 
633 
634 /**Function********************************************************************
635 
636  Synopsis [NOR of two 0-1 ADDs.]
637 
638  Description [NOR of two 0-1 ADDs. Returns NULL
639  if not a terminal case; f NOR g otherwise.]
640 
641  SideEffects [None]
642 
643  SeeAlso [Cudd_addApply]
644 
645 ******************************************************************************/
646 DdNode *
648  DdManager * dd,
649  DdNode ** f,
650  DdNode ** g)
651 {
652  DdNode *F, *G;
653 
654  F = *f; G = *g;
655  if (F == DD_ONE(dd) || G == DD_ONE(dd)) return(DD_ZERO(dd));
656  if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ONE(dd));
657  if (F > G) { /* swap f and g */
658  *f = G;
659  *g = F;
660  }
661  return(NULL);
662 
663 } /* end of Cudd_addNor */
664 
665 
666 /**Function********************************************************************
667 
668  Synopsis [XOR of two 0-1 ADDs.]
669 
670  Description [XOR of two 0-1 ADDs. Returns NULL
671  if not a terminal case; f XOR g otherwise.]
672 
673  SideEffects [None]
674 
675  SeeAlso [Cudd_addApply]
676 
677 ******************************************************************************/
678 DdNode *
680  DdManager * dd,
681  DdNode ** f,
682  DdNode ** g)
683 {
684  DdNode *F, *G;
685 
686  F = *f; G = *g;
687  if (F == G) return(DD_ZERO(dd));
688  if (F == DD_ONE(dd) && G == DD_ZERO(dd)) return(DD_ONE(dd));
689  if (G == DD_ONE(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd));
690  if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd));
691  if (F > G) { /* swap f and g */
692  *f = G;
693  *g = F;
694  }
695  return(NULL);
696 
697 } /* end of Cudd_addXor */
698 
699 
700 /**Function********************************************************************
701 
702  Synopsis [XNOR of two 0-1 ADDs.]
703 
704  Description [XNOR of two 0-1 ADDs. Returns NULL
705  if not a terminal case; f XNOR g otherwise.]
706 
707  SideEffects [None]
708 
709  SeeAlso [Cudd_addApply]
710 
711 ******************************************************************************/
712 DdNode *
714  DdManager * dd,
715  DdNode ** f,
716  DdNode ** g)
717 {
718  DdNode *F, *G;
719 
720  F = *f; G = *g;
721  if (F == G) return(DD_ONE(dd));
722  if (F == DD_ONE(dd) && G == DD_ONE(dd)) return(DD_ONE(dd));
723  if (G == DD_ZERO(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd));
724  if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd));
725  if (F > G) { /* swap f and g */
726  *f = G;
727  *g = F;
728  }
729  return(NULL);
730 
731 } /* end of Cudd_addXnor */
732 
733 
734 /**Function********************************************************************
735 
736  Synopsis [Applies op to the discriminants of f.]
737 
738  Description [Applies op to the discriminants of f.
739  Returns a pointer to the result if succssful; NULL otherwise.]
740 
741  SideEffects [None]
742 
743  SeeAlso [Cudd_addApply Cudd_addLog]
744 
745 ******************************************************************************/
746 DdNode *
748  DdManager * dd,
749  DD_MAOP op,
750  DdNode * f)
751 {
752  DdNode *res;
753 
754  do {
755  dd->reordered = 0;
756  res = cuddAddMonadicApplyRecur(dd,op,f);
757  } while (dd->reordered == 1);
758  return(res);
759 
760 } /* end of Cudd_addMonadicApply */
761 
762 
763 /**Function********************************************************************
764 
765  Synopsis [Natural logarithm of an ADD.]
766 
767  Description [Natural logarithm of an ADDs. Returns NULL
768  if not a terminal case; log(f) otherwise. The discriminants of f must
769  be positive double's.]
770 
771  SideEffects [None]
772 
773  SeeAlso [Cudd_addMonadicApply]
774 
775 ******************************************************************************/
776 DdNode *
778  DdManager * dd,
779  DdNode * f)
780 {
781  if (cuddIsConstant(f)) {
782  CUDD_VALUE_TYPE value = log(cuddV(f));
783  DdNode *res = cuddUniqueConst(dd,value);
784  return(res);
785  }
786  return(NULL);
787 
788 } /* end of Cudd_addLog */
789 
790 
791 /*---------------------------------------------------------------------------*/
792 /* Definition of internal functions */
793 /*---------------------------------------------------------------------------*/
794 
795 
796 /**Function********************************************************************
797 
798  Synopsis [Performs the recursive step of Cudd_addApply.]
799 
800  Description [Performs the recursive step of Cudd_addApply. Returns a
801  pointer to the result if successful; NULL otherwise.]
802 
803  SideEffects [None]
804 
805  SeeAlso [cuddAddMonadicApplyRecur]
806 
807 ******************************************************************************/
808 DdNode *
810  DdManager * dd,
811  DD_AOP op,
812  DdNode * f,
813  DdNode * g)
814 {
815  DdNode *res,
816  *fv, *fvn, *gv, *gvn,
817  *T, *E;
818  unsigned int ford, gord;
819  unsigned int index;
820  DD_CTFP cacheOp;
821 
822  /* Check terminal cases. Op may swap f and g to increase the
823  * cache hit rate.
824  */
825  statLine(dd);
826  res = (*op)(dd,&f,&g);
827  if (res != NULL) return(res);
828 
829  /* Check cache. */
830  cacheOp = (DD_CTFP) op;
831  res = cuddCacheLookup2(dd,cacheOp,f,g);
832  if (res != NULL) return(res);
833 
834  /* Recursive step. */
835  ford = cuddI(dd,f->index);
836  gord = cuddI(dd,g->index);
837  if (ford <= gord) {
838  index = f->index;
839  fv = cuddT(f);
840  fvn = cuddE(f);
841  } else {
842  index = g->index;
843  fv = fvn = f;
844  }
845  if (gord <= ford) {
846  gv = cuddT(g);
847  gvn = cuddE(g);
848  } else {
849  gv = gvn = g;
850  }
851 
852  T = cuddAddApplyRecur(dd,op,fv,gv);
853  if (T == NULL) return(NULL);
854  cuddRef(T);
855 
856  E = cuddAddApplyRecur(dd,op,fvn,gvn);
857  if (E == NULL) {
858  Cudd_RecursiveDeref(dd,T);
859  return(NULL);
860  }
861  cuddRef(E);
862 
863  res = (T == E) ? T : cuddUniqueInter(dd,(int)index,T,E);
864  if (res == NULL) {
865  Cudd_RecursiveDeref(dd, T);
866  Cudd_RecursiveDeref(dd, E);
867  return(NULL);
868  }
869  cuddDeref(T);
870  cuddDeref(E);
871 
872  /* Store result. */
873  cuddCacheInsert2(dd,cacheOp,f,g,res);
874 
875  return(res);
876 
877 } /* end of cuddAddApplyRecur */
878 
879 
880 /**Function********************************************************************
881 
882  Synopsis [Performs the recursive step of Cudd_addMonadicApply.]
883 
884  Description [Performs the recursive step of Cudd_addMonadicApply. Returns a
885  pointer to the result if successful; NULL otherwise.]
886 
887  SideEffects [None]
888 
889  SeeAlso [cuddAddApplyRecur]
890 
891 ******************************************************************************/
892 DdNode *
894  DdManager * dd,
895  DD_MAOP op,
896  DdNode * f)
897 {
898  DdNode *res, *ft, *fe, *T, *E;
899  unsigned int index;
900 
901  /* Check terminal cases. */
902  statLine(dd);
903  res = (*op)(dd,f);
904  if (res != NULL) return(res);
905 
906  /* Check cache. */
907  res = cuddCacheLookup1(dd,op,f);
908  if (res != NULL) return(res);
909 
910  /* Recursive step. */
911  index = f->index;
912  ft = cuddT(f);
913  fe = cuddE(f);
914 
915  T = cuddAddMonadicApplyRecur(dd,op,ft);
916  if (T == NULL) return(NULL);
917  cuddRef(T);
918 
919  E = cuddAddMonadicApplyRecur(dd,op,fe);
920  if (E == NULL) {
921  Cudd_RecursiveDeref(dd,T);
922  return(NULL);
923  }
924  cuddRef(E);
925 
926  res = (T == E) ? T : cuddUniqueInter(dd,(int)index,T,E);
927  if (res == NULL) {
928  Cudd_RecursiveDeref(dd, T);
929  Cudd_RecursiveDeref(dd, E);
930  return(NULL);
931  }
932  cuddDeref(T);
933  cuddDeref(E);
934 
935  /* Store result. */
936  cuddCacheInsert1(dd,op,f,res);
937 
938  return(res);
939 
940 } /* end of cuddAddMonadicApplyRecur */
941 
942 
943 /*---------------------------------------------------------------------------*/
944 /* Definition of static functions */
945 /*---------------------------------------------------------------------------*/
946 
947 
949 
#define cuddRef(n)
Definition: cuddInt.h:584
DdNode * Cudd_addApply(DdManager *dd, DD_AOP op, DdNode *f, DdNode *g)
Definition: cuddAddApply.c:138
static ABC_NAMESPACE_IMPL_START char rcsid[] DD_UNUSED
Definition: cuddAddApply.c:99
#define cuddDeref(n)
Definition: cuddInt.h:604
DdNode * Cudd_addOneZeroMaximum(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:476
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
DdNode * cuddUniqueConst(DdManager *unique, CUDD_VALUE_TYPE value)
Definition: cuddTable.c:1450
DdNode * Cudd_addNor(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:647
DdNode * Cudd_addXor(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:679
DdNode * cuddAddApplyRecur(DdManager *dd, DD_AOP op, DdNode *f, DdNode *g)
Definition: cuddAddApply.c:809
DdNode * Cudd_addNand(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:615
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:321
DdNode * Cudd_addMonadicApply(DdManager *dd, DD_MAOP op, DdNode *f)
Definition: cuddAddApply.c:747
DdNode * cuddAddMonadicApplyRecur(DdManager *dd, DD_MAOP op, DdNode *f)
Definition: cuddAddApply.c:893
DdNode * Cudd_addMinimum(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:385
DdNode * Cudd_addMaximum(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:430
#define statLine(dd)
Definition: cuddInt.h:1037
#define DD_MINUS_INFINITY(dd)
Definition: cuddInt.h:955
#define cuddV(node)
Definition: cuddInt.h:668
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
DdNode * Cudd_addSetNZ(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:282
int reordered
Definition: cuddInt.h:409
DdNode * cuddCacheLookup1(DdManager *table, DD_CTFP1 op, DdNode *f)
Definition: cuddCache.c:556
DdNode * cuddAddNegateRecur(DdManager *dd, DdNode *f)
Definition: cuddAddNeg.c:180
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
#define cuddIsConstant(node)
Definition: cuddInt.h:620
DdNode * Cudd_addLog(DdManager *dd, DdNode *f)
Definition: cuddAddApply.c:777
DdNode * Cudd_addThreshold(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:248
DdNode * Cudd_addDiff(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:511
DdNode *(* DD_MAOP)(DdManager *, DdNode *)
Definition: cudd.h:319
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * Cudd_addMinus(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:349
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
DdNode * Cudd_addAgreement(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:551
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdNode * Cudd_addDivide(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:312
#define CUDD_VALUE_TYPE
Definition: cudd.h:94
DdHalfWord index
Definition: cudd.h:279
DdNode *(* DD_AOP)(DdManager *, DdNode **, DdNode **)
Definition: cudd.h:317
#define cuddE(node)
Definition: cuddInt.h:652
#define DD_PLUS_INFINITY(dd)
Definition: cuddInt.h:941
int value
DdNode * Cudd_addOr(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:581
DdNode * Cudd_addPlus(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:168
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * Cudd_addXnor(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:713
DdNode * Cudd_addTimes(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:208
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
void cuddCacheInsert1(DdManager *table, DD_CTFP1 op, DdNode *f, DdNode *data)
Definition: cuddCache.c:323
DdNode * background
Definition: cuddInt.h:349
#define DD_ZERO(dd)
Definition: cuddInt.h:927