1 /**CFile***********************************************************************
3 FileName [cuddZddIsop.c]
7 Synopsis [Functions to find irredundant SOP covers as ZDDs from BDDs.]
9 Description [External procedures included in this module:
13 <li> Cudd_MakeBddFromZddCover()
15 Internal procedures included in this module:
19 <li> cuddMakeBddFromZddCover()
21 Static procedures included in this module:
30 Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
34 Redistribution and use in source and binary forms, with or without
35 modification, are permitted provided that the following conditions
38 Redistributions of source code must retain the above copyright
39 notice, this list of conditions and the following disclaimer.
41 Redistributions in binary form must reproduce the above copyright
42 notice, this list of conditions and the following disclaimer in the
43 documentation and/or other materials provided with the distribution.
45 Neither the name of the University of Colorado nor the names of its
46 contributors may be used to endorse or promote products derived from
47 this software without specific prior written permission.
49 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
50 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
51 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
52 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
53 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
54 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
55 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
56 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
57 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
59 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
60 POSSIBILITY OF SUCH DAMAGE.]
62 ******************************************************************************/
67 /*---------------------------------------------------------------------------*/
68 /* Constant declarations */
69 /*---------------------------------------------------------------------------*/
72 /*---------------------------------------------------------------------------*/
73 /* Stucture declarations */
74 /*---------------------------------------------------------------------------*/
77 /*---------------------------------------------------------------------------*/
78 /* Type declarations */
79 /*---------------------------------------------------------------------------*/
82 /*---------------------------------------------------------------------------*/
83 /* Variable declarations */
84 /*---------------------------------------------------------------------------*/
87 static char rcsid
[] DD_UNUSED
= "$Id: cuddZddIsop.c,v 1.20 2009/02/19 16:26:12 fabio Exp $";
90 /*---------------------------------------------------------------------------*/
91 /* Macro declarations */
92 /*---------------------------------------------------------------------------*/
95 /**AutomaticStart*************************************************************/
97 /*---------------------------------------------------------------------------*/
98 /* Static function prototypes */
99 /*---------------------------------------------------------------------------*/
102 /**AutomaticEnd***************************************************************/
104 /*---------------------------------------------------------------------------*/
105 /* Definition of exported functions */
106 /*---------------------------------------------------------------------------*/
108 /**Function********************************************************************
110 Synopsis [Computes an ISOP in ZDD form from BDDs.]
112 Description [Computes an irredundant sum of products (ISOP) in ZDD
113 form from BDDs. The two BDDs L and U represent the lower bound and
114 the upper bound, respectively, of the function. The ISOP uses two
115 ZDD variables for each BDD variable: One for the positive literal,
116 and one for the negative literal. These two variables should be
117 adjacent in the ZDD order. The two ZDD variables corresponding to
118 BDD variable <code>i</code> should have indices <code>2i</code> and
119 <code>2i+1</code>. The result of this procedure depends on the
120 variable order. If successful, Cudd_zddIsop returns the BDD for
121 the function chosen from the interval. The ZDD representing the
122 irredundant cover is returned as a side effect in zdd_I. In case of
123 failure, NULL is returned.]
125 SideEffects [zdd_I holds the pointer to the ZDD for the ISOP on
128 SeeAlso [Cudd_bddIsop Cudd_zddVarsFromBddVars]
130 ******************************************************************************/
141 autoDynZ
= dd
->autoDynZ
;
146 res
= cuddZddIsop(dd
, L
, U
, zdd_I
);
147 } while (dd
->reordered
== 1);
148 dd
->autoDynZ
= autoDynZ
;
151 } /* end of Cudd_zddIsop */
154 /**Function********************************************************************
156 Synopsis [Computes a BDD in the interval between L and U with a
157 simple sum-of-produuct cover.]
159 Description [Computes a BDD in the interval between L and U with a
160 simple sum-of-produuct cover. This procedure is similar to
161 Cudd_zddIsop, but it does not return the ZDD for the cover. Returns
162 a pointer to the BDD if successful; NULL otherwise.]
166 SeeAlso [Cudd_zddIsop]
168 ******************************************************************************/
179 res
= cuddBddIsop(dd
, L
, U
);
180 } while (dd
->reordered
== 1);
183 } /* end of Cudd_bddIsop */
186 /**Function********************************************************************
188 Synopsis [Converts a ZDD cover to a BDD graph.]
190 Description [Converts a ZDD cover to a BDD graph. If successful, it
191 returns a BDD node, otherwise it returns NULL.]
195 SeeAlso [cuddMakeBddFromZddCover]
197 ******************************************************************************/
199 Cudd_MakeBddFromZddCover(
207 res
= cuddMakeBddFromZddCover(dd
, node
);
208 } while (dd
->reordered
== 1);
210 } /* end of Cudd_MakeBddFromZddCover */
213 /*---------------------------------------------------------------------------*/
214 /* Definition of internal functions */
215 /*---------------------------------------------------------------------------*/
218 /**Function********************************************************************
220 Synopsis [Performs the recursive step of Cudd_zddIsop.]
226 SeeAlso [Cudd_zddIsop]
228 ******************************************************************************/
236 DdNode
*one
= DD_ONE(dd
);
237 DdNode
*zero
= Cudd_Not(one
);
238 DdNode
*zdd_one
= DD_ONE(dd
);
239 DdNode
*zdd_zero
= DD_ZERO(dd
);
241 DdNode
*Lsub0
, *Usub0
, *Lsub1
, *Usub1
, *Ld
, *Ud
;
242 DdNode
*Lsuper0
, *Usuper0
, *Lsuper1
, *Usuper1
;
243 DdNode
*Isub0
, *Isub1
, *Id
;
244 DdNode
*zdd_Isub0
, *zdd_Isub1
, *zdd_Id
;
246 DdNode
*term0
, *term1
, *sum
;
247 DdNode
*Lv
, *Uv
, *Lnv
, *Unv
;
262 if (U
== zero
|| L
== one
) {
263 printf("*** ERROR : illegal condition for ISOP (U < L).\n");
267 /* Check the cache. We store two results for each recursive call.
268 ** One is the BDD, and the other is the ZDD. Both are needed.
269 ** Hence we need a double hit in the cache to terminate the
270 ** recursion. Clearly, collisions may evict only one of the two
272 cacheOp
= (DD_CTFP
) cuddZddIsop
;
273 r
= cuddCacheLookup2(dd
, cuddBddIsop
, L
, U
);
275 *zdd_I
= cuddCacheLookup2Zdd(dd
, cacheOp
, L
, U
);
279 /* The BDD result may have been dead. In that case
280 ** cuddCacheLookup2 would have called cuddReclaim,
281 ** whose effects we now have to undo. */
283 Cudd_RecursiveDeref(dd
, r
);
287 top_l
= dd
->perm
[Cudd_Regular(L
)->index
];
288 top_u
= dd
->perm
[Cudd_Regular(U
)->index
];
289 v
= ddMin(top_l
, top_u
);
291 /* Compute cofactors. */
293 index
= Cudd_Regular(L
)->index
;
296 if (Cudd_IsComplement(L
)) {
302 index
= Cudd_Regular(U
)->index
;
309 if (Cudd_IsComplement(U
)) {
318 Lsub0
= cuddBddAndRecur(dd
, Lnv
, Cudd_Not(Uv
));
323 Lsub1
= cuddBddAndRecur(dd
, Lv
, Cudd_Not(Unv
));
325 Cudd_RecursiveDeref(dd
, Lsub0
);
331 Isub0
= cuddZddIsop(dd
, Lsub0
, Usub0
, &zdd_Isub0
);
333 Cudd_RecursiveDeref(dd
, Lsub0
);
334 Cudd_RecursiveDeref(dd
, Lsub1
);
338 if ((!cuddIsConstant(Cudd_Regular(Isub0))) &&
339 (Cudd_Regular(Isub0)->index != zdd_Isub0->index / 2 ||
340 dd->permZ[index * 2] > dd->permZ[zdd_Isub0->index])) {
341 printf("*** ERROR : illegal permutation in ZDD. ***\n");
346 Isub1
= cuddZddIsop(dd
, Lsub1
, Usub1
, &zdd_Isub1
);
348 Cudd_RecursiveDeref(dd
, Lsub0
);
349 Cudd_RecursiveDeref(dd
, Lsub1
);
350 Cudd_RecursiveDeref(dd
, Isub0
);
351 Cudd_RecursiveDerefZdd(dd
, zdd_Isub0
);
355 if ((!cuddIsConstant(Cudd_Regular(Isub1))) &&
356 (Cudd_Regular(Isub1)->index != zdd_Isub1->index / 2 ||
357 dd->permZ[index * 2] > dd->permZ[zdd_Isub1->index])) {
358 printf("*** ERROR : illegal permutation in ZDD. ***\n");
363 Cudd_RecursiveDeref(dd
, Lsub0
);
364 Cudd_RecursiveDeref(dd
, Lsub1
);
366 Lsuper0
= cuddBddAndRecur(dd
, Lnv
, Cudd_Not(Isub0
));
367 if (Lsuper0
== NULL
) {
368 Cudd_RecursiveDeref(dd
, Isub0
);
369 Cudd_RecursiveDerefZdd(dd
, zdd_Isub0
);
370 Cudd_RecursiveDeref(dd
, Isub1
);
371 Cudd_RecursiveDerefZdd(dd
, zdd_Isub1
);
375 Lsuper1
= cuddBddAndRecur(dd
, Lv
, Cudd_Not(Isub1
));
376 if (Lsuper1
== NULL
) {
377 Cudd_RecursiveDeref(dd
, Isub0
);
378 Cudd_RecursiveDerefZdd(dd
, zdd_Isub0
);
379 Cudd_RecursiveDeref(dd
, Isub1
);
380 Cudd_RecursiveDerefZdd(dd
, zdd_Isub1
);
381 Cudd_RecursiveDeref(dd
, Lsuper0
);
388 /* Ld = Lsuper0 + Lsuper1 */
389 Ld
= cuddBddAndRecur(dd
, Cudd_Not(Lsuper0
), Cudd_Not(Lsuper1
));
391 Cudd_RecursiveDeref(dd
, Isub0
);
392 Cudd_RecursiveDerefZdd(dd
, zdd_Isub0
);
393 Cudd_RecursiveDeref(dd
, Isub1
);
394 Cudd_RecursiveDerefZdd(dd
, zdd_Isub1
);
395 Cudd_RecursiveDeref(dd
, Lsuper0
);
396 Cudd_RecursiveDeref(dd
, Lsuper1
);
401 /* Ud = Usuper0 * Usuper1 */
402 Ud
= cuddBddAndRecur(dd
, Usuper0
, Usuper1
);
404 Cudd_RecursiveDeref(dd
, Isub0
);
405 Cudd_RecursiveDerefZdd(dd
, zdd_Isub0
);
406 Cudd_RecursiveDeref(dd
, Isub1
);
407 Cudd_RecursiveDerefZdd(dd
, zdd_Isub1
);
408 Cudd_RecursiveDeref(dd
, Lsuper0
);
409 Cudd_RecursiveDeref(dd
, Lsuper1
);
410 Cudd_RecursiveDeref(dd
, Ld
);
414 Cudd_RecursiveDeref(dd
, Lsuper0
);
415 Cudd_RecursiveDeref(dd
, Lsuper1
);
417 Id
= cuddZddIsop(dd
, Ld
, Ud
, &zdd_Id
);
419 Cudd_RecursiveDeref(dd
, Isub0
);
420 Cudd_RecursiveDerefZdd(dd
, zdd_Isub0
);
421 Cudd_RecursiveDeref(dd
, Isub1
);
422 Cudd_RecursiveDerefZdd(dd
, zdd_Isub1
);
423 Cudd_RecursiveDeref(dd
, Ld
);
424 Cudd_RecursiveDeref(dd
, Ud
);
428 if ((!cuddIsConstant(Cudd_Regular(Id))) &&
429 (Cudd_Regular(Id)->index != zdd_Id->index / 2 ||
430 dd->permZ[index * 2] > dd->permZ[zdd_Id->index])) {
431 printf("*** ERROR : illegal permutation in ZDD. ***\n");
436 Cudd_RecursiveDeref(dd
, Ld
);
437 Cudd_RecursiveDeref(dd
, Ud
);
439 x
= cuddUniqueInter(dd
, index
, one
, zero
);
441 Cudd_RecursiveDeref(dd
, Isub0
);
442 Cudd_RecursiveDerefZdd(dd
, zdd_Isub0
);
443 Cudd_RecursiveDeref(dd
, Isub1
);
444 Cudd_RecursiveDerefZdd(dd
, zdd_Isub1
);
445 Cudd_RecursiveDeref(dd
, Id
);
446 Cudd_RecursiveDerefZdd(dd
, zdd_Id
);
450 /* term0 = x * Isub0 */
451 term0
= cuddBddAndRecur(dd
, Cudd_Not(x
), Isub0
);
453 Cudd_RecursiveDeref(dd
, Isub0
);
454 Cudd_RecursiveDerefZdd(dd
, zdd_Isub0
);
455 Cudd_RecursiveDeref(dd
, Isub1
);
456 Cudd_RecursiveDerefZdd(dd
, zdd_Isub1
);
457 Cudd_RecursiveDeref(dd
, Id
);
458 Cudd_RecursiveDerefZdd(dd
, zdd_Id
);
459 Cudd_RecursiveDeref(dd
, x
);
463 Cudd_RecursiveDeref(dd
, Isub0
);
464 /* term1 = x * Isub1 */
465 term1
= cuddBddAndRecur(dd
, x
, Isub1
);
467 Cudd_RecursiveDerefZdd(dd
, zdd_Isub0
);
468 Cudd_RecursiveDeref(dd
, Isub1
);
469 Cudd_RecursiveDerefZdd(dd
, zdd_Isub1
);
470 Cudd_RecursiveDeref(dd
, Id
);
471 Cudd_RecursiveDerefZdd(dd
, zdd_Id
);
472 Cudd_RecursiveDeref(dd
, x
);
473 Cudd_RecursiveDeref(dd
, term0
);
477 Cudd_RecursiveDeref(dd
, x
);
478 Cudd_RecursiveDeref(dd
, Isub1
);
479 /* sum = term0 + term1 */
480 sum
= cuddBddAndRecur(dd
, Cudd_Not(term0
), Cudd_Not(term1
));
482 Cudd_RecursiveDerefZdd(dd
, zdd_Isub0
);
483 Cudd_RecursiveDerefZdd(dd
, zdd_Isub1
);
484 Cudd_RecursiveDeref(dd
, Id
);
485 Cudd_RecursiveDerefZdd(dd
, zdd_Id
);
486 Cudd_RecursiveDeref(dd
, term0
);
487 Cudd_RecursiveDeref(dd
, term1
);
492 Cudd_RecursiveDeref(dd
, term0
);
493 Cudd_RecursiveDeref(dd
, term1
);
495 r
= cuddBddAndRecur(dd
, Cudd_Not(sum
), Cudd_Not(Id
));
496 r
= Cudd_NotCond(r
, r
!= NULL
);
498 Cudd_RecursiveDerefZdd(dd
, zdd_Isub0
);
499 Cudd_RecursiveDerefZdd(dd
, zdd_Isub1
);
500 Cudd_RecursiveDeref(dd
, Id
);
501 Cudd_RecursiveDerefZdd(dd
, zdd_Id
);
502 Cudd_RecursiveDeref(dd
, sum
);
506 Cudd_RecursiveDeref(dd
, sum
);
507 Cudd_RecursiveDeref(dd
, Id
);
509 if (zdd_Isub0
!= zdd_zero
) {
510 z
= cuddZddGetNodeIVO(dd
, index
* 2 + 1, zdd_Isub0
, zdd_Id
);
512 Cudd_RecursiveDerefZdd(dd
, zdd_Isub0
);
513 Cudd_RecursiveDerefZdd(dd
, zdd_Isub1
);
514 Cudd_RecursiveDerefZdd(dd
, zdd_Id
);
515 Cudd_RecursiveDeref(dd
, r
);
523 if (zdd_Isub1
!= zdd_zero
) {
524 y
= cuddZddGetNodeIVO(dd
, index
* 2, zdd_Isub1
, z
);
526 Cudd_RecursiveDerefZdd(dd
, zdd_Isub0
);
527 Cudd_RecursiveDerefZdd(dd
, zdd_Isub1
);
528 Cudd_RecursiveDerefZdd(dd
, zdd_Id
);
529 Cudd_RecursiveDeref(dd
, r
);
530 Cudd_RecursiveDerefZdd(dd
, z
);
538 Cudd_RecursiveDerefZdd(dd
, zdd_Isub0
);
539 Cudd_RecursiveDerefZdd(dd
, zdd_Isub1
);
540 Cudd_RecursiveDerefZdd(dd
, zdd_Id
);
541 Cudd_RecursiveDerefZdd(dd
, z
);
543 cuddCacheInsert2(dd
, cuddBddIsop
, L
, U
, r
);
544 cuddCacheInsert2(dd
, cacheOp
, L
, U
, y
);
550 if (Cudd_Regular(r)->index != y->index / 2) {
551 printf("*** ERROR : mismatch in indices between BDD and ZDD. ***\n");
556 } /* end of cuddZddIsop */
559 /**Function********************************************************************
561 Synopsis [Performs the recursive step of Cudd_bddIsop.]
567 SeeAlso [Cudd_bddIsop]
569 ******************************************************************************/
576 DdNode
*one
= DD_ONE(dd
);
577 DdNode
*zero
= Cudd_Not(one
);
579 DdNode
*Lsub0
, *Usub0
, *Lsub1
, *Usub1
, *Ld
, *Ud
;
580 DdNode
*Lsuper0
, *Usuper0
, *Lsuper1
, *Usuper1
;
581 DdNode
*Isub0
, *Isub1
, *Id
;
583 DdNode
*term0
, *term1
, *sum
;
584 DdNode
*Lv
, *Uv
, *Lnv
, *Unv
;
595 r
= cuddCacheLookup2(dd
, cuddBddIsop
, L
, U
);
599 top_l
= dd
->perm
[Cudd_Regular(L
)->index
];
600 top_u
= dd
->perm
[Cudd_Regular(U
)->index
];
601 v
= ddMin(top_l
, top_u
);
603 /* Compute cofactors */
605 index
= Cudd_Regular(L
)->index
;
608 if (Cudd_IsComplement(L
)) {
614 index
= Cudd_Regular(U
)->index
;
621 if (Cudd_IsComplement(U
)) {
630 Lsub0
= cuddBddAndRecur(dd
, Lnv
, Cudd_Not(Uv
));
635 Lsub1
= cuddBddAndRecur(dd
, Lv
, Cudd_Not(Unv
));
637 Cudd_RecursiveDeref(dd
, Lsub0
);
643 Isub0
= cuddBddIsop(dd
, Lsub0
, Usub0
);
645 Cudd_RecursiveDeref(dd
, Lsub0
);
646 Cudd_RecursiveDeref(dd
, Lsub1
);
650 Isub1
= cuddBddIsop(dd
, Lsub1
, Usub1
);
652 Cudd_RecursiveDeref(dd
, Lsub0
);
653 Cudd_RecursiveDeref(dd
, Lsub1
);
654 Cudd_RecursiveDeref(dd
, Isub0
);
658 Cudd_RecursiveDeref(dd
, Lsub0
);
659 Cudd_RecursiveDeref(dd
, Lsub1
);
661 Lsuper0
= cuddBddAndRecur(dd
, Lnv
, Cudd_Not(Isub0
));
662 if (Lsuper0
== NULL
) {
663 Cudd_RecursiveDeref(dd
, Isub0
);
664 Cudd_RecursiveDeref(dd
, Isub1
);
668 Lsuper1
= cuddBddAndRecur(dd
, Lv
, Cudd_Not(Isub1
));
669 if (Lsuper1
== NULL
) {
670 Cudd_RecursiveDeref(dd
, Isub0
);
671 Cudd_RecursiveDeref(dd
, Isub1
);
672 Cudd_RecursiveDeref(dd
, Lsuper0
);
679 /* Ld = Lsuper0 + Lsuper1 */
680 Ld
= cuddBddAndRecur(dd
, Cudd_Not(Lsuper0
), Cudd_Not(Lsuper1
));
681 Ld
= Cudd_NotCond(Ld
, Ld
!= NULL
);
683 Cudd_RecursiveDeref(dd
, Isub0
);
684 Cudd_RecursiveDeref(dd
, Isub1
);
685 Cudd_RecursiveDeref(dd
, Lsuper0
);
686 Cudd_RecursiveDeref(dd
, Lsuper1
);
690 Ud
= cuddBddAndRecur(dd
, Usuper0
, Usuper1
);
692 Cudd_RecursiveDeref(dd
, Isub0
);
693 Cudd_RecursiveDeref(dd
, Isub1
);
694 Cudd_RecursiveDeref(dd
, Lsuper0
);
695 Cudd_RecursiveDeref(dd
, Lsuper1
);
696 Cudd_RecursiveDeref(dd
, Ld
);
700 Cudd_RecursiveDeref(dd
, Lsuper0
);
701 Cudd_RecursiveDeref(dd
, Lsuper1
);
703 Id
= cuddBddIsop(dd
, Ld
, Ud
);
705 Cudd_RecursiveDeref(dd
, Isub0
);
706 Cudd_RecursiveDeref(dd
, Isub1
);
707 Cudd_RecursiveDeref(dd
, Ld
);
708 Cudd_RecursiveDeref(dd
, Ud
);
712 Cudd_RecursiveDeref(dd
, Ld
);
713 Cudd_RecursiveDeref(dd
, Ud
);
715 x
= cuddUniqueInter(dd
, index
, one
, zero
);
717 Cudd_RecursiveDeref(dd
, Isub0
);
718 Cudd_RecursiveDeref(dd
, Isub1
);
719 Cudd_RecursiveDeref(dd
, Id
);
723 term0
= cuddBddAndRecur(dd
, Cudd_Not(x
), Isub0
);
725 Cudd_RecursiveDeref(dd
, Isub0
);
726 Cudd_RecursiveDeref(dd
, Isub1
);
727 Cudd_RecursiveDeref(dd
, Id
);
728 Cudd_RecursiveDeref(dd
, x
);
732 Cudd_RecursiveDeref(dd
, Isub0
);
733 term1
= cuddBddAndRecur(dd
, x
, Isub1
);
735 Cudd_RecursiveDeref(dd
, Isub1
);
736 Cudd_RecursiveDeref(dd
, Id
);
737 Cudd_RecursiveDeref(dd
, x
);
738 Cudd_RecursiveDeref(dd
, term0
);
742 Cudd_RecursiveDeref(dd
, x
);
743 Cudd_RecursiveDeref(dd
, Isub1
);
744 /* sum = term0 + term1 */
745 sum
= cuddBddAndRecur(dd
, Cudd_Not(term0
), Cudd_Not(term1
));
746 sum
= Cudd_NotCond(sum
, sum
!= NULL
);
748 Cudd_RecursiveDeref(dd
, Id
);
749 Cudd_RecursiveDeref(dd
, term0
);
750 Cudd_RecursiveDeref(dd
, term1
);
754 Cudd_RecursiveDeref(dd
, term0
);
755 Cudd_RecursiveDeref(dd
, term1
);
757 r
= cuddBddAndRecur(dd
, Cudd_Not(sum
), Cudd_Not(Id
));
758 r
= Cudd_NotCond(r
, r
!= NULL
);
760 Cudd_RecursiveDeref(dd
, Id
);
761 Cudd_RecursiveDeref(dd
, sum
);
765 Cudd_RecursiveDeref(dd
, sum
);
766 Cudd_RecursiveDeref(dd
, Id
);
768 cuddCacheInsert2(dd
, cuddBddIsop
, L
, U
, r
);
773 } /* end of cuddBddIsop */
776 /**Function********************************************************************
778 Synopsis [Converts a ZDD cover to a BDD graph.]
780 Description [Converts a ZDD cover to a BDD graph. If successful, it
781 returns a BDD node, otherwise it returns NULL. It is a recursive
782 algorithm as the following. First computes 3 cofactors of a ZDD cover;
783 f1, f0 and fd. Second, compute BDDs(b1, b0 and bd) of f1, f0 and fd.
784 Third, compute T=b1+bd and E=b0+bd. Fourth, compute ITE(v,T,E) where v
785 is the variable which has the index of the top node of the ZDD cover.
786 In this case, since the index of v can be larger than either one of T or
787 one of E, cuddUniqueInterIVO is called, here IVO stands for
788 independent variable ordering.]
792 SeeAlso [Cudd_MakeBddFromZddCover]
794 ******************************************************************************/
796 cuddMakeBddFromZddCover(
802 DdNode
*f1
, *f0
, *fd
;
803 DdNode
*b1
, *b0
, *bd
;
809 if (node
== dd
->zero
)
810 return(Cudd_Not(dd
->one
));
813 neW
= cuddCacheLookup1(dd
, cuddMakeBddFromZddCover
, node
);
817 v
= Cudd_Regular(node
)->index
; /* either yi or zi */
818 if (cuddZddGetCofactors3(dd
, node
, v
, &f1
, &f0
, &fd
)) return(NULL
);
823 b1
= cuddMakeBddFromZddCover(dd
, f1
);
825 Cudd_RecursiveDerefZdd(dd
, f1
);
826 Cudd_RecursiveDerefZdd(dd
, f0
);
827 Cudd_RecursiveDerefZdd(dd
, fd
);
831 b0
= cuddMakeBddFromZddCover(dd
, f0
);
833 Cudd_RecursiveDerefZdd(dd
, f1
);
834 Cudd_RecursiveDerefZdd(dd
, f0
);
835 Cudd_RecursiveDerefZdd(dd
, fd
);
836 Cudd_RecursiveDeref(dd
, b1
);
840 Cudd_RecursiveDerefZdd(dd
, f1
);
841 Cudd_RecursiveDerefZdd(dd
, f0
);
842 if (fd
!= dd
->zero
) {
843 bd
= cuddMakeBddFromZddCover(dd
, fd
);
845 Cudd_RecursiveDerefZdd(dd
, fd
);
846 Cudd_RecursiveDeref(dd
, b1
);
847 Cudd_RecursiveDeref(dd
, b0
);
851 Cudd_RecursiveDerefZdd(dd
, fd
);
853 T
= cuddBddAndRecur(dd
, Cudd_Not(b1
), Cudd_Not(bd
));
855 Cudd_RecursiveDeref(dd
, b1
);
856 Cudd_RecursiveDeref(dd
, b0
);
857 Cudd_RecursiveDeref(dd
, bd
);
860 T
= Cudd_NotCond(T
, T
!= NULL
);
862 Cudd_RecursiveDeref(dd
, b1
);
863 E
= cuddBddAndRecur(dd
, Cudd_Not(b0
), Cudd_Not(bd
));
865 Cudd_RecursiveDeref(dd
, b0
);
866 Cudd_RecursiveDeref(dd
, bd
);
867 Cudd_RecursiveDeref(dd
, T
);
870 E
= Cudd_NotCond(E
, E
!= NULL
);
872 Cudd_RecursiveDeref(dd
, b0
);
873 Cudd_RecursiveDeref(dd
, bd
);
876 Cudd_RecursiveDerefZdd(dd
, fd
);
881 if (Cudd_IsComplement(T
)) {
882 neW
= cuddUniqueInterIVO(dd
, v
/ 2, Cudd_Not(T
), Cudd_Not(E
));
884 Cudd_RecursiveDeref(dd
, T
);
885 Cudd_RecursiveDeref(dd
, E
);
891 neW
= cuddUniqueInterIVO(dd
, v
/ 2, T
, E
);
893 Cudd_RecursiveDeref(dd
, T
);
894 Cudd_RecursiveDeref(dd
, E
);
899 Cudd_RecursiveDeref(dd
, T
);
900 Cudd_RecursiveDeref(dd
, E
);
902 cuddCacheInsert1(dd
, cuddMakeBddFromZddCover
, node
, neW
);
906 } /* end of cuddMakeBddFromZddCover */
909 /*---------------------------------------------------------------------------*/
910 /* Definition of static functions */
911 /*---------------------------------------------------------------------------*/