abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddBridge.c
Go to the documentation of this file.
1 /**CFile***********************************************************************
2 
3  FileName [cuddBridge.c]
4 
5  PackageName [cudd]
6 
7  Synopsis [Translation from BDD to ADD and vice versa and transfer between
8  different managers.]
9 
10  Description [External procedures included in this file:
11  <ul>
12  <li> Cudd_addBddThreshold()
13  <li> Cudd_addBddStrictThreshold()
14  <li> Cudd_addBddInterval()
15  <li> Cudd_addBddIthBit()
16  <li> Cudd_BddToAdd()
17  <li> Cudd_addBddPattern()
18  <li> Cudd_bddTransfer()
19  </ul>
20  Internal procedures included in this file:
21  <ul>
22  <li> cuddBddTransfer()
23  <li> cuddAddBddDoPattern()
24  </ul>
25  Static procedures included in this file:
26  <ul>
27  <li> addBddDoThreshold()
28  <li> addBddDoStrictThreshold()
29  <li> addBddDoInterval()
30  <li> addBddDoIthBit()
31  <li> ddBddToAddRecur()
32  <li> cuddBddTransferRecur()
33  </ul>
34  ]
35 
36  SeeAlso []
37 
38  Author [Fabio Somenzi]
39 
40  Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
41 
42  All rights reserved.
43 
44  Redistribution and use in source and binary forms, with or without
45  modification, are permitted provided that the following conditions
46  are met:
47 
48  Redistributions of source code must retain the above copyright
49  notice, this list of conditions and the following disclaimer.
50 
51  Redistributions in binary form must reproduce the above copyright
52  notice, this list of conditions and the following disclaimer in the
53  documentation and/or other materials provided with the distribution.
54 
55  Neither the name of the University of Colorado nor the names of its
56  contributors may be used to endorse or promote products derived from
57  this software without specific prior written permission.
58 
59  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
60  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
61  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
62  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
63  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
64  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
65  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
66  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
67  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
68  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
69  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
70  POSSIBILITY OF SUCH DAMAGE.]
71 
72 ******************************************************************************/
73 
74 #include "misc/util/util_hack.h"
75 #include "cuddInt.h"
76 
78 
79 
80 
81 /*---------------------------------------------------------------------------*/
82 /* Constant declarations */
83 /*---------------------------------------------------------------------------*/
84 
85 
86 /*---------------------------------------------------------------------------*/
87 /* Stucture declarations */
88 /*---------------------------------------------------------------------------*/
89 
90 
91 /*---------------------------------------------------------------------------*/
92 /* Type declarations */
93 /*---------------------------------------------------------------------------*/
94 
95 
96 /*---------------------------------------------------------------------------*/
97 /* Variable declarations */
98 /*---------------------------------------------------------------------------*/
99 
100 #ifndef lint
101 static char rcsid[] DD_UNUSED = "$Id: cuddBridge.c,v 1.19 2008/04/25 06:42:55 fabio Exp $";
102 #endif
103 
104 /*---------------------------------------------------------------------------*/
105 /* Macro declarations */
106 /*---------------------------------------------------------------------------*/
107 
108 
109 #ifdef __cplusplus
110 extern "C" {
111 #endif
112 
113 /**AutomaticStart*************************************************************/
114 
115 /*---------------------------------------------------------------------------*/
116 /* Static function prototypes */
117 /*---------------------------------------------------------------------------*/
118 
119 static DdNode * addBddDoThreshold (DdManager *dd, DdNode *f, DdNode *val);
120 static DdNode * addBddDoStrictThreshold (DdManager *dd, DdNode *f, DdNode *val);
121 static DdNode * addBddDoInterval (DdManager *dd, DdNode *f, DdNode *l, DdNode *u);
122 static DdNode * addBddDoIthBit (DdManager *dd, DdNode *f, DdNode *index);
123 static DdNode * ddBddToAddRecur (DdManager *dd, DdNode *B);
124 static DdNode * cuddBddTransferRecur (DdManager *ddS, DdManager *ddD, DdNode *f, st__table *table);
125 
126 /**AutomaticEnd***************************************************************/
127 
128 #ifdef __cplusplus
129 }
130 #endif
131 
132 
133 /*---------------------------------------------------------------------------*/
134 /* Definition of exported functions */
135 /*---------------------------------------------------------------------------*/
136 
137 
138 /**Function********************************************************************
139 
140  Synopsis [Converts an ADD to a BDD.]
141 
142  Description [Converts an ADD to a BDD by replacing all
143  discriminants greater than or equal to value with 1, and all other
144  discriminants with 0. Returns a pointer to the resulting BDD if
145  successful; NULL otherwise.]
146 
147  SideEffects [None]
148 
149  SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd
150  Cudd_addBddStrictThreshold]
151 
152 ******************************************************************************/
153 DdNode *
155  DdManager * dd,
156  DdNode * f,
158 {
159  DdNode *res;
160  DdNode *val;
161 
162  val = cuddUniqueConst(dd,value);
163  if (val == NULL) return(NULL);
164  cuddRef(val);
165 
166  do {
167  dd->reordered = 0;
168  res = addBddDoThreshold(dd, f, val);
169  } while (dd->reordered == 1);
170 
171  if (res == NULL) {
172  Cudd_RecursiveDeref(dd, val);
173  return(NULL);
174  }
175  cuddRef(res);
176  Cudd_RecursiveDeref(dd, val);
177  cuddDeref(res);
178  return(res);
179 
180 } /* end of Cudd_addBddThreshold */
181 
182 
183 /**Function********************************************************************
184 
185  Synopsis [Converts an ADD to a BDD.]
186 
187  Description [Converts an ADD to a BDD by replacing all
188  discriminants STRICTLY greater than value with 1, and all other
189  discriminants with 0. Returns a pointer to the resulting BDD if
190  successful; NULL otherwise.]
191 
192  SideEffects [None]
193 
194  SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd
195  Cudd_addBddThreshold]
196 
197 ******************************************************************************/
198 DdNode *
200  DdManager * dd,
201  DdNode * f,
203 {
204  DdNode *res;
205  DdNode *val;
206 
207  val = cuddUniqueConst(dd,value);
208  if (val == NULL) return(NULL);
209  cuddRef(val);
210 
211  do {
212  dd->reordered = 0;
213  res = addBddDoStrictThreshold(dd, f, val);
214  } while (dd->reordered == 1);
215 
216  if (res == NULL) {
217  Cudd_RecursiveDeref(dd, val);
218  return(NULL);
219  }
220  cuddRef(res);
221  Cudd_RecursiveDeref(dd, val);
222  cuddDeref(res);
223  return(res);
224 
225 } /* end of Cudd_addBddStrictThreshold */
226 
227 
228 /**Function********************************************************************
229 
230  Synopsis [Converts an ADD to a BDD.]
231 
232  Description [Converts an ADD to a BDD by replacing all
233  discriminants greater than or equal to lower and less than or equal to
234  upper with 1, and all other discriminants with 0. Returns a pointer to
235  the resulting BDD if successful; NULL otherwise.]
236 
237  SideEffects [None]
238 
239  SeeAlso [Cudd_addBddThreshold Cudd_addBddStrictThreshold
240  Cudd_addBddPattern Cudd_BddToAdd]
241 
242 ******************************************************************************/
243 DdNode *
245  DdManager * dd,
246  DdNode * f,
247  CUDD_VALUE_TYPE lower,
248  CUDD_VALUE_TYPE upper)
249 {
250  DdNode *res;
251  DdNode *l;
252  DdNode *u;
253 
254  /* Create constant nodes for the interval bounds, so that we can use
255  ** the global cache.
256  */
257  l = cuddUniqueConst(dd,lower);
258  if (l == NULL) return(NULL);
259  cuddRef(l);
260  u = cuddUniqueConst(dd,upper);
261  if (u == NULL) {
262  Cudd_RecursiveDeref(dd,l);
263  return(NULL);
264  }
265  cuddRef(u);
266 
267  do {
268  dd->reordered = 0;
269  res = addBddDoInterval(dd, f, l, u);
270  } while (dd->reordered == 1);
271 
272  if (res == NULL) {
273  Cudd_RecursiveDeref(dd, l);
274  Cudd_RecursiveDeref(dd, u);
275  return(NULL);
276  }
277  cuddRef(res);
278  Cudd_RecursiveDeref(dd, l);
279  Cudd_RecursiveDeref(dd, u);
280  cuddDeref(res);
281  return(res);
282 
283 } /* end of Cudd_addBddInterval */
284 
285 
286 /**Function********************************************************************
287 
288  Synopsis [Converts an ADD to a BDD by extracting the i-th bit from
289  the leaves.]
290 
291  Description [Converts an ADD to a BDD by replacing all
292  discriminants whose i-th bit is equal to 1 with 1, and all other
293  discriminants with 0. The i-th bit refers to the integer
294  representation of the leaf value. If the value is has a fractional
295  part, it is ignored. Repeated calls to this procedure allow one to
296  transform an integer-valued ADD into an array of BDDs, one for each
297  bit of the leaf values. Returns a pointer to the resulting BDD if
298  successful; NULL otherwise.]
299 
300  SideEffects [None]
301 
302  SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd]
303 
304 ******************************************************************************/
305 DdNode *
307  DdManager * dd,
308  DdNode * f,
309  int bit)
310 {
311  DdNode *res;
312  DdNode *index;
313 
314  index = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) bit);
315  if (index == NULL) return(NULL);
316  cuddRef(index);
317 
318  do {
319  dd->reordered = 0;
320  res = addBddDoIthBit(dd, f, index);
321  } while (dd->reordered == 1);
322 
323  if (res == NULL) {
324  Cudd_RecursiveDeref(dd, index);
325  return(NULL);
326  }
327  cuddRef(res);
328  Cudd_RecursiveDeref(dd, index);
329  cuddDeref(res);
330  return(res);
331 
332 } /* end of Cudd_addBddIthBit */
333 
334 
335 /**Function********************************************************************
336 
337  Synopsis [Converts a BDD to a 0-1 ADD.]
338 
339  Description [Converts a BDD to a 0-1 ADD. Returns a pointer to the
340  resulting ADD if successful; NULL otherwise.]
341 
342  SideEffects [None]
343 
344  SeeAlso [Cudd_addBddPattern Cudd_addBddThreshold Cudd_addBddInterval
345  Cudd_addBddStrictThreshold]
346 
347 ******************************************************************************/
348 DdNode *
350  DdManager * dd,
351  DdNode * B)
352 {
353  DdNode *res;
354 
355  do {
356  dd->reordered = 0;
357  res = ddBddToAddRecur(dd, B);
358  } while (dd->reordered ==1);
359  return(res);
360 
361 } /* end of Cudd_BddToAdd */
362 
363 
364 /**Function********************************************************************
365 
366  Synopsis [Converts an ADD to a BDD.]
367 
368  Description [Converts an ADD to a BDD by replacing all
369  discriminants different from 0 with 1. Returns a pointer to the
370  resulting BDD if successful; NULL otherwise.]
371 
372  SideEffects [None]
373 
374  SeeAlso [Cudd_BddToAdd Cudd_addBddThreshold Cudd_addBddInterval
375  Cudd_addBddStrictThreshold]
376 
377 ******************************************************************************/
378 DdNode *
380  DdManager * dd,
381  DdNode * f)
382 {
383  DdNode *res;
384 
385  do {
386  dd->reordered = 0;
387  res = cuddAddBddDoPattern(dd, f);
388  } while (dd->reordered == 1);
389  return(res);
390 
391 } /* end of Cudd_addBddPattern */
392 
393 
394 /**Function********************************************************************
395 
396  Synopsis [Convert a BDD from a manager to another one.]
397 
398  Description [Convert a BDD from a manager to another one. The orders of the
399  variables in the two managers may be different. Returns a
400  pointer to the BDD in the destination manager if successful; NULL
401  otherwise.]
402 
403  SideEffects [None]
404 
405  SeeAlso []
406 
407 ******************************************************************************/
408 DdNode *
410  DdManager * ddSource,
411  DdManager * ddDestination,
412  DdNode * f)
413 {
414  DdNode *res;
415  do {
416  ddDestination->reordered = 0;
417  res = cuddBddTransfer(ddSource, ddDestination, f);
418  } while (ddDestination->reordered == 1);
419  return(res);
420 
421 } /* end of Cudd_bddTransfer */
422 
423 
424 /*---------------------------------------------------------------------------*/
425 /* Definition of internal functions */
426 /*---------------------------------------------------------------------------*/
427 
428 
429 /**Function********************************************************************
430 
431  Synopsis [Convert a BDD from a manager to another one.]
432 
433  Description [Convert a BDD from a manager to another one. Returns a
434  pointer to the BDD in the destination manager if successful; NULL
435  otherwise.]
436 
437  SideEffects [None]
438 
439  SeeAlso [Cudd_bddTransfer]
440 
441 ******************************************************************************/
442 DdNode *
444  DdManager * ddS,
445  DdManager * ddD,
446  DdNode * f)
447 {
448  DdNode *res;
449  st__table *table = NULL;
450  st__generator *gen = NULL;
451  DdNode *key, *value;
452 
454  if (table == NULL) goto failure;
455  res = cuddBddTransferRecur(ddS, ddD, f, table);
456  if (res != NULL) cuddRef(res);
457 
458  /* Dereference all elements in the table and dispose of the table.
459  ** This must be done also if res is NULL to avoid leaks in case of
460  ** reordering. */
461  gen = st__init_gen(table);
462  if (gen == NULL) goto failure;
463  while ( st__gen(gen, (const char **)&key, (char **)&value)) {
464  Cudd_RecursiveDeref(ddD, value);
465  }
466  st__free_gen(gen); gen = NULL;
467  st__free_table(table); table = NULL;
468 
469  if (res != NULL) cuddDeref(res);
470  return(res);
471 
472 failure:
473  /* No need to free gen because it is always NULL here. */
474  if (table != NULL) st__free_table(table);
475  return(NULL);
476 
477 } /* end of cuddBddTransfer */
478 
479 
480 /**Function********************************************************************
481 
482  Synopsis [Performs the recursive step for Cudd_addBddPattern.]
483 
484  Description [Performs the recursive step for Cudd_addBddPattern. Returns a
485  pointer to the resulting BDD if successful; NULL otherwise.]
486 
487  SideEffects [None]
488 
489  SeeAlso []
490 
491 ******************************************************************************/
492 DdNode *
494  DdManager * dd,
495  DdNode * f)
496 {
497  DdNode *res, *T, *E;
498  DdNode *fv, *fvn;
499  int v;
500 
501  statLine(dd);
502  /* Check terminal case. */
503  if (cuddIsConstant(f)) {
504  return(Cudd_NotCond(DD_ONE(dd),f == DD_ZERO(dd)));
505  }
506 
507  /* Check cache. */
509  if (res != NULL) return(res);
510 
511  /* Recursive step. */
512  v = f->index;
513  fv = cuddT(f); fvn = cuddE(f);
514 
515  T = cuddAddBddDoPattern(dd,fv);
516  if (T == NULL) return(NULL);
517  cuddRef(T);
518 
519  E = cuddAddBddDoPattern(dd,fvn);
520  if (E == NULL) {
521  Cudd_RecursiveDeref(dd, T);
522  return(NULL);
523  }
524  cuddRef(E);
525  if (Cudd_IsComplement(T)) {
526  res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E));
527  if (res == NULL) {
528  Cudd_RecursiveDeref(dd, T);
529  Cudd_RecursiveDeref(dd, E);
530  return(NULL);
531  }
532  res = Cudd_Not(res);
533  } else {
534  res = (T == E) ? T : cuddUniqueInter(dd,v,T,E);
535  if (res == NULL) {
536  Cudd_RecursiveDeref(dd, T);
537  Cudd_RecursiveDeref(dd, E);
538  return(NULL);
539  }
540  }
541  cuddDeref(T);
542  cuddDeref(E);
543 
544  /* Store result. */
546 
547  return(res);
548 
549 } /* end of cuddAddBddDoPattern */
550 
551 
552 /*---------------------------------------------------------------------------*/
553 /* Definition of static functions */
554 /*---------------------------------------------------------------------------*/
555 
556 
557 /**Function********************************************************************
558 
559  Synopsis [Performs the recursive step for Cudd_addBddThreshold.]
560 
561  Description [Performs the recursive step for Cudd_addBddThreshold.
562  Returns a pointer to the BDD if successful; NULL otherwise.]
563 
564  SideEffects [None]
565 
566  SeeAlso [addBddDoStrictThreshold]
567 
568 ******************************************************************************/
569 static DdNode *
571  DdManager * dd,
572  DdNode * f,
573  DdNode * val)
574 {
575  DdNode *res, *T, *E;
576  DdNode *fv, *fvn;
577  int v;
578 
579  statLine(dd);
580  /* Check terminal case. */
581  if (cuddIsConstant(f)) {
582  return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(val)));
583  }
584 
585  /* Check cache. */
586  res = cuddCacheLookup2(dd,addBddDoThreshold,f,val);
587  if (res != NULL) return(res);
588 
589  /* Recursive step. */
590  v = f->index;
591  fv = cuddT(f); fvn = cuddE(f);
592 
593  T = addBddDoThreshold(dd,fv,val);
594  if (T == NULL) return(NULL);
595  cuddRef(T);
596 
597  E = addBddDoThreshold(dd,fvn,val);
598  if (E == NULL) {
599  Cudd_RecursiveDeref(dd, T);
600  return(NULL);
601  }
602  cuddRef(E);
603  if (Cudd_IsComplement(T)) {
604  res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E));
605  if (res == NULL) {
606  Cudd_RecursiveDeref(dd, T);
607  Cudd_RecursiveDeref(dd, E);
608  return(NULL);
609  }
610  res = Cudd_Not(res);
611  } else {
612  res = (T == E) ? T : cuddUniqueInter(dd,v,T,E);
613  if (res == NULL) {
614  Cudd_RecursiveDeref(dd, T);
615  Cudd_RecursiveDeref(dd, E);
616  return(NULL);
617  }
618  }
619  cuddDeref(T);
620  cuddDeref(E);
621 
622  /* Store result. */
623  cuddCacheInsert2(dd,addBddDoThreshold,f,val,res);
624 
625  return(res);
626 
627 } /* end of addBddDoThreshold */
628 
629 
630 /**Function********************************************************************
631 
632  Synopsis [Performs the recursive step for Cudd_addBddStrictThreshold.]
633 
634  Description [Performs the recursive step for Cudd_addBddStrictThreshold.
635  Returns a pointer to the BDD if successful; NULL otherwise.]
636 
637  SideEffects [None]
638 
639  SeeAlso [addBddDoThreshold]
640 
641 ******************************************************************************/
642 static DdNode *
644  DdManager * dd,
645  DdNode * f,
646  DdNode * val)
647 {
648  DdNode *res, *T, *E;
649  DdNode *fv, *fvn;
650  int v;
651 
652  statLine(dd);
653  /* Check terminal case. */
654  if (cuddIsConstant(f)) {
655  return(Cudd_NotCond(DD_ONE(dd),cuddV(f) <= cuddV(val)));
656  }
657 
658  /* Check cache. */
660  if (res != NULL) return(res);
661 
662  /* Recursive step. */
663  v = f->index;
664  fv = cuddT(f); fvn = cuddE(f);
665 
666  T = addBddDoStrictThreshold(dd,fv,val);
667  if (T == NULL) return(NULL);
668  cuddRef(T);
669 
670  E = addBddDoStrictThreshold(dd,fvn,val);
671  if (E == NULL) {
672  Cudd_RecursiveDeref(dd, T);
673  return(NULL);
674  }
675  cuddRef(E);
676  if (Cudd_IsComplement(T)) {
677  res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E));
678  if (res == NULL) {
679  Cudd_RecursiveDeref(dd, T);
680  Cudd_RecursiveDeref(dd, E);
681  return(NULL);
682  }
683  res = Cudd_Not(res);
684  } else {
685  res = (T == E) ? T : cuddUniqueInter(dd,v,T,E);
686  if (res == NULL) {
687  Cudd_RecursiveDeref(dd, T);
688  Cudd_RecursiveDeref(dd, E);
689  return(NULL);
690  }
691  }
692  cuddDeref(T);
693  cuddDeref(E);
694 
695  /* Store result. */
697 
698  return(res);
699 
700 } /* end of addBddDoStrictThreshold */
701 
702 
703 /**Function********************************************************************
704 
705  Synopsis [Performs the recursive step for Cudd_addBddInterval.]
706 
707  Description [Performs the recursive step for Cudd_addBddInterval.
708  Returns a pointer to the BDD if successful; NULL otherwise.]
709 
710  SideEffects [None]
711 
712  SeeAlso [addBddDoThreshold addBddDoStrictThreshold]
713 
714 ******************************************************************************/
715 static DdNode *
717  DdManager * dd,
718  DdNode * f,
719  DdNode * l,
720  DdNode * u)
721 {
722  DdNode *res, *T, *E;
723  DdNode *fv, *fvn;
724  int v;
725 
726  statLine(dd);
727  /* Check terminal case. */
728  if (cuddIsConstant(f)) {
729  return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(l) || cuddV(f) > cuddV(u)));
730  }
731 
732  /* Check cache. */
734  if (res != NULL) return(res);
735 
736  /* Recursive step. */
737  v = f->index;
738  fv = cuddT(f); fvn = cuddE(f);
739 
740  T = addBddDoInterval(dd,fv,l,u);
741  if (T == NULL) return(NULL);
742  cuddRef(T);
743 
744  E = addBddDoInterval(dd,fvn,l,u);
745  if (E == NULL) {
746  Cudd_RecursiveDeref(dd, T);
747  return(NULL);
748  }
749  cuddRef(E);
750  if (Cudd_IsComplement(T)) {
751  res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E));
752  if (res == NULL) {
753  Cudd_RecursiveDeref(dd, T);
754  Cudd_RecursiveDeref(dd, E);
755  return(NULL);
756  }
757  res = Cudd_Not(res);
758  } else {
759  res = (T == E) ? T : cuddUniqueInter(dd,v,T,E);
760  if (res == NULL) {
761  Cudd_RecursiveDeref(dd, T);
762  Cudd_RecursiveDeref(dd, E);
763  return(NULL);
764  }
765  }
766  cuddDeref(T);
767  cuddDeref(E);
768 
769  /* Store result. */
771 
772  return(res);
773 
774 } /* end of addBddDoInterval */
775 
776 
777 /**Function********************************************************************
778 
779  Synopsis [Performs the recursive step for Cudd_addBddIthBit.]
780 
781  Description [Performs the recursive step for Cudd_addBddIthBit.
782  Returns a pointer to the BDD if successful; NULL otherwise.]
783 
784  SideEffects [None]
785 
786  SeeAlso []
787 
788 ******************************************************************************/
789 static DdNode *
791  DdManager * dd,
792  DdNode * f,
793  DdNode * index)
794 {
795  DdNode *res, *T, *E;
796  DdNode *fv, *fvn;
797  int mask, value;
798  int v;
799 
800  statLine(dd);
801  /* Check terminal case. */
802  if (cuddIsConstant(f)) {
803  mask = 1 << ((int) cuddV(index));
804  value = (int) cuddV(f);
805  return(Cudd_NotCond(DD_ONE(dd),(value & mask) == 0));
806  }
807 
808  /* Check cache. */
809  res = cuddCacheLookup2(dd,addBddDoIthBit,f,index);
810  if (res != NULL) return(res);
811 
812  /* Recursive step. */
813  v = f->index;
814  fv = cuddT(f); fvn = cuddE(f);
815 
816  T = addBddDoIthBit(dd,fv,index);
817  if (T == NULL) return(NULL);
818  cuddRef(T);
819 
820  E = addBddDoIthBit(dd,fvn,index);
821  if (E == NULL) {
822  Cudd_RecursiveDeref(dd, T);
823  return(NULL);
824  }
825  cuddRef(E);
826  if (Cudd_IsComplement(T)) {
827  res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E));
828  if (res == NULL) {
829  Cudd_RecursiveDeref(dd, T);
830  Cudd_RecursiveDeref(dd, E);
831  return(NULL);
832  }
833  res = Cudd_Not(res);
834  } else {
835  res = (T == E) ? T : cuddUniqueInter(dd,v,T,E);
836  if (res == NULL) {
837  Cudd_RecursiveDeref(dd, T);
838  Cudd_RecursiveDeref(dd, E);
839  return(NULL);
840  }
841  }
842  cuddDeref(T);
843  cuddDeref(E);
844 
845  /* Store result. */
846  cuddCacheInsert2(dd,addBddDoIthBit,f,index,res);
847 
848  return(res);
849 
850 } /* end of addBddDoIthBit */
851 
852 
853 /**Function********************************************************************
854 
855  Synopsis [Performs the recursive step for Cudd_BddToAdd.]
856 
857  Description [Performs the recursive step for Cudd_BddToAdd. Returns a
858  pointer to the resulting ADD if successful; NULL otherwise.]
859 
860  SideEffects [None]
861 
862  SeeAlso []
863 
864 ******************************************************************************/
865 static DdNode *
867  DdManager * dd,
868  DdNode * B)
869 {
870  DdNode *one;
871  DdNode *res, *res1, *T, *E, *Bt, *Be;
872  int complement = 0;
873 
874  statLine(dd);
875  one = DD_ONE(dd);
876 
877  if (Cudd_IsConstant(B)) {
878  if (B == one) {
879  res = one;
880  } else {
881  res = DD_ZERO(dd);
882  }
883  return(res);
884  }
885  /* Check visited table */
886  res = cuddCacheLookup1(dd,ddBddToAddRecur,B);
887  if (res != NULL) return(res);
888 
889  if (Cudd_IsComplement(B)) {
890  complement = 1;
891  Bt = cuddT(Cudd_Regular(B));
892  Be = cuddE(Cudd_Regular(B));
893  } else {
894  Bt = cuddT(B);
895  Be = cuddE(B);
896  }
897 
898  T = ddBddToAddRecur(dd, Bt);
899  if (T == NULL) return(NULL);
900  cuddRef(T);
901 
902  E = ddBddToAddRecur(dd, Be);
903  if (E == NULL) {
904  Cudd_RecursiveDeref(dd, T);
905  return(NULL);
906  }
907  cuddRef(E);
908 
909  /* No need to check for T == E, because it is guaranteed not to happen. */
910  res = cuddUniqueInter(dd, (int) Cudd_Regular(B)->index, T, E);
911  if (res == NULL) {
912  Cudd_RecursiveDeref(dd ,T);
913  Cudd_RecursiveDeref(dd ,E);
914  return(NULL);
915  }
916  cuddDeref(T);
917  cuddDeref(E);
918 
919  if (complement) {
920  cuddRef(res);
921  res1 = cuddAddCmplRecur(dd, res);
922  if (res1 == NULL) {
923  Cudd_RecursiveDeref(dd, res);
924  return(NULL);
925  }
926  cuddRef(res1);
927  Cudd_RecursiveDeref(dd, res);
928  res = res1;
929  cuddDeref(res);
930  }
931 
932  /* Store result. */
934 
935  return(res);
936 
937 } /* end of ddBddToAddRecur */
938 
939 
940 /**Function********************************************************************
941 
942  Synopsis [Performs the recursive step of Cudd_bddTransfer.]
943 
944  Description [Performs the recursive step of Cudd_bddTransfer.
945  Returns a pointer to the result if successful; NULL otherwise.]
946 
947  SideEffects [None]
948 
949  SeeAlso [cuddBddTransfer]
950 
951 ******************************************************************************/
952 static DdNode *
954  DdManager * ddS,
955  DdManager * ddD,
956  DdNode * f,
957  st__table * table)
958 {
959  DdNode *ft, *fe, *t, *e, *var, *res;
960  DdNode *one, *zero;
961  int index;
962  int comple = 0;
963 
964  statLine(ddD);
965  one = DD_ONE(ddD);
966  comple = Cudd_IsComplement(f);
967 
968  /* Trivial cases. */
969  if (Cudd_IsConstant(f)) return(Cudd_NotCond(one, comple));
970 
971  /* Make canonical to increase the utilization of the cache. */
972  f = Cudd_NotCond(f,comple);
973  /* Now f is a regular pointer to a non-constant node. */
974 
975  /* Check the cache. */
976  if ( st__lookup(table, (const char *)f, (char **)&res))
977  return(Cudd_NotCond(res,comple));
978 
979  if ( ddS->TimeStop && Abc_Clock() > ddS->TimeStop )
980  return NULL;
981  if ( ddD->TimeStop && Abc_Clock() > ddD->TimeStop )
982  return NULL;
983 
984  /* Recursive step. */
985  index = f->index;
986  ft = cuddT(f); fe = cuddE(f);
987 
988  t = cuddBddTransferRecur(ddS, ddD, ft, table);
989  if (t == NULL) {
990  return(NULL);
991  }
992  cuddRef(t);
993 
994  e = cuddBddTransferRecur(ddS, ddD, fe, table);
995  if (e == NULL) {
996  Cudd_RecursiveDeref(ddD, t);
997  return(NULL);
998  }
999  cuddRef(e);
1000 
1001  zero = Cudd_Not(one);
1002  var = cuddUniqueInter(ddD,index,one,zero);
1003  if (var == NULL) {
1004  Cudd_RecursiveDeref(ddD, t);
1005  Cudd_RecursiveDeref(ddD, e);
1006  return(NULL);
1007  }
1008  res = cuddBddIteRecur(ddD,var,t,e);
1009  if (res == NULL) {
1010  Cudd_RecursiveDeref(ddD, t);
1011  Cudd_RecursiveDeref(ddD, e);
1012  return(NULL);
1013  }
1014  cuddRef(res);
1015  Cudd_RecursiveDeref(ddD, t);
1016  Cudd_RecursiveDeref(ddD, e);
1017 
1018  if ( st__add_direct(table, (char *) f, (char *) res) == st__OUT_OF_MEM) {
1019  Cudd_RecursiveDeref(ddD, res);
1020  return(NULL);
1021  }
1022  return(Cudd_NotCond(res,comple));
1023 
1024 } /* end of cuddBddTransferRecur */
1025 
1026 
1028 
1029 
void st__free_table(st__table *table)
Definition: st.c:81
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
abctime TimeStop
Definition: cuddInt.h:489
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
void st__free_gen(st__generator *gen)
Definition: st.c:556
DdNode * cuddUniqueConst(DdManager *unique, CUDD_VALUE_TYPE value)
Definition: cuddTable.c:1450
int var(Lit p)
Definition: SolverTypes.h:62
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:222
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
DdNode * Cudd_addBddThreshold(DdManager *dd, DdNode *f, CUDD_VALUE_TYPE value)
Definition: cuddBridge.c:154
static ABC_NAMESPACE_IMPL_START char rcsid[] DD_UNUSED
Definition: cuddBridge.c:101
pcover complement(pcube *T)
Definition: compl.c:49
static DdNode * ddBddToAddRecur(DdManager *dd, DdNode *B)
Definition: cuddBridge.c:866
static abctime Abc_Clock()
Definition: abc_global.h:279
#define statLine(dd)
Definition: cuddInt.h:1037
#define cuddV(node)
Definition: cuddInt.h:668
static DdNode * addBddDoThreshold(DdManager *dd, DdNode *f, DdNode *val)
Definition: cuddBridge.c:570
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
DdNode * cuddBddTransfer(DdManager *ddS, DdManager *ddD, DdNode *f)
Definition: cuddBridge.c:443
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
int reordered
Definition: cuddInt.h:409
#define Cudd_IsComplement(node)
Definition: cudd.h:425
DdNode * Cudd_BddToAdd(DdManager *dd, DdNode *B)
Definition: cuddBridge.c:349
DdNode * Cudd_addBddStrictThreshold(DdManager *dd, DdNode *f, CUDD_VALUE_TYPE value)
Definition: cuddBridge.c:199
DdNode * cuddCacheLookup1(DdManager *table, DD_CTFP1 op, DdNode *f)
Definition: cuddCache.c:556
static DdNode * one
Definition: cuddDecomp.c:112
Definition: st.h:52
DdNode * cuddAddBddDoPattern(DdManager *dd, DdNode *f)
Definition: cuddBridge.c:493
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
#define cuddIsConstant(node)
Definition: cuddInt.h:620
DdNode * Cudd_addBddPattern(DdManager *dd, DdNode *f)
Definition: cuddBridge.c:379
static DdNode * addBddDoStrictThreshold(DdManager *dd, DdNode *f, DdNode *val)
Definition: cuddBridge.c:643
#define cuddT(node)
Definition: cuddInt.h:636
st__generator * st__init_gen(st__table *table)
Definition: st.c:486
#define st__OUT_OF_MEM
Definition: st.h:113
#define DD_ADD_BDD_DO_INTERVAL_TAG
Definition: cuddInt.h:176
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
#define CUDD_VALUE_TYPE
Definition: cudd.h:94
DdNode * Cudd_addBddIthBit(DdManager *dd, DdNode *f, int bit)
Definition: cuddBridge.c:306
static DdNode * addBddDoIthBit(DdManager *dd, DdNode *f, DdNode *index)
Definition: cuddBridge.c:790
DdHalfWord index
Definition: cudd.h:279
enum keys key
DdNode * Cudd_bddTransfer(DdManager *ddSource, DdManager *ddDestination, DdNode *f)
Definition: cuddBridge.c:409
DdNode * Cudd_addBddInterval(DdManager *dd, DdNode *f, CUDD_VALUE_TYPE lower, CUDD_VALUE_TYPE upper)
Definition: cuddBridge.c:244
#define cuddE(node)
Definition: cuddInt.h:652
int st__add_direct(st__table *table, char *key, char *value)
Definition: st.c:205
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
int value
#define DD_ONE(dd)
Definition: cuddInt.h:911
static DdNode * addBddDoInterval(DdManager *dd, DdNode *f, DdNode *l, DdNode *u)
Definition: cuddBridge.c:716
int st__ptrhash(const char *, int)
Definition: st.c:468
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
static DdNode * cuddBddTransferRecur(DdManager *ddS, DdManager *ddD, DdNode *f, st__table *table)
Definition: cuddBridge.c:953
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:369
int st__gen(st__generator *gen, const char **key_p, char **value_p)
Definition: st.c:502
void cuddCacheInsert1(DdManager *table, DD_CTFP1 op, DdNode *f, DdNode *data)
Definition: cuddCache.c:323
DdNode * cuddAddCmplRecur(DdManager *dd, DdNode *f)
Definition: cuddAddIte.c:562
#define DD_ZERO(dd)
Definition: cuddInt.h:927
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:633