source: vis_dev/glu-2.3/src/cuPort/cuPort.c@ 28

Last change on this file since 28 was 21, checked in by cecile, 15 years ago

un delete de trop

File size: 195.5 KB
Line 
1/**CFile***********************************************************************
2
3 FileName [cuPort.c]
4
5 PackageName [cudd]
6
7 Synopsis [SIS/VIS interface to the Decision Diagram Package of the University
8 of Colorado.]
9
10 Description [This file implements an interface between the functions in the
11 Berkeley BDD package and the functions provided by the CUDD (decision
12 diagram) package from the University of Colorado. The CUDD package is a
13 generic implementation of a decision diagram data structure. For the time
14 being, only Boole expansion is implemented and the leaves in the in the
15 nodes can be the constants zero, one or any arbitrary value.]
16
17 Author [Abelardo Pardo, Kavita Ravi]
18
19 Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
20
21 All rights reserved.
22
23 Redistribution and use in source and binary forms, with or without
24 modification, are permitted provided that the following conditions
25 are met:
26
27 Redistributions of source code must retain the above copyright
28 notice, this list of conditions and the following disclaimer.
29
30 Redistributions in binary form must reproduce the above copyright
31 notice, this list of conditions and the following disclaimer in the
32 documentation and/or other materials provided with the distribution.
33
34 Neither the name of the University of Colorado nor the names of its
35 contributors may be used to endorse or promote products derived from
36 this software without specific prior written permission.
37
38 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
39 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
40 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
41 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
42 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
43 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
44 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
46 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
47 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
48 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49 POSSIBILITY OF SUCH DAMAGE.]
50
51******************************************************************************/
52
53#include "cuPortInt.h"
54
55/*---------------------------------------------------------------------------*/
56/* Constant declarations */
57/*---------------------------------------------------------------------------*/
58
59
60/*---------------------------------------------------------------------------*/
61/* Type declarations */
62/*---------------------------------------------------------------------------*/
63
64
65/*---------------------------------------------------------------------------*/
66/* Structure declarations */
67/*---------------------------------------------------------------------------*/
68
69
70/*---------------------------------------------------------------------------*/
71/* Variable declarations */
72/*---------------------------------------------------------------------------*/
73
74#ifndef lint
75static char rcsid[] DD_UNUSED = "$Id: cuPort.c,v 1.132 2009/04/11 23:44:57 fabio Exp $";
76#endif
77
78/*---------------------------------------------------------------------------*/
79/* Macro declarations */
80/*---------------------------------------------------------------------------*/
81
82
83/**AutomaticStart*************************************************************/
84
85/*---------------------------------------------------------------------------*/
86/* Static function prototypes */
87/*---------------------------------------------------------------------------*/
88
89static void InvalidType( FILE *file, const char *field, const char *expected);
90
91
92/**AutomaticEnd***************************************************************/
93
94/*---------------------------------------------------------------------------*/
95/* Definition of exported functions */
96/*---------------------------------------------------------------------------*/
97
98/**Function********************************************************************
99
100 Synopsis [Builds the bdd_t structure.]
101
102 Description [Builds the bdd_t structure from manager and node.
103 Assumes that the reference count of the node has already been
104 increased. If it fails to create a new bdd_t structure it disposes of
105 the node to simplify error handling for the caller. Returns a
106 pointer to the newly created structure if successful; NULL
107 otherwise.]
108
109 SideEffects []
110
111******************************************************************************/
112bdd_t *
113bdd_construct_bdd_t(bdd_manager *mgr, bdd_node *fn)
114{
115 bdd_t *result;
116
117 result = ALLOC(bdd_t, 1);
118 if (result == NULL) {
119 Cudd_RecursiveDeref((DdManager *)mgr,(DdNode *)fn);
120 return(NULL);
121 }
122 result->mgr = (DdManager *) mgr;
123 result->node = (DdNode *) fn;
124 result->free = FALSE;
125 return(result);
126
127} /* end of bdd_construct_bdd_t */
128
129
130/**Function********************************************************************
131
132 Synopsis [Function to identify the bdd package being used]
133
134 SideEffects []
135
136******************************************************************************/
137bdd_package_type_t
138bdd_get_package_name(void)
139{
140 return(CUDD);
141
142} /* end of bdd_get_package_name */
143
144
145/**Function********************************************************************
146
147 Synopsis [Terminates the bdd package.]
148
149 SideEffects []
150
151******************************************************************************/
152void
153bdd_end(bdd_manager *mgr)
154{
155 DdManager *manager;
156
157 manager = (DdManager *)mgr;
158 if (manager->hooks != NULL) FREE(manager->hooks);
159 Cudd_Quit(manager);
160
161} /* end of bdd_end */
162
163
164/**Function********************************************************************
165
166 Synopsis [Starts the manager with nvariables variables.]
167
168 SideEffects []
169
170******************************************************************************/
171bdd_manager *
172bdd_start(int nvariables)
173{
174 DdManager *mgr;
175 bdd_external_hooks *hooks;
176
177 mgr = Cudd_Init((unsigned int)nvariables, 0, CUDD_UNIQUE_SLOTS,
178 CUDD_CACHE_SLOTS, getSoftDataLimit() / 10 * 9);
179
180 hooks = ALLOC(bdd_external_hooks,1);
181 hooks->mdd = hooks->network = hooks->undef1 = (char *) 0;
182 mgr->hooks = (char *) hooks;
183
184 return(bdd_manager *)mgr;
185
186} /* end of bdd_start */
187
188
189/**Function********************************************************************
190
191 Synopsis [Creates a new variable in the manager.]
192
193 SideEffects [Modifies the manager]
194
195 SeeAlso [bdd_create_variable_after]
196
197******************************************************************************/
198bdd_t *
199bdd_create_variable(bdd_manager *mgr)
200{
201 DdNode *var;
202 DdManager *dd = (DdManager *) mgr;
203 DdNode *one = DD_ONE(dd);
204
205 if (dd->size >= CUDD_MAXINDEX -1) return(NULL);
206 do {
207 dd->reordered = 0;
208 var = cuddUniqueInter(dd,dd->size,one,Cudd_Not(one));
209 } while (dd->reordered == 1);
210
211 if (var == NULL) return((bdd_t *)NULL);
212 cuddRef(var);
213 return(bdd_construct_bdd_t(dd,var));
214
215} /* end of bdd_create_variable */
216
217
218/**Function********************************************************************
219
220 Synopsis [Creates a new variable and positions it after the
221 variable with the specified index.]
222
223 SideEffects [Modifies the manager.]
224
225 SeeAlso [bdd_create_variable]
226
227******************************************************************************/
228bdd_t *
229bdd_create_variable_after(bdd_manager *mgr, bdd_variableId after_id)
230{
231 DdNode *var;
232 DdManager *dd = (DdManager *) mgr;
233 int level;
234
235 if (after_id >= (bdd_variableId) dd->size) return(NULL);
236 level = 1 + dd->perm[after_id];
237 var = Cudd_bddNewVarAtLevel(dd,level);
238 if (var == NULL) return((bdd_t *)NULL);
239 cuddRef(var);
240 return(bdd_construct_bdd_t(dd,var));
241
242} /* end of bdd_create_variable_after */
243
244
245/**Function********************************************************************
246
247 Synopsis [Returns the BDD representing the variable with given ID.]
248
249 SideEffects []
250
251******************************************************************************/
252bdd_t *
253bdd_get_variable(bdd_manager *mgr, bdd_variableId variable_ID)
254{
255 DdNode *var;
256 DdManager *dd = (DdManager *) mgr;
257 DdNode *one = DD_ONE(dd);
258
259 if (variable_ID >= CUDD_MAXINDEX -1) return(NULL);
260 do {
261 dd->reordered = 0;
262 var = cuddUniqueInter(dd,(int)variable_ID,one,Cudd_Not(one));
263 } while (dd->reordered == 1);
264
265 if (var == NULL) return((bdd_t *)NULL);
266 cuddRef(var);
267 return(bdd_construct_bdd_t(dd,var));
268
269} /* end of bdd_get_variable */
270
271
272/**Function********************************************************************
273
274 Synopsis [Creates a copy of the BDD.]
275
276 SideEffects []
277
278******************************************************************************/
279bdd_t *
280bdd_dup(bdd_t *f)
281{
282 cuddRef(f->node);
283 return(bdd_construct_bdd_t(f->mgr,f->node));
284
285} /* end of bdd_dup */
286
287
288/**Function********************************************************************
289
290 Synopsis [Deletes the BDD of f.]
291
292 SideEffects []
293
294******************************************************************************/
295void
296bdd_free(bdd_t *f)
297{
298 if (f == NULL) {
299 fail("bdd_free: trying to free a NULL bdd_t");
300 }
301
302 if (f->free == TRUE) {
303 fail("bdd_free: trying to free a freed bdd_t");
304 }
305
306 Cudd_RecursiveDeref(f->mgr,f->node);
307 /* This is a bit overconservative. */
308 f->node = NULL;
309 f->mgr = NULL;
310 f->free = TRUE;
311 FREE(f);
312 return;
313
314} /* end of bdd_free */
315
316
317/**Function********************************************************************
318
319 Synopsis [And of two BDDs.]
320
321 SideEffects []
322
323******************************************************************************/
324bdd_t *
325bdd_and(
326 bdd_t *f,
327 bdd_t *g,
328 boolean f_phase,
329 boolean g_phase)
330{
331 DdManager *dd;
332 DdNode *newf, *newg, *fandg;
333
334 /* Make sure both BDDs belong to the same manager. */
335 assert(f->mgr == g->mgr);
336
337 /* Modify the phases of the operands according to the parameters. */
338 newf = Cudd_NotCond(f->node,!f_phase);
339 newg = Cudd_NotCond(g->node,!g_phase);
340
341 /* Perform the AND operation. */
342 dd = f->mgr;
343 fandg = Cudd_bddAnd(f->mgr,newf,newg);
344 if (fandg == NULL) return(NULL);
345 cuddRef(fandg);
346
347 return(bdd_construct_bdd_t(dd,fandg));
348
349} /* end of bdd_and */
350
351
352/**Function********************************************************************
353
354 Synopsis [And of two BDDs with limit on new nodes.]
355
356 Description [If more new nodes than specified by limit must be created,
357 this function returns NULL. The caller must be prepared for this
358 occurrence.]
359
360 SideEffects []
361
362******************************************************************************/
363bdd_t *
364bdd_and_with_limit(
365 bdd_t *f,
366 bdd_t *g,
367 boolean f_phase,
368 boolean g_phase,
369 unsigned int limit)
370{
371 DdManager *dd;
372 DdNode *newf, *newg, *fandg;
373
374 /* Make sure both BDDs belong to the same manager. */
375 assert(f->mgr == g->mgr);
376
377 /* Modify the phases of the operands according to the parameters. */
378 newf = Cudd_NotCond(f->node,!f_phase);
379 newg = Cudd_NotCond(g->node,!g_phase);
380
381 /* Perform the AND operation. */
382 dd = f->mgr;
383 fandg = Cudd_bddAndLimit(f->mgr,newf,newg,limit);
384 if (fandg == NULL) return(NULL);
385 cuddRef(fandg);
386
387 return(bdd_construct_bdd_t(dd,fandg));
388
389} /* end of bdd_and_with_limit */
390
391
392/**Function********************************************************************
393
394 Synopsis [And of a BDD and an array of BDDs.]
395
396 SideEffects []
397
398******************************************************************************/
399bdd_t *
400bdd_and_array(
401 bdd_t *f,
402 array_t *g_array,
403 boolean f_phase,
404 boolean g_phase)
405{
406 bdd_t *g;
407 DdNode *result, *temp;
408 int i;
409 DdNode *newf, *newg;
410
411 /* Modify the phases of the operands according to the parameters. */
412 newf = Cudd_NotCond(f->node,!f_phase);
413
414 Cudd_Ref(result = newf);
415
416 for (i = 0; i < array_n(g_array); i++) {
417 g = array_fetch(bdd_t *, g_array, i);
418
419 /* Modify the phases of the operands according to the parameters. */
420 newg = Cudd_NotCond(g->node,!g_phase);
421
422 temp = Cudd_bddAnd(f->mgr, result, newg);
423 if (temp == NULL) {
424 Cudd_RecursiveDeref(f->mgr, result);
425 return(NULL);
426 }
427 cuddRef(temp);
428 Cudd_RecursiveDeref(f->mgr, result);
429 result = temp;
430 }
431
432 return(bdd_construct_bdd_t(f->mgr,result));
433
434} /* end of bdd_and_array */
435
436
437/**Function********************************************************************
438
439 Synopsis [Takes the and of an array of functions.]
440
441 SideEffects [None]
442
443******************************************************************************/
444bdd_t *
445bdd_multiway_and(bdd_manager *manager, array_t *bddArray)
446{
447 DdManager *mgr;
448 bdd_t *operand;
449 DdNode *result, *temp;
450 int i;
451
452 mgr = (DdManager *)manager;
453
454 Cudd_Ref(result = DD_ONE(mgr));
455
456 for (i = 0; i < array_n(bddArray); i++) {
457 operand = array_fetch(bdd_t *, bddArray, i);
458 temp = Cudd_bddAnd(mgr, result, operand->node);
459 if (temp == NULL) {
460 Cudd_RecursiveDeref(mgr, result);
461 return(NULL);
462 }
463 cuddRef(temp);
464 Cudd_RecursiveDeref(mgr, result);
465 result = temp;
466 }
467
468 return(bdd_construct_bdd_t(mgr,result));
469
470} /* end of bdd_multiway_and */
471
472
473/**Function********************************************************************
474
475 Synopsis [Takes the or of an array of functions.]
476
477 SideEffects []
478
479******************************************************************************/
480bdd_t *
481bdd_multiway_or(bdd_manager *manager, array_t *bddArray)
482{
483 DdManager *mgr;
484 bdd_t *operand;
485 DdNode *result, *temp;
486 int i;
487
488 mgr = (DdManager *)manager;
489 Cudd_Ref(result = Cudd_Not(DD_ONE(mgr)));
490
491 for (i = 0; i < array_n(bddArray); i++) {
492 operand = array_fetch(bdd_t *, bddArray, i);
493 temp = Cudd_bddOr(mgr, result, operand->node);
494 if (temp == NULL) {
495 Cudd_RecursiveDeref(mgr, result);
496 return(NULL);
497 }
498 cuddRef(temp);
499 Cudd_RecursiveDeref(mgr, result);
500 result = temp;
501 }
502
503 return(bdd_construct_bdd_t(mgr,result));
504
505} /* end of bdd_multiway_or */
506
507
508/**Function********************************************************************
509
510 Synopsis [Takes the xor of an array of functions.]
511
512 SideEffects [None]
513
514******************************************************************************/
515bdd_t *
516bdd_multiway_xor(bdd_manager *manager, array_t *bddArray)
517{
518 DdManager *mgr;
519 bdd_t *operand;
520 DdNode *result, *temp;
521 int i;
522
523 mgr = (DdManager *)manager;
524
525 Cudd_Ref(result = Cudd_Not(DD_ONE(mgr)));
526
527 for (i = 0; i < array_n(bddArray); i++) {
528 operand = array_fetch(bdd_t *, bddArray, i);
529 temp = Cudd_bddXor(mgr, result, operand->node);
530 if (temp == NULL) {
531 Cudd_RecursiveDeref(mgr, result);
532 return(NULL);
533 }
534 cuddRef(temp);
535 Cudd_RecursiveDeref(mgr, result);
536 result = temp;
537 }
538
539 return(bdd_construct_bdd_t(mgr,result));
540
541} /* end of bdd_multiway_xor */
542
543
544/**Function********************************************************************
545
546 Synopsis [Takes the pairwise or of two arrays of bdds of the same length.]
547
548 SideEffects [None]
549
550******************************************************************************/
551array_t *
552bdd_pairwise_or(bdd_manager *manager, array_t *bddArray1, array_t *bddArray2)
553{
554 DdManager *mgr;
555 bdd_t *op1, *op2;
556 bdd_t *unit;
557 DdNode *result;
558 array_t *resultArray;
559 int i;
560
561 mgr = (DdManager *)manager;
562
563 if (array_n(bddArray1) != array_n(bddArray2)) {
564 (void) fprintf(stderr,
565 "bdd_pairwise_or: Arrays of different lengths.\n");
566 return(NULL);
567 }
568
569 resultArray = array_alloc(bdd_t *, array_n(bddArray1));
570 for (i = 0; i < array_n(bddArray1); i++) {
571 op1 = array_fetch(bdd_t *, bddArray1, i);
572 op2 = array_fetch(bdd_t *, bddArray2, i);
573
574 result = Cudd_bddOr(mgr, op1->node, op2->node);
575 if (result == NULL) {
576 int j;
577 bdd_t *item;
578 for (j = 0; j < array_n(resultArray); j++) {
579 item = array_fetch(bdd_t *, resultArray, j);
580 bdd_free(item);
581 }
582 array_free(resultArray);
583 return((array_t *)NULL);
584 }
585 cuddRef(result);
586
587 unit = bdd_construct_bdd_t(mgr, result);
588 array_insert(bdd_t *, resultArray, i, unit);
589 }
590
591 return(resultArray);
592
593} /* end of bdd_pairwise_or */
594
595
596/**Function********************************************************************
597
598 Synopsis [Takes the pairwise and of two arrays of bdds of the same length.]
599
600 SideEffects [required]
601
602******************************************************************************/
603array_t *
604bdd_pairwise_and(bdd_manager *manager, array_t *bddArray1, array_t *bddArray2)
605{
606 DdManager *mgr;
607 bdd_t *op1, *op2;
608 bdd_t *unit;
609 DdNode *result;
610 array_t *resultArray;
611 int i;
612
613 mgr = (DdManager *)manager;
614
615 if (array_n(bddArray1) != array_n(bddArray2)) {
616 (void) fprintf(stderr,
617 "bdd_pairwise_or: Arrays of different lengths.\n");
618 return(NULL);
619 }
620
621 resultArray = array_alloc(bdd_t *, array_n(bddArray1));
622 for (i = 0; i < array_n(bddArray1); i++) {
623 op1 = array_fetch(bdd_t *, bddArray1, i);
624 op2 = array_fetch(bdd_t *, bddArray2, i);
625
626 result = Cudd_bddAnd(mgr, op1->node, op2->node);
627 if (result == NULL) {
628 int j;
629 bdd_t *item;
630 for (j = 0; j < array_n(resultArray); j++) {
631 item = array_fetch(bdd_t *, resultArray, j);
632 bdd_free(item);
633 }
634 array_free(resultArray);
635 return((array_t *)NULL);
636 }
637 cuddRef(result);
638
639 unit = bdd_construct_bdd_t(mgr, result);
640 array_insert(bdd_t *, resultArray, i, unit);
641 }
642
643 return(resultArray);
644
645} /* end of bdd_pairwise_and */
646
647
648/**Function********************************************************************
649
650 Synopsis [Takes the pairwise xor of two arrays of bdds of the same length.]
651
652 SideEffects [required]
653
654******************************************************************************/
655array_t *
656bdd_pairwise_xor(bdd_manager *manager, array_t *bddArray1, array_t *bddArray2)
657{
658 DdManager *mgr;
659 bdd_t *op1, *op2;
660 bdd_t *unit;
661 DdNode *result;
662 array_t *resultArray;
663 int i;
664
665 mgr = (DdManager *)manager;
666
667 if (array_n(bddArray1) != array_n(bddArray2)) {
668 (void) fprintf(stderr,
669 "bdd_pairwise_or: Arrays of different lengths.\n");
670 return(NULL);
671 }
672
673 resultArray = array_alloc(bdd_t *, array_n(bddArray1));
674 for (i = 0; i < array_n(bddArray1); i++) {
675 op1 = array_fetch(bdd_t *, bddArray1, i);
676 op2 = array_fetch(bdd_t *, bddArray2, i);
677
678 result = Cudd_bddXor(mgr, op1->node, op2->node);
679 if (result == NULL) {
680 int j;
681 bdd_t *item;
682 for (j = 0; j < array_n(resultArray); j++) {
683 item = array_fetch(bdd_t *, resultArray, j);
684 bdd_free(item);
685 }
686 array_free(resultArray);
687 return((array_t *)NULL);
688 }
689 cuddRef(result);
690
691 unit = bdd_construct_bdd_t(mgr, result);
692 array_insert(bdd_t *, resultArray, i, unit);
693 }
694
695 return(resultArray);
696
697} /* end of bdd_pairwise_xor */
698
699
700/**Function********************************************************************
701
702 Synopsis [Abstracts variables from the product of two BDDs.]
703
704 SideEffects []
705
706******************************************************************************/
707bdd_t *
708bdd_and_smooth(
709 bdd_t *f,
710 bdd_t *g,
711 array_t *smoothing_vars /* of bdd_t *'s */)
712{
713 int i;
714 bdd_t *variable;
715 DdNode *cube, *tmpDd, *result;
716 DdManager *mgr;
717
718 /* Make sure both operands belong to the same manager. */
719 assert(f->mgr == g->mgr);
720
721 /* CUDD needs the smoothing variables passed as a cube.
722 * Therefore we must build that cube from the indices of variables
723 * in the array before calling the procedure.
724 */
725 mgr = f->mgr;
726 Cudd_Ref(cube = DD_ONE(mgr));
727 for (i = 0; i < array_n(smoothing_vars); i++) {
728 variable = array_fetch(bdd_t *,smoothing_vars,i);
729
730 /* Make sure the variable belongs to the same manager. */
731 assert(mgr == variable->mgr);
732
733 tmpDd = Cudd_bddAnd(mgr,cube,variable->node);
734 if (tmpDd == NULL) {
735 Cudd_RecursiveDeref(mgr,cube);
736 return(NULL);
737 }
738 cuddRef(tmpDd);
739 Cudd_RecursiveDeref(mgr, cube);
740 cube = tmpDd;
741 }
742
743 /* Perform the smoothing */
744 result = Cudd_bddAndAbstract(mgr,f->node,g->node,cube);
745 if (result == NULL) {
746 Cudd_RecursiveDeref(mgr, cube);
747 return(NULL);
748 }
749 cuddRef(result);
750 /* Get rid of temporary results. */
751 Cudd_RecursiveDeref(mgr, cube);
752
753 /* Build the bdd_t structure for the result */
754 return(bdd_construct_bdd_t(mgr,result));
755
756} /* end of bdd_and_smooth */
757
758
759/**Function********************************************************************
760
761 Synopsis [Abstracts variables from the product of two BDDs with limit
762 on new nodes.]
763
764 Description [If more new nodes than specified by limit must be created,
765 this function returns NULL. The caller must be prepared for this
766 occurrence.]
767
768 SideEffects []
769
770******************************************************************************/
771bdd_t *
772bdd_and_smooth_with_limit(
773 bdd_t *f,
774 bdd_t *g,
775 array_t *smoothing_vars /* of bdd_t *'s */,
776 unsigned int limit)
777{
778 int i;
779 bdd_t *variable;
780 DdNode *cube, *tmpDd, *result;
781 DdManager *mgr;
782
783 /* Make sure both operands belong to the same manager. */
784 assert(f->mgr == g->mgr);
785
786 /* CUDD needs the smothing variables passed as a cube.
787 * Therefore we must build that cube from the indices of variables
788 * in the array before calling the procedure.
789 */
790 mgr = f->mgr;
791 Cudd_Ref(cube = DD_ONE(mgr));
792 for (i = 0; i < array_n(smoothing_vars); i++) {
793 variable = array_fetch(bdd_t *,smoothing_vars,i);
794
795 /* Make sure the variable belongs to the same manager. */
796 assert(mgr == variable->mgr);
797
798 tmpDd = Cudd_bddAnd(mgr,cube,variable->node);
799 if (tmpDd == NULL) {
800 Cudd_RecursiveDeref(mgr,cube);
801 return(NULL);
802 }
803 cuddRef(tmpDd);
804 Cudd_RecursiveDeref(mgr, cube);
805 cube = tmpDd;
806 }
807
808 /* Perform the smoothing */
809 result = Cudd_bddAndAbstractLimit(mgr,f->node,g->node,cube,limit);
810 if (result == NULL) {
811 Cudd_RecursiveDeref(mgr, cube);
812 return(NULL);
813 }
814 cuddRef(result);
815 /* Get rid of temporary results. */
816 Cudd_RecursiveDeref(mgr, cube);
817
818 /* Build the bdd_t structure for the result */
819 return(bdd_construct_bdd_t(mgr,result));
820
821} /* end of bdd_and_smooth_with_limit */
822
823
824/**Function********************************************************************
825
826 Synopsis [Abstracts variables from the product of two BDDs.]
827
828 SideEffects []
829
830******************************************************************************/
831bdd_t *
832bdd_and_smooth_with_cube(bdd_t *f, bdd_t *g, bdd_t *cube)
833{
834 DdNode *result;
835 DdManager *mgr;
836
837 /* Make sure both operands belong to the same manager. */
838 assert(f->mgr == g->mgr);
839
840 /* The Boulder package needs the smothing variables passed as a cube.
841 * Therefore we must build that cube from the indices of variables
842 * in the array before calling the procedure.
843 */
844 mgr = f->mgr;
845
846 /* Perform the smoothing */
847 result = Cudd_bddAndAbstract(mgr,f->node,g->node,cube->node);
848 if (result == NULL)
849 return(NULL);
850 cuddRef(result);
851
852 /* Build the bdd_t structure for the result */
853 return(bdd_construct_bdd_t(mgr,result));
854
855} /* end of bdd_and_smooth_with_cube */
856
857
858/**Function********************************************************************
859
860 Synopsis [Abstracts variables from the product of two
861 BDDs. Computation is clipped at a certain depth.]
862
863 Description [Abstracts variables from the product of two
864 BDDs. Computation is clipped at a certain depth. This procedure is
865 similar to bdd_and_smooth but large depth recursions are
866 avoided. maxDepth specifies the recursion depth. over specifies
867 which kind of approximation is used 0 - under approximation and 1 -
868 for over approximation. ]
869
870 SideEffects []
871
872******************************************************************************/
873bdd_t *
874bdd_clipping_and_smooth(
875 bdd_t *f,
876 bdd_t *g,
877 array_t *smoothing_vars /* of bdd_t *'s */,
878 int maxDepth,
879 int over)
880{
881 int i;
882 bdd_t *variable;
883 DdNode *cube,*tmpDd,*result;
884 DdManager *mgr;
885
886 /* Make sure both operands belong to the same manager. */
887 assert(f->mgr == g->mgr);
888
889 /* The Boulder package needs the smothing variables passed as a cube.
890 * Therefore we must build that cube from the indices of variables
891 * in the array before calling the procedure.
892 */
893 mgr = f->mgr;
894 Cudd_Ref(cube = DD_ONE(mgr));
895 for (i = 0; i < array_n(smoothing_vars); i++) {
896 variable = array_fetch(bdd_t *,smoothing_vars,i);
897
898 /* Make sure the variable belongs to the same manager. */
899 assert(mgr == variable->mgr);
900
901 tmpDd = Cudd_bddAnd(mgr,cube,variable->node);
902 if (tmpDd == NULL) {
903 Cudd_RecursiveDeref(mgr,cube);
904 return(NULL);
905 }
906 cuddRef(tmpDd);
907 Cudd_RecursiveDeref(mgr, cube);
908 cube = tmpDd;
909 }
910
911 /* Perform the smoothing */
912 result = Cudd_bddClippingAndAbstract(mgr,f->node,g->node,cube, maxDepth, over);
913 if (result == NULL) {
914 Cudd_RecursiveDeref(mgr, cube);
915 return(NULL);
916 }
917 cuddRef(result);
918 /* Get rid of temporary results. */
919 Cudd_RecursiveDeref(mgr, cube);
920
921 /* Build the bdd_t structure for the result */
922 return(bdd_construct_bdd_t(mgr,result));
923
924} /* end of bdd_clipping_and_smooth */
925
926
927/**Function********************************************************************
928
929 Synopsis [Abstracts variables from the exclusive OR of two BDDs.]
930
931 SideEffects []
932
933******************************************************************************/
934bdd_t *
935bdd_xor_smooth(
936 bdd_t *f,
937 bdd_t *g,
938 array_t *smoothing_vars /* of bdd_t *'s */)
939{
940 int i;
941 bdd_t *variable;
942 DdNode *cube,*tmpDd,*result;
943 DdManager *mgr;
944
945 /* Make sure both operands belong to the same manager. */
946 assert(f->mgr == g->mgr);
947
948 /* The Boulder package needs the smothing variables passed as a cube.
949 * Therefore we must build that cube from the indices of variables
950 * in the array before calling the procedure.
951 */
952 mgr = f->mgr;
953 Cudd_Ref(cube = DD_ONE(mgr));
954 for (i = 0; i < array_n(smoothing_vars); i++) {
955 variable = array_fetch(bdd_t *,smoothing_vars,i);
956
957 /* Make sure the variable belongs to the same manager. */
958 assert(mgr == variable->mgr);
959
960 tmpDd = Cudd_bddAnd(mgr,cube,variable->node);
961 if (tmpDd == NULL) {
962 Cudd_RecursiveDeref(mgr,cube);
963 return(NULL);
964 }
965 cuddRef(tmpDd);
966 Cudd_RecursiveDeref(mgr, cube);
967 cube = tmpDd;
968 }
969
970 /* Perform the smoothing */
971 result = Cudd_bddXorExistAbstract(mgr,f->node,g->node,cube);
972 if (result == NULL) {
973 Cudd_RecursiveDeref(mgr, cube);
974 return(NULL);
975 }
976 cuddRef(result);
977 /* Get rid of temporary results. */
978 Cudd_RecursiveDeref(mgr, cube);
979
980 /* Build the bdd_t structure for the result */
981 return(bdd_construct_bdd_t(mgr,result));
982
983} /* end of bdd_xor_smooth */
984
985
986/**Function********************************************************************
987
988 Synopsis [Return a minimum size BDD between bounds.]
989
990 SideEffects []
991
992******************************************************************************/
993bdd_t *
994bdd_between(bdd_t *f_min, bdd_t *f_max)
995{
996 bdd_t *care_set, *ret;
997
998 if (bdd_equal(f_min, f_max)) {
999 return (bdd_dup(f_min));
1000 }
1001 care_set = bdd_or(f_min, f_max, 1, 0);
1002 ret = bdd_minimize(f_min, care_set);
1003 bdd_free(care_set);
1004 /* The size of ret is never larger than the size of f_min. We need
1005 ** only to check ret against f_max. */
1006 if (bdd_size(f_max) <= bdd_size(ret)) {
1007 bdd_free(ret);
1008 return(bdd_dup(f_max));
1009 } else {
1010 return(ret);
1011 }
1012
1013} /* end of bdd_between */
1014
1015
1016/**Function********************************************************************
1017
1018 Synopsis [Computes the cube of an array of mdd ids. The cube
1019 is positive unate. Returns a pointer to the result if successful;
1020 NULL otherwise.]
1021
1022 SideEffects []
1023
1024******************************************************************************/
1025bdd_t *
1026bdd_compute_cube(bdd_manager *mgr, array_t *vars)
1027{
1028 DdNode *result;
1029 DdNode **nodeArray;
1030 int i, id;
1031
1032 if (vars == NIL(array_t)) return NIL(bdd_t);
1033 if (array_n(vars) == 0) return NIL(bdd_t);
1034 /* create an array of DdNodes */
1035 nodeArray = ALLOC(DdNode *, array_n(vars));
1036 arrayForEachItem(int, vars, i, id) {
1037 assert(id < bdd_num_vars(mgr));
1038 nodeArray[i] = Cudd_bddIthVar((DdManager *)mgr, id);
1039 }
1040 result = Cudd_bddComputeCube((DdManager *)mgr, (DdNode **)nodeArray,
1041 NULL, array_n(vars));
1042 FREE(nodeArray);
1043 if (result == NULL) return(NULL);
1044 cuddRef(result);
1045 return(bdd_construct_bdd_t(mgr,result));
1046
1047} /* end of bdd_compute_cube */
1048
1049
1050/**Function********************************************************************
1051
1052 Synopsis [Computes the cube of an array of mdd ids. The phase if
1053 each variable is given in the phase array. Returns a pointer to the
1054 result if successful; NULL otherwise.]
1055
1056 SideEffects [none]
1057
1058******************************************************************************/
1059bdd_t *
1060bdd_compute_cube_with_phase(bdd_manager *mgr, array_t *vars, array_t *phase)
1061{
1062 DdNode *result;
1063 DdNode **nodeArray;
1064 int *phaseArray;
1065 int i, id, ph;
1066
1067 if (vars == NIL(array_t)) return NIL(bdd_t);
1068 if (array_n(vars) == 0) return NIL(bdd_t);
1069 if (phase != NIL(array_t) && array_n(vars) != array_n(phase))
1070 return NIL(bdd_t);
1071 /* create an array of DdNodes */
1072 nodeArray = ALLOC(DdNode *, array_n(vars));
1073 phaseArray = NIL(int);
1074 if (phase != NIL(array_t)) phaseArray = ALLOC(int, array_n(phase));
1075 arrayForEachItem(int, vars, i, id) {
1076 assert(id < bdd_num_vars(mgr));
1077 nodeArray[i] = Cudd_bddIthVar((DdManager *)mgr, id);
1078 }
1079 arrayForEachItem(int, phase, i, ph) {
1080 assert(ph == 0 || ph == 1);
1081 phaseArray[i] = ph;
1082 }
1083 result = Cudd_bddComputeCube((DdManager *)mgr, (DdNode **)nodeArray,
1084 phaseArray, array_n(vars));
1085 FREE(nodeArray);
1086 if (phaseArray != NIL(int)) FREE(phaseArray);
1087 if (result == NULL) return(NULL);
1088 cuddRef(result);
1089 return(bdd_construct_bdd_t(mgr,result));
1090
1091} /* end of bdd_compute_cube_with_phase */
1092
1093
1094/**Function********************************************************************
1095
1096 Synopsis [Computes the cofactor of f with respect to g.]
1097
1098 SideEffects []
1099
1100******************************************************************************/
1101bdd_t *
1102bdd_cofactor(bdd_t *f, bdd_t *g)
1103{
1104 DdNode *result;
1105
1106 /* Make sure both operands belong to the same manager */
1107 assert(f->mgr == g->mgr);
1108
1109 /* We use Cudd_bddConstrain instead of Cudd_Cofactor for generality. */
1110 result = Cudd_bddConstrain(f->mgr,f->node,
1111 g->node);
1112 if (result == NULL) return(NULL);
1113 cuddRef(result);
1114 return(bdd_construct_bdd_t(f->mgr,result));
1115
1116} /* end of bdd_cofactor */
1117
1118
1119/**Function********************************************************************
1120
1121 Synopsis [Computes the cofactor of f with respect to g.]
1122
1123 SideEffects []
1124
1125******************************************************************************/
1126bdd_t *
1127bdd_cofactor_array(bdd_t *f, array_t *bddArray)
1128{
1129 bdd_t *operand;
1130 DdNode *result, *temp;
1131 int i;
1132
1133 Cudd_Ref(result = f->node);
1134
1135 for (i = 0; i < array_n(bddArray); i++) {
1136 operand = array_fetch(bdd_t *, bddArray, i);
1137 temp = Cudd_bddConstrain(f->mgr, result, operand->node);
1138 if (temp == NULL) {
1139 Cudd_RecursiveDeref(f->mgr, result);
1140 return(NULL);
1141 }
1142 cuddRef(temp);
1143 Cudd_RecursiveDeref(f->mgr, result);
1144 result = temp;
1145 }
1146
1147 return(bdd_construct_bdd_t(f->mgr,result));
1148
1149} /* end of bdd_cofactor_array */
1150
1151
1152/**Function********************************************************************
1153
1154 Synopsis [Computes the cofactor of f with respect to g.]
1155
1156 SideEffects []
1157
1158******************************************************************************/
1159bdd_t *
1160bdd_var_cofactor(bdd_t *f, bdd_t *g)
1161{
1162 DdNode *result;
1163
1164 /* Make sure both operands belong to the same manager */
1165 assert(f->mgr == g->mgr);
1166
1167 result = Cudd_Cofactor(f->mgr,f->node,
1168 g->node);
1169 if (result == NULL) return(NULL);
1170 cuddRef(result);
1171 return(bdd_construct_bdd_t(f->mgr,result));
1172
1173} /* end of bdd_var_cofactor */
1174
1175
1176/**Function********************************************************************
1177
1178 Synopsis [Computes the cofactor of f with respect to g in a safe manner.]
1179
1180 Description [Performs safe minimization of a BDD. Given the BDD
1181 <code>f</code> of a function to be minimized and a BDD
1182 <code>c</code> representing the care set, Cudd_bddLICompaction
1183 produces the BDD of a function that agrees with <code>f</code>
1184 wherever <code>c</code> is 1. Safe minimization means that the size
1185 of the result is guaranteed not to exceed the size of
1186 <code>f</code>. This function is based on the DAC97 paper by Hong et
1187 al.. Returns a pointer to the result if successful; NULL
1188 otherwise.]
1189
1190 SideEffects []
1191
1192******************************************************************************/
1193bdd_t *
1194bdd_compact(bdd_t *f, bdd_t *g)
1195{
1196 DdNode *result;
1197
1198 /* Make sure both operands belong to the same manager */
1199 assert(f->mgr == g->mgr);
1200
1201 result = Cudd_bddLICompaction(f->mgr,f->node,
1202 g->node);
1203 if (result == NULL) return(NULL);
1204 cuddRef(result);
1205 return(bdd_construct_bdd_t(f->mgr,result));
1206
1207} /* end of bdd_compact */
1208
1209
1210/**Function********************************************************************
1211
1212 Synopsis [Computes a bdd between l and u.]
1213
1214 SideEffects []
1215
1216******************************************************************************/
1217bdd_t *
1218bdd_squeeze(bdd_t *l, bdd_t *u)
1219{
1220 DdNode *result;
1221
1222 /* Make sure both operands belong to the same manager */
1223 assert(l->mgr == u->mgr);
1224
1225 result = Cudd_bddSqueeze(l->mgr,l->node,
1226 u->node);
1227 if (result == NULL) return(NULL);
1228 cuddRef(result);
1229 return(bdd_construct_bdd_t(l->mgr,result));
1230
1231} /* end of bdd_squeeze */
1232
1233
1234/**Function********************************************************************
1235
1236 Synopsis [Functional composition of a function by a variable.]
1237
1238 SideEffects []
1239
1240******************************************************************************/
1241bdd_t *
1242bdd_compose(bdd_t *f, bdd_t *v, bdd_t *g)
1243{
1244 DdNode *result;
1245
1246 /* Make sure all operands belong to the same manager. */
1247 assert(f->mgr == g->mgr);
1248 assert(f->mgr == v->mgr);
1249
1250 result = Cudd_bddCompose(f->mgr,f->node,
1251 g->node,
1252 (int)Cudd_Regular(v->node)->index);
1253 if (result == NULL) return(NULL);
1254 cuddRef(result);
1255 return(bdd_construct_bdd_t(f->mgr,result));
1256
1257} /* end of bdd_compose */
1258
1259
1260/**Function********************************************************************
1261
1262 Synopsis [Composes a BDD with a vector of BDDs. Given a vector of
1263 BDDs, creates a new BDD by substituting the BDDs for the variables
1264 of the BDD f.]
1265
1266 SideEffects []
1267
1268******************************************************************************/
1269bdd_t *
1270bdd_vector_compose(bdd_t *f, array_t *varArray, array_t *funcArray)
1271{
1272 int i, n, nVars, index;
1273 bdd_t *var, *func;
1274 DdNode *result;
1275 DdNode **vector;
1276
1277 assert(array_n(varArray) == array_n(funcArray));
1278 n = array_n(varArray);
1279 nVars = ((DdManager *)f->mgr)->size;
1280 vector = ALLOC(DdNode *, sizeof(DdNode *) * nVars);
1281 memset(vector, 0, sizeof(DdNode *) * nVars);
1282
1283 for (i = 0; i < n; i++) {
1284 var = array_fetch(bdd_t *, varArray, i);
1285 func = array_fetch(bdd_t *, funcArray, i);
1286 index = (int)bdd_top_var_id(var);
1287 vector[index] = (DdNode *)func->node;
1288 cuddRef(vector[index]);
1289 }
1290 for (i = 0; i < nVars; i++) {
1291 if (!vector[i]) {
1292 vector[i] = Cudd_bddIthVar((DdManager *)f->mgr, i);
1293 cuddRef(vector[i]);
1294 }
1295 }
1296
1297 result = Cudd_bddVectorCompose(f->mgr, f->node, vector);
1298
1299 for (i = 0; i < nVars; i++)
1300 Cudd_RecursiveDeref((DdManager *)f->mgr, vector[i]);
1301 FREE(vector);
1302 if (result == NULL) return(NULL);
1303 cuddRef(result);
1304 return(bdd_construct_bdd_t(f->mgr,result));
1305
1306} /* end of bdd_vector_compose */
1307
1308
1309/**Function********************************************************************
1310
1311 Synopsis [Universal Abstraction of Variables.]
1312
1313 SideEffects []
1314
1315******************************************************************************/
1316bdd_t *
1317bdd_consensus(
1318 bdd_t *f,
1319 array_t *quantifying_vars /* of bdd_t *'s */)
1320{
1321 int i;
1322 bdd_t *variable;
1323 DdNode *cube,*tmpDd,*result;
1324 DdManager *mgr;
1325
1326 /* The Boulder package needs the smothing variables passed as a cube.
1327 * Therefore we must build that cube from the indices of the variables
1328 * in the array before calling the procedure.
1329 */
1330 mgr = f->mgr;
1331 Cudd_Ref(cube = DD_ONE(mgr));
1332 for (i = 0; i < array_n(quantifying_vars); i++) {
1333 variable = array_fetch(bdd_t *,quantifying_vars,i);
1334
1335 /* Make sure the variable belongs to the same manager */
1336 assert(mgr == variable->mgr);
1337
1338 tmpDd = Cudd_bddAnd(mgr,cube,variable->node);
1339 if (tmpDd == NULL) {
1340 Cudd_RecursiveDeref(mgr, cube);
1341 return(NULL);
1342 }
1343 cuddRef(tmpDd);
1344 Cudd_RecursiveDeref(mgr, cube);
1345 cube = tmpDd;
1346 }
1347
1348 /* Perform the consensus */
1349 result = Cudd_bddUnivAbstract(mgr,f->node,cube);
1350 if (result == NULL) {
1351 Cudd_RecursiveDeref(mgr, cube);
1352 return(NULL);
1353 }
1354 cuddRef(result);
1355 /* Get rid of temporary results */
1356 Cudd_RecursiveDeref(mgr, cube);
1357
1358 /* Build the bdd_t structure for the result */
1359 return(bdd_construct_bdd_t(mgr,result));
1360
1361} /* end of bdd_consensus */
1362
1363
1364/**Function********************************************************************
1365
1366 Synopsis [Universal Abstraction of Variables.]
1367
1368 SideEffects []
1369
1370******************************************************************************/
1371bdd_t *
1372bdd_consensus_with_cube(
1373 bdd_t *f,
1374 bdd_t *cube)
1375{
1376 DdNode *result;
1377 DdManager *mgr;
1378
1379 mgr = f->mgr;
1380 /* Perform the consensus */
1381 result = Cudd_bddUnivAbstract(mgr,f->node,cube->node);
1382 if (result == NULL)
1383 return(NULL);
1384 cuddRef(result);
1385
1386 /* Build the bdd_t structure for the result */
1387 return(bdd_construct_bdd_t(mgr,result));
1388
1389} /* end of bdd_consensus_with_cube */
1390
1391
1392/**Function********************************************************************
1393
1394 Synopsis [The compatible projection function.]
1395
1396 Description [The compatible projection function. The reference minterm
1397 is chosen based on the phases of the quantifying variables. If all
1398 variables are in positive phase, the minterm 111...111 is used as
1399 reference.]
1400
1401 SideEffects []
1402
1403******************************************************************************/
1404bdd_t *
1405bdd_cproject(
1406 bdd_t *f,
1407 array_t *quantifying_vars /* of bdd_t* */)
1408{
1409 DdManager *dd;
1410 DdNode *cube;
1411 DdNode *res;
1412 bdd_t *fi;
1413 int nvars, i;
1414
1415 if (f == NULL) {
1416 fail ("bdd_cproject: invalid BDD");
1417 }
1418
1419 nvars = array_n(quantifying_vars);
1420 if (nvars <= 0) {
1421 fail("bdd_cproject: no projection variables");
1422 }
1423 dd = f->mgr;
1424
1425 cube = DD_ONE(dd);
1426 cuddRef(cube);
1427 for (i = nvars - 1; i >= 0; i--) {
1428 DdNode *tmpp;
1429 fi = array_fetch(bdd_t *, quantifying_vars, i);
1430 tmpp = Cudd_bddAnd(dd,fi->node,cube);
1431 if (tmpp == NULL) {
1432 Cudd_RecursiveDeref(dd,cube);
1433 return(NULL);
1434 }
1435 cuddRef(tmpp);
1436 Cudd_RecursiveDeref(dd,cube);
1437 cube = tmpp;
1438 }
1439
1440 res = Cudd_CProjection(dd,f->node,cube);
1441 if (res == NULL) {
1442 Cudd_RecursiveDeref(dd,cube);
1443 return(NULL);
1444 }
1445 cuddRef(res);
1446 Cudd_RecursiveDeref(dd,cube);
1447
1448 return(bdd_construct_bdd_t(dd,res));
1449
1450} /* end of bdd_cproject */
1451
1452
1453/**Function********************************************************************
1454
1455 Synopsis [Returns the else branch of a BDD.]
1456
1457 SideEffects []
1458
1459******************************************************************************/
1460bdd_t *
1461bdd_else(bdd_t *f)
1462{
1463 DdNode *result;
1464
1465 result = Cudd_E(f->node);
1466 result = Cudd_NotCond(result,Cudd_IsComplement(f->node));
1467 cuddRef(result);
1468 return(bdd_construct_bdd_t(f->mgr,result));
1469
1470} /* end of bdd_else */
1471
1472
1473/**Function********************************************************************
1474
1475 Synopsis [ITE.]
1476
1477 SideEffects []
1478
1479******************************************************************************/
1480bdd_t *
1481bdd_ite(
1482 bdd_t *i,
1483 bdd_t *t,
1484 bdd_t *e,
1485 boolean i_phase,
1486 boolean t_phase,
1487 boolean e_phase)
1488{
1489 DdNode *newi,*newt,*newe,*ite;
1490
1491 /* Make sure both bdds belong to the same mngr */
1492 assert(i->mgr == t->mgr);
1493 assert(i->mgr == e->mgr);
1494
1495 /* Modify the phases of the operands according to the parameters */
1496 if (!i_phase) {
1497 newi = Cudd_Not(i->node);
1498 } else {
1499 newi = i->node;
1500 }
1501 if (!t_phase) {
1502 newt = Cudd_Not(t->node);
1503 } else {
1504 newt = t->node;
1505 }
1506 if (!e_phase) {
1507 newe = Cudd_Not(e->node);
1508 } else {
1509 newe = e->node;
1510 }
1511
1512 /* Perform the ITE operation */
1513 ite = Cudd_bddIte(i->mgr,newi,newt,newe);
1514 if (ite == NULL) return(NULL);
1515 cuddRef(ite);
1516 return(bdd_construct_bdd_t(i->mgr,ite));
1517
1518} /* end of bdd_ite */
1519
1520
1521/**Function********************************************************************
1522
1523 Synopsis [Restrict operator as described in Coudert et al. ICCAD90.]
1524
1525 Description [Restrict operator as described in Coudert et
1526 al. ICCAD90. Always returns a BDD not larger than the input
1527 <code>f</code> if successful; NULL otherwise.]
1528
1529 SideEffects [none]
1530
1531******************************************************************************/
1532bdd_t *
1533bdd_minimize(bdd_t *f, bdd_t *c)
1534{
1535 DdNode *result;
1536 bdd_t *output;
1537
1538 /* Make sure both operands belong to the same manager. */
1539 assert(f->mgr == c->mgr);
1540
1541 result = Cudd_bddRestrict(f->mgr, f->node, c->node);
1542 if (result == NULL) return(NULL);
1543 cuddRef(result);
1544
1545 output = bdd_construct_bdd_t(f->mgr,result);
1546 return(output);
1547
1548} /* end of bdd_minimize */
1549
1550
1551/**Function********************************************************************
1552
1553 Synopsis [Restrict operator as described in Coudert et al. ICCAD90.]
1554
1555 Description [Restrict operator as described in Coudert et
1556 al. ICCAD90. Always returns a BDD not larger than the input
1557 <code>f</code> if successful; NULL otherwise.]
1558
1559 SideEffects [none]
1560
1561******************************************************************************/
1562bdd_t *
1563bdd_minimize_array(bdd_t *f, array_t *bddArray)
1564{
1565 bdd_t *operand;
1566 DdNode *result, *temp;
1567 int i;
1568
1569 Cudd_Ref(result = f->node);
1570
1571 for (i = 0; i < array_n(bddArray); i++) {
1572 operand = array_fetch(bdd_t *, bddArray, i);
1573 temp = Cudd_bddRestrict(f->mgr, result, operand->node);
1574 if (temp == NULL) {
1575 Cudd_RecursiveDeref(f->mgr, result);
1576 return(NULL);
1577 }
1578 cuddRef(temp);
1579 Cudd_RecursiveDeref(f->mgr, result);
1580 result = temp;
1581 }
1582
1583 return(bdd_construct_bdd_t(f->mgr,result));
1584
1585} /* end of bdd_minimize_array */
1586
1587
1588/**Function********************************************************************
1589
1590 Synopsis [Subset (superset) operator.]
1591
1592 Description [It computes a bdd which is a subset (superset) of the
1593 given operand and has less nodes. approxDir specifies over/under
1594 approximation. The number of variables is an estimate of the support
1595 of the operand, and threshold is the maximum number of vertices
1596 allowed in the result. The technique applied to eliminate nodes is
1597 to remove a child of a node, starting with the root, that contribute
1598 to fewer minterms than the other child. Refer to Ravi & Somenzi
1599 ICCAD95.]
1600
1601 SideEffects [none]
1602
1603******************************************************************************/
1604bdd_t *
1605bdd_approx_hb(
1606 bdd_t *f,
1607 bdd_approx_dir_t approxDir,
1608 int numVars,
1609 int threshold)
1610{
1611 DdNode *result;
1612 bdd_t *output;
1613
1614 switch (approxDir) {
1615 case BDD_OVER_APPROX:
1616 result = Cudd_SupersetHeavyBranch(f->mgr, f->node, numVars, threshold);
1617 break;
1618 case BDD_UNDER_APPROX:
1619 result = Cudd_SubsetHeavyBranch(f->mgr, f->node, numVars, threshold);
1620 break;
1621 default:
1622 result = NULL;
1623 }
1624 if (result == NULL) return(NULL);
1625 cuddRef(result);
1626
1627 output = bdd_construct_bdd_t(f->mgr,result);
1628 return(output);
1629
1630} /* end of bdd_approx_hb */
1631
1632
1633/**Function********************************************************************
1634
1635 Synopsis [Subset (superset) operator.]
1636
1637 Description [It computes a bdd which is a subset (superset) of the
1638 given operand and it has less nodes. approxDir specifies over/under
1639 approximation. The number of variables is an estimate of the support
1640 of the operand, and threshold is the maximum number of vertices
1641 allowed in the result. If unsure, pass NULL for the number of
1642 variables. The method used is to extract the smallest cubes in the
1643 bdd which also correspond to the shortest paths in the bdd to the
1644 constant 1. hardlimit indicates that the node limit is strict. Refer
1645 to Ravi and Somenzi ICCAD95.]
1646
1647 SideEffects [none]
1648
1649******************************************************************************/
1650bdd_t *
1651bdd_approx_sp(
1652 bdd_t *f,
1653 bdd_approx_dir_t approxDir,
1654 int numVars,
1655 int threshold,
1656 int hardlimit)
1657{
1658 DdNode *result;
1659 bdd_t *output;
1660
1661 switch (approxDir) {
1662 case BDD_OVER_APPROX:
1663 result = Cudd_SupersetShortPaths(f->mgr, f->node, numVars, threshold, hardlimit);
1664 break;
1665 case BDD_UNDER_APPROX:
1666 result = Cudd_SubsetShortPaths(f->mgr, f->node, numVars, threshold, hardlimit);
1667 break;
1668 default:
1669 result = NULL;
1670 }
1671
1672 if (result == NULL) return(NULL);
1673 cuddRef(result);
1674
1675 output = bdd_construct_bdd_t(f->mgr,result);
1676 return(output);
1677
1678} /* end of bdd_approx_sp */
1679
1680
1681/**Function********************************************************************
1682
1683 Synopsis [Subset (superset) operator.]
1684
1685 Description [It computes a bdd which is a subset (superset) of the
1686 given operand and it has less nodes. The bdd chooses to preserve
1687 nodes that contribute a large number and throws away those that
1688 contribute fewer minterms and dominate a large number of
1689 nodes. approxDir specifies over/under approximation. numVars is the
1690 number of variables in the true support of f. threshold is a limit
1691 specified on the number of nodes. safe is a parameter to ensure that
1692 the result is never larger than the operand. quality is a factor
1693 that affects replacement of nodes: 1 is the default value. Values
1694 for quality imply that the ratio of the density of the result of
1695 replaced nodes to the original original is equal to the value. Refer
1696 to Shiple thesis.]
1697
1698 SideEffects [none]
1699
1700******************************************************************************/
1701bdd_t *
1702bdd_approx_ua(
1703 bdd_t *f,
1704 bdd_approx_dir_t approxDir,
1705 int numVars,
1706 int threshold,
1707 int safe,
1708 double quality)
1709{
1710 DdNode *result;
1711 bdd_t *output;
1712
1713 switch (approxDir) {
1714 case BDD_OVER_APPROX:
1715 result = Cudd_OverApprox(f->mgr, f->node, numVars, threshold, safe, quality);
1716 break;
1717 case BDD_UNDER_APPROX:
1718 result = Cudd_UnderApprox(f->mgr, f->node, numVars, threshold, safe, quality);
1719 break;
1720 default:
1721 result = NULL;
1722 }
1723 if (result == NULL) return(NULL);
1724 cuddRef(result);
1725
1726 output = bdd_construct_bdd_t(f->mgr,result);
1727 return(output);
1728
1729} /* end of bdd_approx_ua */
1730
1731
1732/**Function********************************************************************
1733
1734 Synopsis [Subset (superset) operator.]
1735
1736 Description [It computes a bdd which is a subset (superset) of the
1737 given operand and it has less nodes.The bdd chooses to preserve
1738 nodes that contribute a large number and throws away those that
1739 contribute fewer minterms and dominate a large number of nodes. Some
1740 nodes may be remapped to existing nodes in the BDD. approxDir
1741 specifies over/under approximation. numVars is the number of
1742 variables in the true support of f. threshold is a limit specified
1743 on the number of nodes. safe is a parameter to ensure that the
1744 result is never larger than the operand. quality is a factor that
1745 affects replacement of nodes: 1 is the default value. Values for
1746 quality imply that the ratio of the density of the result with
1747 replaced nodes to the original bdd is equal to the value. Refer to
1748 Shiple, Somenzi DAC98. ]
1749
1750 SideEffects [none]
1751
1752******************************************************************************/
1753bdd_t *
1754bdd_approx_remap_ua(
1755 bdd_t *f,
1756 bdd_approx_dir_t approxDir,
1757 int numVars,
1758 int threshold,
1759 double quality)
1760{
1761 DdNode *result;
1762 bdd_t *output;
1763
1764 switch (approxDir) {
1765 case BDD_OVER_APPROX:
1766 result = Cudd_RemapOverApprox((DdManager *)f->mgr, (DdNode *)f->node, numVars, threshold, quality);
1767 break;
1768 case BDD_UNDER_APPROX:
1769 result = Cudd_RemapUnderApprox((DdManager *)f->mgr, (DdNode *)f->node, numVars, threshold, quality);
1770 break;
1771 default:
1772 result = NULL;
1773 }
1774
1775 if (result == NULL) return(NULL);
1776 cuddRef(result);
1777
1778 output = bdd_construct_bdd_t((DdManager *)f->mgr,result);
1779 return(output);
1780
1781} /* end of bdd_approx_remap_ua */
1782
1783
1784/**Function********************************************************************
1785
1786 Synopsis [Subset (superset) operator.]
1787
1788 Description [It computes a bdd which is a subset (superset) of the
1789 given operand and it has less nodes.The bdd chooses to preserve
1790 nodes that contribute a large number and throws away those that
1791 contribute fewer minterms and dominate a large number of nodes. Some
1792 nodes may be remapped to existing nodes in the BDD. approxDir
1793 specifies over/under approximation. numVars is the number of
1794 variables in the true support of f. threshold is a limit specified
1795 on the number of nodes. safe is a parameter to ensure that the
1796 result is never larger than the operand. quality is a factor that
1797 affects replacement of nodes: 1 is the default value. Values for
1798 quality imply that the ratio of the density of the result with
1799 replaced nodes to the original bdd is equal to the value. Refer
1800 Shiple, Somenzi DAC98. The only difference between this function and
1801 bdd_approx_remap_ua is that this function takes a bias BDD and tries
1802 to lean the approximation towards the bias]
1803
1804 SideEffects [none]
1805
1806******************************************************************************/
1807bdd_t *
1808bdd_approx_biased_rua(
1809 bdd_t *f,
1810 bdd_approx_dir_t approxDir,
1811 bdd_t *bias,
1812 int numVars,
1813 int threshold,
1814 double quality,
1815 double qualityBias)
1816{
1817 DdNode *result;
1818 bdd_t *output;
1819
1820 assert(bias->mgr == f->mgr);
1821 switch (approxDir) {
1822 case BDD_OVER_APPROX:
1823 result = Cudd_BiasedOverApprox((DdManager *)f->mgr, (DdNode *)f->node, (DdNode *)bias->node, numVars, threshold, quality, qualityBias);
1824 break;
1825 case BDD_UNDER_APPROX:
1826 result = Cudd_BiasedUnderApprox((DdManager *)f->mgr, (DdNode *)f->node, (DdNode *)bias->node, numVars, threshold, quality, qualityBias);
1827 break;
1828 default:
1829 result = NULL;
1830 }
1831
1832 if (result == NULL) return(NULL);
1833 cuddRef(result);
1834
1835 output = bdd_construct_bdd_t((DdManager *)f->mgr,result);
1836 return(output);
1837
1838} /* end of bdd_approx_biased_rua */
1839
1840
1841/**Function********************************************************************
1842
1843 Synopsis [Subset (superset) operator.]
1844
1845 Description [It computes a bdd which is a subset (superset) of the
1846 given operand and it has less nodes. approxDir specifies over/under
1847 approximation. The number of variables is an estimate of the support
1848 of the operand, and threshold is the maximum number of vertices
1849 allowed in the result. It applies short paths with the given
1850 threshold first and then uses remap_ua to increase density.]
1851
1852 SideEffects [none]
1853
1854******************************************************************************/
1855bdd_t *
1856bdd_approx_compress(
1857 bdd_t *f,
1858 bdd_approx_dir_t approxDir,
1859 int numVars,
1860 int threshold)
1861{
1862 DdNode *result;
1863 bdd_t *output;
1864
1865 switch (approxDir) {
1866 case BDD_OVER_APPROX:
1867 result = Cudd_SupersetCompress(f->mgr, f->node, numVars, threshold);
1868 break;
1869 case BDD_UNDER_APPROX:
1870 result = Cudd_SubsetCompress(f->mgr, f->node, numVars, threshold);
1871 break;
1872 default:
1873 result = NULL;
1874 }
1875
1876 if (result == NULL) return(NULL);
1877 cuddRef(result);
1878
1879 output = bdd_construct_bdd_t(f->mgr,result);
1880 return(output);
1881
1882} /* end of bdd_approx_compress */
1883
1884
1885/**Function********************************************************************
1886
1887 Synopsis [Finds a shortest path in a DD.]
1888
1889 Description [Finds a shortest path in a DD. f is the DD we want to
1890 get the shortest path for; weight\[i\] is the weight of the THEN arc
1891 coming from the node whose index is i. If weight is NULL, then unit
1892 weights are assumed for all THEN arcs. All ELSE arcs have 0 weight.
1893 If non-NULL, both weight and support should point to arrays with at
1894 least as many entries as there are variables in the manager.
1895 Returns the shortest path as the BDD of a cube.]
1896
1897 SideEffects [support contains on return the true support of f.
1898 If support is NULL on entry, then Cudd_ShortestPath does not compute
1899 the true support info. length contains the length of the path.]
1900
1901******************************************************************************/
1902bdd_t *
1903bdd_shortest_path(
1904 bdd_t *f,
1905 int *weight,
1906 int *support,
1907 int *length)
1908{
1909 DdNode *result;
1910 bdd_t *output;
1911
1912 result = Cudd_ShortestPath(f->mgr, f->node, weight, support, length);
1913 if (result == NULL) return(NULL);
1914 cuddRef(result);
1915
1916 output = bdd_construct_bdd_t(f->mgr,result);
1917 return(output);
1918
1919} /* end of bdd_shortest_path */
1920
1921
1922/**Function********************************************************************
1923
1924 Synopsis [Negation.]
1925
1926 SideEffects []
1927
1928******************************************************************************/
1929bdd_t *
1930bdd_not(bdd_t *f)
1931{
1932 DdNode *result;
1933
1934 Cudd_Ref(result = Cudd_Not(f->node));
1935 return(bdd_construct_bdd_t(f->mgr,result));
1936
1937} /* end of bdd_not */
1938
1939
1940/**Function********************************************************************
1941
1942 Synopsis [Returns the one BDD.]
1943
1944 SideEffects []
1945
1946******************************************************************************/
1947bdd_t *
1948bdd_one(bdd_manager *mgr)
1949{
1950 DdNode *result;
1951
1952 Cudd_Ref(result = DD_ONE((DdManager *)mgr));
1953 return(bdd_construct_bdd_t((DdManager *)mgr,result));
1954
1955} /* end of bdd_one */
1956
1957
1958/**Function********************************************************************
1959
1960 Synopsis [Or of two BDDs.]
1961
1962 SideEffects []
1963
1964******************************************************************************/
1965bdd_t *
1966bdd_or(
1967 bdd_t *f,
1968 bdd_t *g,
1969 boolean f_phase,
1970 boolean g_phase)
1971{
1972 DdNode *newf,*newg,*forg;
1973 bdd_t *result;
1974
1975 /* Make sure both bdds belong to the same mngr */
1976 assert(f->mgr == g->mgr);
1977
1978 /* Modify the phases of the operands according to the parameters */
1979 if (f_phase) {
1980 newf = Cudd_Not(f->node);
1981 } else {
1982 newf = f->node;
1983 }
1984 if (g_phase) {
1985 newg = Cudd_Not(g->node);
1986 } else {
1987 newg = g->node;
1988 }
1989
1990 /* Perform the OR operation */
1991 forg = Cudd_bddAnd(f->mgr,newf,newg);
1992 if (forg == NULL) return(NULL);
1993 forg = Cudd_Not(forg);
1994 cuddRef(forg);
1995 result = bdd_construct_bdd_t(f->mgr,forg);
1996
1997 return(result);
1998
1999} /* end of bdd_or */
2000
2001
2002/**Function********************************************************************
2003
2004 Synopsis [Existential abstraction of variables.]
2005
2006 SideEffects []
2007
2008******************************************************************************/
2009bdd_t *
2010bdd_smooth(
2011 bdd_t *f,
2012 array_t *smoothing_vars /* of bdd_t *'s */)
2013{
2014 int i;
2015 bdd_t *variable;
2016 DdNode *cube,*tmpDd,*result;
2017 DdManager *mgr;
2018 DdNode **vars;
2019 int nVars, level;
2020
2021 /* The Boulder package needs the smoothing variables passed as a cube.
2022 * Therefore we must build that cube from the indices of the variables
2023 * in the array before calling the procedure.
2024 */
2025 mgr = f->mgr;
2026 nVars = mgr->size;
2027 vars = ALLOC(DdNode *, sizeof(DdNode *) * nVars);
2028 memset(vars, 0, sizeof(DdNode *) * nVars);
2029 for (i = 0; i < array_n(smoothing_vars); i++) {
2030 variable = array_fetch(bdd_t *,smoothing_vars,i);
2031
2032 /* Make sure the variable belongs to the same manager. */
2033 assert(mgr == variable->mgr);
2034
2035 level = Cudd_ReadPerm(mgr, Cudd_NodeReadIndex(variable->node));
2036 vars[level] = variable->node;
2037 }
2038 Cudd_Ref(cube = DD_ONE(mgr));
2039 for (i = nVars - 1; i >= 0; i--) {
2040 if (!vars[i])
2041 continue;
2042 tmpDd = Cudd_bddAnd(mgr,cube,vars[i]);
2043 if (tmpDd == NULL) {
2044 Cudd_RecursiveDeref(mgr, cube);
2045 return(NULL);
2046 }
2047 cuddRef(tmpDd);
2048 Cudd_RecursiveDeref(mgr, cube);
2049 cube = tmpDd;
2050 }
2051 FREE(vars);
2052
2053 /* Perform the smoothing */
2054 result = Cudd_bddExistAbstract(mgr,f->node,cube);
2055 if (result == NULL) {
2056 Cudd_RecursiveDeref(mgr, cube);
2057 return(NULL);
2058 }
2059 cuddRef(result);
2060
2061 /* Get rid of temporary results */
2062 Cudd_RecursiveDeref(mgr, cube);
2063
2064 /* Build the bdd_t structure for the result */
2065 return(bdd_construct_bdd_t(mgr,result));
2066
2067} /* end of bdd_smooth */
2068
2069
2070/**Function********************************************************************
2071
2072 Synopsis [Existential abstraction of variables.]
2073
2074 SideEffects []
2075
2076******************************************************************************/
2077bdd_t *
2078bdd_smooth_with_cube(bdd_t *f, bdd_t *cube)
2079{
2080 DdNode *result;
2081 DdManager *mgr;
2082
2083 mgr = f->mgr;
2084
2085 /* Perform the smoothing */
2086 result = Cudd_bddExistAbstract(mgr,f->node,cube->node);
2087 if (result == NULL)
2088 return(NULL);
2089 cuddRef(result);
2090
2091 /* Build the bdd_t structure for the result */
2092 return(bdd_construct_bdd_t(mgr,result));
2093
2094} /* end of bdd_smooth_with_cube */
2095
2096
2097/**Function********************************************************************
2098
2099 Synopsis [Permutes the variables.]
2100
2101 SideEffects []
2102
2103******************************************************************************/
2104bdd_t *
2105bdd_substitute(
2106 bdd_t *f,
2107 array_t *old_array /* of bdd_t *'s */,
2108 array_t *new_array /* of bdd_t *'s */)
2109{
2110 int i,from,to;
2111 int *permut;
2112 bdd_t *variable;
2113 DdNode *result;
2114
2115 /* Make sure both arrays have the same number of elements. */
2116 assert(array_n(old_array) == array_n(new_array));
2117
2118 /* Allocate and fill the array with the trivial permutation. */
2119 permut = ALLOC(int, Cudd_ReadSize((DdManager *)f->mgr));
2120 for (i = 0; i < Cudd_ReadSize((DdManager *)f->mgr); i++) permut[i] = i;
2121
2122 /* Modify the permutation by looking at both arrays old and new. */
2123 for (i = 0; i < array_n(old_array); i++) {
2124 variable = array_fetch(bdd_t *, old_array, i);
2125 from = Cudd_Regular(variable->node)->index;
2126 variable = array_fetch(bdd_t *, new_array, i);
2127 /* Make sure the variable belongs to this manager. */
2128 assert(f->mgr == variable->mgr);
2129
2130 to = Cudd_Regular(variable->node)->index;
2131 permut[from] = to;
2132 }
2133
2134 result = Cudd_bddPermute(f->mgr,f->node,permut);
2135 FREE(permut);
2136 if (result == NULL) return(NULL);
2137 cuddRef(result);
2138 return(bdd_construct_bdd_t(f->mgr,result));
2139
2140} /* end of bdd_substitute */
2141
2142
2143/**Function********************************************************************
2144
2145 Synopsis [Permutes the variables.]
2146
2147 SideEffects []
2148
2149******************************************************************************/
2150bdd_t *
2151bdd_substitute_with_permut(
2152 bdd_t *f,
2153 int *permut)
2154{
2155 DdNode *result;
2156
2157 result = Cudd_bddPermute(f->mgr,f->node,permut);
2158 if (result == NULL) return(NULL);
2159 cuddRef(result);
2160 return(bdd_construct_bdd_t(f->mgr,result));
2161
2162} /* end of bdd_substitute_with_permut */
2163
2164
2165/**Function********************************************************************
2166
2167 Synopsis [Permutes the variables.]
2168
2169 SideEffects []
2170
2171******************************************************************************/
2172array_t *
2173bdd_substitute_array(
2174 array_t *f_array,
2175 array_t *old_array, /* of bdd_t *'s */
2176 array_t *new_array) /* of bdd_t *'s */
2177{
2178 int i;
2179 bdd_t *f, *new_;
2180 array_t *substitute_array = array_alloc(bdd_t *, 0);
2181
2182 arrayForEachItem(bdd_t *, f_array, i, f) {
2183 new_ = bdd_substitute(f, old_array, new_array);
2184 array_insert_last(bdd_t *, substitute_array, new_);
2185 }
2186 return(substitute_array);
2187
2188} /* end of bdd_substitute_array */
2189
2190
2191/**Function********************************************************************
2192
2193 Synopsis [Permutes the variables.]
2194
2195 SideEffects []
2196
2197******************************************************************************/
2198array_t *
2199bdd_substitute_array_with_permut(
2200 array_t *f_array,
2201 int *permut)
2202{
2203 int i;
2204 bdd_t *f, *new_;
2205 array_t *substitute_array = array_alloc(bdd_t *, 0);
2206
2207 arrayForEachItem(bdd_t *, f_array, i, f) {
2208 new_ = bdd_substitute_with_permut(f, permut);
2209 array_insert_last(bdd_t *, substitute_array, new_);
2210 }
2211 return(substitute_array);
2212
2213} /* end of bdd_substitute_array_with_permut */
2214
2215
2216/**Function********************************************************************
2217
2218 Synopsis [Returns the pointer of the BDD.]
2219
2220 SideEffects []
2221
2222******************************************************************************/
2223void *
2224bdd_pointer(bdd_t *f)
2225{
2226 return((void *)f->node);
2227
2228} /* end of bdd_pointer */
2229
2230
2231/**Function********************************************************************
2232
2233 Synopsis [Returns the Then branch of the BDD.]
2234
2235 SideEffects []
2236
2237******************************************************************************/
2238bdd_t *
2239bdd_then(bdd_t *f)
2240{
2241 DdNode *result;
2242
2243 result = Cudd_T(f->node);
2244 result = Cudd_NotCond(result,Cudd_IsComplement(f->node));
2245 cuddRef(result);
2246 return(bdd_construct_bdd_t(f->mgr,result));
2247
2248} /* end of bdd_then */
2249
2250
2251/**Function********************************************************************
2252
2253 Synopsis [Returns the BDD of the top variable.]
2254
2255 Description [Returns the BDD of the top variable of the argument. If
2256 the argument is constant, it returns the constant function itself.]
2257
2258 SideEffects []
2259
2260******************************************************************************/
2261bdd_t *
2262bdd_top_var(bdd_t *f)
2263{
2264 DdNode *result;
2265
2266 if (Cudd_IsConstant(f->node)) {
2267 result = f->node;
2268 } else {
2269 result = f->mgr->vars[Cudd_Regular(f->node)->index];
2270 }
2271 cuddRef(result);
2272 return(bdd_construct_bdd_t(f->mgr,result));
2273
2274} /* end of bdd_top_var */
2275
2276
2277/**Function********************************************************************
2278
2279 Synopsis [Computes the exclusive nor of two BDDs.]
2280
2281 SideEffects []
2282
2283******************************************************************************/
2284bdd_t *
2285bdd_xnor(bdd_t *f, bdd_t *g)
2286{
2287 DdNode *result;
2288
2289 /* Make sure both operands belong to the same manager. */
2290 assert(f->mgr == g->mgr);
2291
2292 result = Cudd_bddXnor(f->mgr,f->node,g->node);
2293 if (result == NULL) return(NULL);
2294 cuddRef(result);
2295 return(bdd_construct_bdd_t(f->mgr,result));
2296
2297} /* end of bdd_xnor */
2298
2299
2300/**Function********************************************************************
2301
2302 Synopsis [Computes the exclusive or of two BDDs.]
2303
2304 SideEffects []
2305
2306******************************************************************************/
2307bdd_t *
2308bdd_xor(bdd_t *f, bdd_t *g)
2309{
2310 DdNode *result;
2311
2312 /* Make sure both operands belong to the same manager. */
2313 assert(f->mgr == g->mgr);
2314
2315 result = Cudd_bddXor(f->mgr,f->node,g->node);
2316 if (result == NULL) return(NULL);
2317 cuddRef(result);
2318 return(bdd_construct_bdd_t(f->mgr,result));
2319
2320} /* end of bdd_xor */
2321
2322
2323/**Function********************************************************************
2324
2325 Synopsis [Returns the constant logical zero BDD.]
2326
2327 SideEffects [bdd_read_zero]
2328
2329******************************************************************************/
2330bdd_t *
2331bdd_zero(bdd_manager *mgr)
2332{
2333 DdManager *manager;
2334 DdNode *result;
2335
2336 manager = (DdManager *)mgr;
2337 Cudd_Ref(result = Cudd_Not(DD_ONE((manager))));
2338 return(bdd_construct_bdd_t(manager,result));
2339
2340} /* end of bdd_zero */
2341
2342
2343/**Function********************************************************************
2344
2345 Synopsis [Equality check.]
2346
2347 SideEffects []
2348
2349******************************************************************************/
2350boolean
2351bdd_equal(bdd_t *f, bdd_t *g)
2352{
2353 return(f->node == g->node);
2354
2355} /* end of bdd_equal */
2356
2357
2358/**Function********************************************************************
2359
2360 Synopsis [Equality check with don't care conditions.]
2361
2362 Description [Returns 1 if f equals g wherever careSet is 1.]
2363
2364 SideEffects [None: No new nodes are created.]
2365
2366******************************************************************************/
2367boolean
2368bdd_equal_mod_care_set(
2369 bdd_t *f,
2370 bdd_t *g,
2371 bdd_t *careSet)
2372{
2373 /* Make sure all operands belong to the same manager. */
2374 assert(f->mgr == g->mgr && f->mgr == careSet->mgr);
2375 return(Cudd_EquivDC(f->mgr, f->node, g->node, Cudd_Not(careSet->node)));
2376
2377} /* end of bdd_equal_mod_care_set */
2378
2379
2380/**Function********************************************************************
2381
2382 Synopsis [Returns a BDD included in the intersection of f and g.]
2383
2384 SideEffects []
2385
2386******************************************************************************/
2387bdd_t *
2388bdd_intersects(
2389 bdd_t *f,
2390 bdd_t *g)
2391{
2392 DdNode *result;
2393
2394 /* Make sure both operands belong to the same manager. */
2395 assert(f->mgr == g->mgr);
2396
2397 result = Cudd_bddIntersect(f->mgr,f->node,g->node);
2398 if (result == NULL) return(NULL);
2399 cuddRef(result);
2400 return(bdd_construct_bdd_t(f->mgr,result));
2401
2402} /* end of bdd_intersects */
2403
2404
2405/**Function********************************************************************
2406
2407 Synopsis [Returns a BDD included in f at minimum distance from g.]
2408
2409 SideEffects [The distance is returned as a side effect in dist.]
2410
2411******************************************************************************/
2412bdd_t *
2413bdd_closest_cube(
2414 bdd_t *f,
2415 bdd_t *g,
2416 int *dist)
2417{
2418 DdNode *result;
2419
2420 /* Make sure both operands belong to the same manager. */
2421 assert(f->mgr == g->mgr);
2422
2423 result = Cudd_bddClosestCube(f->mgr,f->node,g->node,dist);
2424 if (result == NULL) return(NULL);
2425 cuddRef(result);
2426 return(bdd_construct_bdd_t(f->mgr,result));
2427
2428} /* end of bdd_closest_cube */
2429
2430
2431/**Function********************************************************************
2432
2433 Synopsis [Checks a BDD for tautology.]
2434
2435 SideEffects []
2436
2437******************************************************************************/
2438boolean
2439bdd_is_tautology(bdd_t *f, boolean phase)
2440{
2441 if (phase) {
2442 return(f->node == DD_ONE(f->mgr));
2443 } else {
2444 return(f->node == Cudd_Not(DD_ONE(f->mgr)));
2445 }
2446
2447} /* end of bdd_is_tautology */
2448
2449
2450/**Function********************************************************************
2451
2452 Synopsis [Tests for containment of f in g.]
2453
2454 SideEffects [None: No new nodes are created.]
2455
2456******************************************************************************/
2457boolean
2458bdd_leq(
2459 bdd_t *f,
2460 bdd_t *g,
2461 boolean f_phase,
2462 boolean g_phase)
2463{
2464 DdNode *newf, *newg;
2465
2466 /* Make sure both operands belong to the same manager. */
2467 assert(f->mgr == g->mgr);
2468 newf = Cudd_NotCond(f->node, !f_phase);
2469 newg = Cudd_NotCond(g->node, !g_phase);
2470
2471 return(Cudd_bddLeq(f->mgr,newf,newg));
2472
2473} /* end of bdd_leq */
2474
2475
2476/**Function********************************************************************
2477
2478 Synopsis [Implication check with don't care conditions.]
2479
2480 Description [Returns 1 if f implies g wherever careSet is 1.]
2481
2482 SideEffects [None: No new nodes are created.]
2483
2484******************************************************************************/
2485boolean
2486bdd_lequal_mod_care_set(
2487 bdd_t *f,
2488 bdd_t *g,
2489 boolean f_phase,
2490 boolean g_phase,
2491 bdd_t *careSet)
2492{
2493 DdNode *newf, *newg;
2494
2495 /* Make sure all operands belong to the same manager. */
2496 assert(f->mgr == g->mgr && f->mgr == careSet->mgr);
2497 newf = Cudd_NotCond(f->node, !f_phase);
2498 newg = Cudd_NotCond(g->node, !g_phase);
2499
2500 return(Cudd_bddLeqUnless(f->mgr, newf, newg, Cudd_Not(careSet->node)));
2501
2502} /* end of bdd_lequal_mod_care_set */
2503
2504
2505/**Function********************************************************************
2506
2507 Synopsis [Tests for containment of f in g.]
2508
2509 SideEffects []
2510
2511******************************************************************************/
2512boolean
2513bdd_leq_array(
2514 bdd_t *f,
2515 array_t *g_array,
2516 boolean f_phase,
2517 boolean g_phase)
2518{
2519 int i;
2520 bdd_t *g;
2521 boolean result;
2522
2523 arrayForEachItem(bdd_t *, g_array, i, g) {
2524 result = bdd_leq(f, g, f_phase, g_phase);
2525 if (g_phase) {
2526 if (!result)
2527 return(0);
2528 } else {
2529 if (result)
2530 return(1);
2531 }
2532 }
2533 if (g_phase)
2534 return(1);
2535 else
2536 return(0);
2537
2538} /* end of bdd_leq_array */
2539
2540
2541/**Function********************************************************************
2542
2543 Synopsis [Counts the number of minterms in the on set.]
2544
2545 SideEffects []
2546
2547******************************************************************************/
2548double
2549bdd_count_onset(
2550 bdd_t *f,
2551 array_t *var_array /* of bdd_t *'s */)
2552{
2553 return(Cudd_CountMinterm(f->mgr,f->node,array_n(var_array)));
2554
2555} /* end of bdd_count_onset */
2556
2557
2558/**Function********************************************************************
2559
2560 Synopsis [Counts the number of minterms in the on set.]
2561
2562 SideEffects []
2563
2564******************************************************************************/
2565int
2566bdd_epd_count_onset(
2567 bdd_t *f,
2568 array_t *var_array /* of bdd_t *'s */,
2569 EpDouble *epd)
2570{
2571 return(Cudd_EpdCountMinterm(f->mgr,f->node,array_n(var_array),epd));
2572
2573} /* end of bdd_epd_count_onset */
2574
2575
2576/**Function********************************************************************
2577
2578 Synopsis [Returns the free field of the BDD.]
2579
2580 SideEffects []
2581
2582******************************************************************************/
2583int
2584bdd_get_free(bdd_t *f)
2585{
2586 return(f->free);
2587
2588} /* end of bdd_get_free */
2589
2590
2591/**Function********************************************************************
2592
2593 Synopsis [Obtains the manager of the BDD.]
2594
2595 SideEffects []
2596
2597******************************************************************************/
2598bdd_manager *
2599bdd_get_manager(bdd_t *f)
2600{
2601 return(f->mgr);
2602
2603} /* end of bdd_get_manager */
2604
2605
2606/**Function********************************************************************
2607
2608 Synopsis [Returns the node of the BDD.]
2609
2610 SideEffects [Sets is_complemented.]
2611
2612******************************************************************************/
2613bdd_node *
2614bdd_get_node(
2615 bdd_t *f,
2616 boolean *is_complemented /* return */)
2617{
2618 if (Cudd_IsComplement(f->node)) {
2619 *is_complemented = TRUE;
2620 return(Cudd_Regular(f->node));
2621 }
2622 *is_complemented = FALSE;
2623 return(f->node);
2624
2625} /* end of bdd_get_node */
2626
2627
2628/**Function********************************************************************
2629
2630 Synopsis [Obtains the support of the BDD.]
2631
2632 SideEffects []
2633
2634******************************************************************************/
2635var_set_t *
2636bdd_get_support(bdd_t *f)
2637{
2638 int i, size, *support;
2639 var_set_t *result;
2640
2641 size = (unsigned int)Cudd_ReadSize((DdManager *)f->mgr);
2642 support = Cudd_SupportIndex(f->mgr,f->node);
2643 if (support == NULL) return(NULL);
2644
2645 result = var_set_new((int) f->mgr->size);
2646 for (i = 0; i < size; i++) {
2647 if (support[i])
2648 var_set_set_elt(result, i);
2649 }
2650 FREE(support);
2651
2652 return(result);
2653
2654} /* end of bdd_get_support */
2655
2656
2657/**Function********************************************************************
2658
2659 Synopsis [Checks whether a BDD is a support of f.]
2660
2661 SideEffects []
2662
2663******************************************************************************/
2664int
2665bdd_is_support_var(bdd_t *f, bdd_t *var)
2666{
2667 return(bdd_is_support_var_id(f, bdd_top_var_id(var)));
2668
2669} /* end of bdd_is_support_var */
2670
2671
2672/**Function********************************************************************
2673
2674 Synopsis [Checks whether a BDD index is a support of f.]
2675
2676 SideEffects []
2677
2678******************************************************************************/
2679int
2680bdd_is_support_var_id(bdd_t *f, int index)
2681{
2682 DdNode *support, *scan;
2683
2684 support = Cudd_Support(f->mgr,f->node);
2685 if (support == NULL) return(-1);
2686 cuddRef(support);
2687
2688 scan = support;
2689 while (!cuddIsConstant(scan)) {
2690 if (scan->index == index) {
2691 Cudd_RecursiveDeref(f->mgr,support);
2692 return(1);
2693 }
2694 scan = cuddT(scan);
2695 }
2696 Cudd_RecursiveDeref(f->mgr,support);
2697
2698 return(0);
2699
2700} /* end of bdd_is_support_var_id */
2701
2702
2703/**Function********************************************************************
2704
2705 Synopsis [Obtains the array of indices of an array of variables.]
2706
2707 SideEffects []
2708
2709******************************************************************************/
2710array_t *
2711bdd_get_varids(array_t *var_array)
2712{
2713 int i;
2714 int index;
2715 bdd_t *var;
2716 array_t *result = array_alloc(int,array_n(var_array));
2717
2718 for (i = 0; i < array_n(var_array); i++) {
2719 var = array_fetch(bdd_t *, var_array, i);
2720 index = Cudd_Regular(var->node)->index;
2721 (void) array_insert_last(int, result, index);
2722 }
2723 return(result);
2724
2725} /* end of bdd_get_varids */
2726
2727
2728/**Function********************************************************************
2729
2730 Synopsis [Returns the number of variables in the manager.]
2731
2732 SideEffects []
2733
2734******************************************************************************/
2735unsigned int
2736bdd_num_vars(bdd_manager *mgr)
2737{
2738 unsigned int size;
2739 size = (unsigned int)Cudd_ReadSize((DdManager *)mgr);
2740 return(size);
2741
2742} /* end of bdd_num_vars */
2743
2744
2745/**Function********************************************************************
2746
2747 Synopsis [Prints the BDD.]
2748
2749 SideEffects []
2750
2751******************************************************************************/
2752void
2753bdd_print(bdd_t *f)
2754{
2755 (void) cuddP(f->mgr,f->node);
2756
2757} /* end of bdd_print */
2758
2759
2760/**Function********************************************************************
2761
2762 Synopsis [Prints statistics about the package.]
2763
2764 SideEffects []
2765
2766******************************************************************************/
2767void
2768bdd_print_stats(bdd_manager *mgr, FILE *file)
2769{
2770 Cudd_PrintInfo((DdManager *)mgr, file);
2771
2772 /* Print some guidance to the parameters */
2773 (void) fprintf(file, "\nMore detailed information about the semantics ");
2774 (void) fprintf(file, "and values of these parameters\n");
2775 (void) fprintf(file, "can be found in the documentation about the CU ");
2776 (void) fprintf(file, "Decision Diagram Package.\n");
2777
2778 return;
2779
2780} /* end of bdd_print_stats */
2781
2782
2783/**Function********************************************************************
2784
2785 Synopsis [Sets the internal parameters of the package to the given values.]
2786
2787 Description [The CUDD package has a set of parameters that can be assigned
2788 different values. This function receives a table which maps strings to
2789 values and sets the parameters represented by the strings to the pertinent
2790 values. Some basic type checking is done. It returns 1 if everything is
2791 correct and 0 otherwise.]
2792
2793 SideEffects []
2794
2795******************************************************************************/
2796int
2797bdd_set_parameters(
2798 bdd_manager *mgr,
2799 avl_tree *valueTable,
2800 FILE *file)
2801{
2802 Cudd_ReorderingType reorderMethod;
2803 Cudd_ReorderingType zddReorderMethod;
2804 st_table *newValueTable;
2805 st_generator *stgen;
2806 avl_generator *avlgen;
2807 char *paramName;
2808 char *paramValue;
2809
2810 /* Initial value of the variables. */
2811 reorderMethod = CUDD_REORDER_SAME;
2812 zddReorderMethod = CUDD_REORDER_SAME;
2813
2814 /* Build a new table with the parameter names but with
2815 ** the prefix removed. */
2816 newValueTable = st_init_table(st_ptrcmp, st_ptrhash);
2817 avl_foreach_item(valueTable, avlgen, AVL_FORWARD, (char **)&paramName,
2818 (char **)&paramValue) {
2819 if (strncmp(paramName, "BDD.", 4) == 0) {
2820 st_insert(newValueTable, (char *)&paramName[4],
2821 (char *)paramValue);
2822 }
2823 }
2824
2825 st_foreach_item(newValueTable, stgen, &paramName, &paramValue) {
2826 int uvalue;
2827 char *invalidChar;
2828
2829 invalidChar = NIL(char);
2830
2831 if (strcmp(paramName, "Hard limit for cache size") == 0) {
2832
2833 uvalue = strtol(paramValue, &invalidChar, 10);
2834 if (*invalidChar || uvalue < 0) {
2835 InvalidType(file, "Hard limit for cache size",
2836 "unsigned integer");
2837 }
2838 else {
2839 Cudd_SetMaxCacheHard((DdManager *) mgr, (unsigned int) uvalue);
2840 }
2841 }
2842 else if (strcmp(paramName, "Cache hit threshold for resizing") == 0) {
2843
2844 uvalue = strtol(paramValue, &invalidChar, 10);
2845 if (*invalidChar || uvalue < 0) {
2846 InvalidType(file, "Cache hit threshold for resizing",
2847 "unsigned integer");
2848 }
2849 else {
2850 Cudd_SetMinHit((DdManager *) mgr, (unsigned int) uvalue);
2851 }
2852 }
2853 else if (strcmp(paramName, "Garbage collection enabled") == 0) {
2854 if (strcmp(paramValue, "yes") == 0) {
2855 Cudd_EnableGarbageCollection((DdManager *) mgr);
2856 }
2857 else if (strcmp(paramValue, "no") == 0) {
2858 Cudd_DisableGarbageCollection((DdManager *) mgr);
2859 }
2860 else {
2861 InvalidType(file, "Garbage collection enabled", "(yes,no)");
2862 }
2863 }
2864 else if (strcmp(paramName, "Limit for fast unique table growth")
2865 == 0) {
2866
2867 uvalue = strtol(paramValue, &invalidChar, 10);
2868 if (*invalidChar || uvalue < 0) {
2869 InvalidType(file, "Limit for fast unique table growth",
2870 "unsigned integer");
2871 }
2872 else {
2873 Cudd_SetLooseUpTo((DdManager *) mgr, (unsigned int) uvalue);
2874 }
2875 }
2876 else if (strcmp(paramName,
2877 "Maximum number of variables sifted per reordering")
2878 == 0) {
2879
2880 uvalue = strtol(paramValue, &invalidChar, 10);
2881 if (*invalidChar || uvalue < 0) {
2882 InvalidType(file, "Maximum number of variables sifted per reordering",
2883 "unsigned integer");
2884 }
2885 else {
2886 Cudd_SetSiftMaxVar((DdManager *) mgr, uvalue);
2887 }
2888 }
2889 else if (strcmp(paramName,
2890 "Maximum number of variable swaps per reordering")
2891 == 0) {
2892
2893 uvalue = strtol(paramValue, &invalidChar, 10);
2894 if (*invalidChar || uvalue < 0) {
2895 InvalidType(file, "Maximum number of variable swaps per reordering",
2896 "unsigned integer");
2897 }
2898 else {
2899 Cudd_SetSiftMaxSwap((DdManager *) mgr, uvalue);
2900 }
2901 }
2902 else if (strcmp(paramName,
2903 "Maximum growth while sifting a variable") == 0) {
2904 double value;
2905
2906 value = strtod(paramValue, &invalidChar);
2907 if (*invalidChar) {
2908 InvalidType(file, "Maximum growth while sifting a variable",
2909 "real");
2910 }
2911 else {
2912 Cudd_SetMaxGrowth((DdManager *) mgr, value);
2913 }
2914 }
2915 else if (strcmp(paramName, "Dynamic reordering of BDDs enabled")
2916 == 0) {
2917 if (strcmp(paramValue, "yes") == 0) {
2918 Cudd_AutodynEnable((DdManager *) mgr, reorderMethod);
2919 }
2920 else if (strcmp(paramValue, "no") == 0) {
2921 Cudd_AutodynDisable((DdManager *) mgr);
2922 }
2923 else {
2924 InvalidType(file, "Dynamic reordering of BDDs enabled",
2925 "(yes,no)");
2926 }
2927 }
2928 else if (strcmp(paramName, "Default BDD reordering method") == 0) {
2929 Cudd_ReorderingType reorderInt;
2930
2931 reorderMethod = (Cudd_ReorderingType) strtol(paramValue,
2932 &invalidChar, 10);
2933 if (*invalidChar || reorderMethod < 0) {
2934 InvalidType(file, "Default BDD reordering method", "integer");
2935 }
2936 else {
2937 if (Cudd_ReorderingStatus((DdManager *) mgr, &reorderInt)) {
2938 Cudd_AutodynEnable((DdManager *) mgr, reorderMethod);
2939 }
2940 }
2941 }
2942 else if (strcmp(paramName, "Dynamic reordering of ZDDs enabled")
2943 == 0) {
2944 if (strcmp(paramValue, "yes") == 0) {
2945 Cudd_AutodynEnableZdd((DdManager *) mgr, zddReorderMethod);
2946 }
2947 else if (strcmp(paramValue, "no") == 0) {
2948 Cudd_AutodynDisableZdd((DdManager *) mgr);
2949 }
2950 else {
2951 InvalidType(file, "Dynamic reordering of ZDDs enabled", "(yes,no)");
2952 }
2953 }
2954 else if (strcmp(paramName, "Default ZDD reordering method") == 0) {
2955 Cudd_ReorderingType reorderInt;
2956
2957 zddReorderMethod = (Cudd_ReorderingType) strtol(paramValue,
2958 &invalidChar, 10);
2959 if (*invalidChar || zddReorderMethod < 0) {
2960 InvalidType(file, "Default ZDD reordering method", "integer");
2961 }
2962 else {
2963 if (Cudd_ReorderingStatusZdd((DdManager *) mgr, &reorderInt)) {
2964 Cudd_AutodynEnableZdd((DdManager *) mgr, zddReorderMethod);
2965 }
2966 }
2967 }
2968 else if (strcmp(paramName, "Realignment of ZDDs to BDDs enabled")
2969 == 0) {
2970 if (strcmp(paramValue, "yes") == 0) {
2971 Cudd_zddRealignEnable((DdManager *) mgr);
2972 }
2973 else if (strcmp(paramValue, "no") == 0) {
2974 Cudd_zddRealignDisable((DdManager *) mgr);
2975 }
2976 else {
2977 InvalidType(file, "Realignment of ZDDs to BDDs enabled",
2978 "(yes,no)");
2979 }
2980 }
2981 else if (strcmp(paramName,
2982 "Dead node counted in triggering reordering") == 0) {
2983 if (strcmp(paramValue, "yes") == 0) {
2984 Cudd_TurnOnCountDead((DdManager *) mgr);
2985 }
2986 else if (strcmp(paramValue, "no") == 0) {
2987 Cudd_TurnOffCountDead((DdManager *) mgr);
2988 }
2989 else {
2990 InvalidType(file,
2991 "Dead node counted in triggering reordering",
2992 "(yes,no)");
2993 }
2994 }
2995 else if (strcmp(paramName, "Group checking criterion") == 0) {
2996
2997 uvalue = strtol(paramValue, &invalidChar, 10);
2998 if (*invalidChar || uvalue < 0) {
2999 InvalidType(file, "Group checking criterion", "integer");
3000 }
3001 else {
3002 Cudd_SetGroupcheck((DdManager *) mgr, (Cudd_AggregationType) uvalue);
3003 }
3004 }
3005 else if (strcmp(paramName, "Recombination threshold") == 0) {
3006
3007 uvalue = strtol(paramValue, &invalidChar, 10);
3008 if (*invalidChar || uvalue < 0) {
3009 InvalidType(file, "Recombination threshold", "integer");
3010 }
3011 else {
3012 Cudd_SetRecomb((DdManager *) mgr, uvalue);
3013 }
3014 }
3015 else if (strcmp(paramName, "Symmetry violation threshold") == 0) {
3016
3017 uvalue = strtol(paramValue, &invalidChar, 10);
3018 if (*invalidChar || uvalue < 0) {
3019 InvalidType(file, "Symmetry violation threshold", "integer");
3020 }
3021 else {
3022 Cudd_SetSymmviolation((DdManager *) mgr, uvalue);
3023 }
3024 }
3025 else if (strcmp(paramName, "Arc violation threshold") == 0) {
3026
3027 uvalue = strtol(paramValue, &invalidChar, 10);
3028 if (*invalidChar || uvalue < 0) {
3029 InvalidType(file, "Arc violation threshold", "integer");
3030 }
3031 else {
3032 Cudd_SetArcviolation((DdManager *) mgr, uvalue);
3033 }
3034 }
3035 else if (strcmp(paramName, "GA population size") == 0) {
3036
3037 uvalue = strtol(paramValue, &invalidChar, 10);
3038 if (*invalidChar || uvalue < 0) {
3039 InvalidType(file, "GA population size", "integer");
3040 }
3041 else {
3042 Cudd_SetPopulationSize((DdManager *) mgr, uvalue);
3043 }
3044 }
3045 else if (strcmp(paramName, "Number of crossovers for GA") == 0) {
3046
3047 uvalue = strtol(paramValue, &invalidChar, 10);
3048 if (*invalidChar || uvalue < 0) {
3049 InvalidType(file, "Number of crossovers for GA", "integer");
3050 }
3051 else {
3052 Cudd_SetNumberXovers((DdManager *) mgr, uvalue);
3053 }
3054 }
3055 else if (strcmp(paramName, "Next reordering threshold") == 0) {
3056
3057 uvalue = (unsigned int) strtol(paramValue, &invalidChar, 10);
3058 if (*invalidChar || uvalue < 0) {
3059 InvalidType(file, "Next reordering threshold", "integer");
3060 }
3061 else {
3062 Cudd_SetNextReordering((DdManager *) mgr, uvalue);
3063 }
3064 }
3065 else {
3066 (void) fprintf(file, "Warning: Parameter %s not recognized.",
3067 paramName);
3068 (void) fprintf(file, " Ignored.\n");
3069 }
3070 } /* end of st_foreach_item */
3071
3072 /* Clean up. */
3073 st_free_table(newValueTable);
3074
3075 return(1);
3076
3077} /* end of bdd_set_parameters */
3078
3079
3080/**Function********************************************************************
3081
3082 Synopsis [Computes the number of nodes of a BDD.]
3083
3084 SideEffects []
3085
3086******************************************************************************/
3087int
3088bdd_size(bdd_t *f)
3089{
3090 return(Cudd_DagSize(f->node));
3091
3092} /* end of bdd_size */
3093
3094
3095/**Function********************************************************************
3096
3097 Synopsis [Computes the number of nodes of a BDD.]
3098
3099 SideEffects []
3100
3101******************************************************************************/
3102int
3103bdd_node_size(bdd_node *f)
3104{
3105 return(Cudd_DagSize((DdNode *) f));
3106
3107} /* end of bdd_node_size */
3108
3109
3110/**Function********************************************************************
3111
3112 Synopsis [Computes the shared size of an array of BDDs.]
3113
3114 Description [Computes the shared size of an array of BDDs. Returns
3115 CUDD_OUT_OF_MEM in case of failure.]
3116
3117 SideEffects []
3118
3119******************************************************************************/
3120long
3121bdd_size_multiple(array_t *bddArray)
3122{
3123 DdNode **nodeArray;
3124 bdd_t *bddUnit;
3125 long result;
3126 int i;
3127
3128 nodeArray = ALLOC(DdNode *, array_n(bddArray));
3129 if (nodeArray == NULL) return(CUDD_OUT_OF_MEM);
3130 for (i = 0; i < array_n(bddArray); i++) {
3131 bddUnit = array_fetch(bdd_t *, bddArray, i);
3132 nodeArray[i] = bddUnit->node;
3133 }
3134
3135 result = Cudd_SharingSize(nodeArray,array_n(bddArray));
3136
3137 /* Clean up */
3138 FREE(nodeArray);
3139
3140 return(result);
3141
3142} /* end of bdd_size_multiple */
3143
3144
3145/**Function********************************************************************
3146
3147 Synopsis [Accesses the id of the top variable.]
3148
3149 SideEffects []
3150
3151******************************************************************************/
3152bdd_variableId
3153bdd_top_var_id(bdd_t *f)
3154{
3155 return(Cudd_Regular(f->node)->index);
3156
3157} /* end of bdd_top_var_id */
3158
3159
3160/**Function********************************************************************
3161
3162 Synopsis [Accesses the external_hooks field of the manager.]
3163
3164 SideEffects []
3165
3166******************************************************************************/
3167bdd_external_hooks *
3168bdd_get_external_hooks(bdd_manager *mgr)
3169{
3170 return((bdd_external_hooks *)(((DdManager *)mgr)->hooks));
3171
3172} /* end of bdd_get_external_hooks */
3173
3174
3175/**Function********************************************************************
3176
3177 Synopsis [Adds a function to a hook.]
3178
3179 SideEffects []
3180
3181******************************************************************************/
3182int
3183bdd_add_hook(
3184 bdd_manager *mgr,
3185 int (*procedure)(bdd_manager *, char *, void *),
3186 bdd_hook_type_t whichHook)
3187{
3188 int retval;
3189 Cudd_HookType hook;
3190 switch (whichHook) {
3191 case BDD_PRE_GC_HOOK: hook = CUDD_PRE_GC_HOOK; break;
3192 case BDD_POST_GC_HOOK: hook = CUDD_POST_GC_HOOK; break;
3193 case BDD_PRE_REORDERING_HOOK: hook = CUDD_PRE_REORDERING_HOOK; break;
3194 case BDD_POST_REORDERING_HOOK: hook = CUDD_POST_REORDERING_HOOK; break;
3195 default: fprintf(stderr, "Dont know which hook"); return 0;
3196 }
3197
3198 retval = Cudd_AddHook((DdManager *)mgr, (DD_HFP)procedure, hook);
3199 return retval;
3200
3201} /* end of bdd_add_hook */
3202
3203
3204/**Function********************************************************************
3205
3206 Synopsis [Removes the function from the hook.]
3207
3208 SideEffects []
3209
3210******************************************************************************/
3211int
3212bdd_remove_hook(
3213 bdd_manager *mgr,
3214 int (*procedure)(bdd_manager *, char *, void *),
3215 bdd_hook_type_t whichHook)
3216{
3217 int retval;
3218 Cudd_HookType hook;
3219 switch (whichHook) {
3220 case BDD_PRE_GC_HOOK: hook = CUDD_PRE_GC_HOOK; break;
3221 case BDD_POST_GC_HOOK: hook = CUDD_POST_GC_HOOK; break;
3222 case BDD_PRE_REORDERING_HOOK: hook = CUDD_PRE_REORDERING_HOOK; break;
3223 case BDD_POST_REORDERING_HOOK: hook = CUDD_POST_REORDERING_HOOK; break;
3224 default: fprintf(stderr, "Dont know which hook"); return 0;
3225 }
3226 retval = Cudd_RemoveHook((DdManager *)mgr, (DD_HFP)procedure, hook);
3227 return retval;
3228
3229} /* end of bdd_remove_hook */
3230
3231
3232/**Function********************************************************************
3233
3234 Synopsis [Enables reporting of reordering stats.]
3235
3236 SideEffects []
3237
3238******************************************************************************/
3239int
3240bdd_enable_reordering_reporting(bdd_manager *mgr)
3241{
3242 int retval;
3243 retval = Cudd_EnableReorderingReporting((DdManager *) mgr);
3244 return retval;
3245
3246} /* end of bdd_enable_reordering_reporting */
3247
3248
3249/**Function********************************************************************
3250
3251 Synopsis [Disables reporting of reordering stats.]
3252
3253 SideEffects []
3254
3255******************************************************************************/
3256int
3257bdd_disable_reordering_reporting(bdd_manager *mgr)
3258{
3259 int retval;
3260 retval = Cudd_DisableReorderingReporting((DdManager *) mgr);
3261 return retval;
3262
3263} /* end of bdd_disable_reordering_reporting */
3264
3265
3266/**Function********************************************************************
3267
3268 Synopsis [ Reporting of reordering stats.]
3269
3270 SideEffects []
3271
3272******************************************************************************/
3273bdd_reorder_verbosity_t
3274bdd_reordering_reporting(bdd_manager *mgr)
3275{
3276 int retval;
3277 bdd_reorder_verbosity_t reorderVerbosity;
3278 retval = Cudd_ReorderingReporting((DdManager *) mgr);
3279 switch(retval) {
3280 case 0: reorderVerbosity = BDD_REORDER_NO_VERBOSITY; break;
3281 case 1: reorderVerbosity = BDD_REORDER_VERBOSITY; break;
3282 default: reorderVerbosity = BDD_REORDER_VERBOSITY_DEFAULT; break;
3283 }
3284 return reorderVerbosity;
3285
3286} /* end of bdd_reordering_reporting */
3287
3288
3289/**Function********************************************************************
3290
3291 Synopsis [Turns on or off garbage collection.]
3292
3293 SideEffects []
3294
3295******************************************************************************/
3296void
3297bdd_set_gc_mode(bdd_manager *mgr, boolean no_gc)
3298{
3299 if (no_gc) {
3300 Cudd_DisableGarbageCollection((DdManager *) mgr);
3301 } else {
3302 Cudd_EnableGarbageCollection((DdManager *) mgr);
3303 }
3304 return;
3305
3306} /* end of bdd_set_gc_mode */
3307
3308
3309/**Function********************************************************************
3310
3311 Synopsis [Reorders the BDD pool.]
3312
3313 SideEffects []
3314
3315******************************************************************************/
3316void
3317bdd_dynamic_reordering(
3318 bdd_manager *mgr_,
3319 bdd_reorder_type_t algorithm_type,
3320 bdd_reorder_verbosity_t verbosity)
3321{
3322 DdManager *mgr;
3323
3324 mgr = (DdManager *)mgr_;
3325
3326 switch (algorithm_type) {
3327 case BDD_REORDER_SIFT:
3328 Cudd_AutodynEnable(mgr, CUDD_REORDER_SIFT);
3329 break;
3330 case BDD_REORDER_WINDOW:
3331 case BDD_REORDER_WINDOW3_CONV:
3332 Cudd_AutodynEnable(mgr, CUDD_REORDER_WINDOW3_CONV);
3333 break;
3334 case BDD_REORDER_NONE:
3335 Cudd_AutodynDisable(mgr);
3336 break;
3337 case BDD_REORDER_SAME:
3338 Cudd_AutodynEnable(mgr, CUDD_REORDER_SAME);
3339 break;
3340 case BDD_REORDER_RANDOM:
3341 Cudd_AutodynEnable(mgr, CUDD_REORDER_RANDOM);
3342 break;
3343 case BDD_REORDER_RANDOM_PIVOT:
3344 Cudd_AutodynEnable(mgr, CUDD_REORDER_RANDOM_PIVOT);
3345 break;
3346 case BDD_REORDER_SIFT_CONVERGE:
3347 Cudd_AutodynEnable(mgr,CUDD_REORDER_SIFT_CONVERGE);
3348 break;
3349 case BDD_REORDER_SYMM_SIFT:
3350 Cudd_AutodynEnable(mgr, CUDD_REORDER_SYMM_SIFT);
3351 break;
3352 case BDD_REORDER_SYMM_SIFT_CONV:
3353 Cudd_AutodynEnable(mgr, CUDD_REORDER_SYMM_SIFT_CONV);
3354 break;
3355 case BDD_REORDER_WINDOW2:
3356 Cudd_AutodynEnable(mgr, CUDD_REORDER_WINDOW2);
3357 break;
3358 case BDD_REORDER_WINDOW4:
3359 Cudd_AutodynEnable(mgr, CUDD_REORDER_WINDOW4);
3360 break;
3361 case BDD_REORDER_WINDOW2_CONV:
3362 Cudd_AutodynEnable(mgr, CUDD_REORDER_WINDOW2_CONV);
3363 break;
3364 case BDD_REORDER_WINDOW3:
3365 Cudd_AutodynEnable(mgr, CUDD_REORDER_WINDOW3);
3366 break;
3367 case BDD_REORDER_WINDOW4_CONV:
3368 Cudd_AutodynEnable(mgr, CUDD_REORDER_WINDOW4_CONV);
3369 break;
3370 case BDD_REORDER_GROUP_SIFT:
3371 Cudd_AutodynEnable(mgr, CUDD_REORDER_GROUP_SIFT);
3372 break;
3373 case BDD_REORDER_GROUP_SIFT_CONV:
3374 Cudd_AutodynEnable(mgr, CUDD_REORDER_GROUP_SIFT_CONV);
3375 break;
3376 case BDD_REORDER_ANNEALING:
3377 Cudd_AutodynEnable(mgr, CUDD_REORDER_ANNEALING);
3378 break;
3379 case BDD_REORDER_GENETIC:
3380 Cudd_AutodynEnable(mgr, CUDD_REORDER_GENETIC);
3381 break;
3382 case BDD_REORDER_EXACT:
3383 Cudd_AutodynEnable(mgr, CUDD_REORDER_EXACT);
3384 break;
3385 case BDD_REORDER_LAZY_SIFT:
3386 Cudd_AutodynEnable(mgr, CUDD_REORDER_LAZY_SIFT);
3387 break;
3388 default:
3389 fprintf(stderr,"CU DD Package: Reordering algorithm not considered\n");
3390 }
3391
3392 if (verbosity == BDD_REORDER_NO_VERBOSITY) {
3393 (void) bdd_disable_reordering_reporting((DdManager *)mgr);
3394 } else if (verbosity == BDD_REORDER_VERBOSITY) {
3395 (void) bdd_enable_reordering_reporting((DdManager *)mgr);
3396 }
3397
3398} /* end of bdd_dynamic_reordering */
3399
3400
3401/**Function********************************************************************
3402
3403 Synopsis [Reorders the ZDD pool.]
3404
3405 SideEffects []
3406
3407******************************************************************************/
3408void
3409bdd_dynamic_reordering_zdd(
3410 bdd_manager *mgr_,
3411 bdd_reorder_type_t algorithm_type,
3412 bdd_reorder_verbosity_t verbosity)
3413{
3414 DdManager *mgr;
3415
3416 mgr = (DdManager *)mgr_;
3417
3418 switch (algorithm_type) {
3419 case BDD_REORDER_SIFT:
3420 Cudd_AutodynEnableZdd(mgr, CUDD_REORDER_SIFT);
3421 break;
3422 case BDD_REORDER_WINDOW:
3423 case BDD_REORDER_WINDOW3_CONV:
3424 Cudd_AutodynEnableZdd(mgr, CUDD_REORDER_WINDOW3_CONV);
3425 break;
3426 case BDD_REORDER_NONE:
3427 Cudd_AutodynDisable(mgr);
3428 break;
3429 case BDD_REORDER_SAME:
3430 Cudd_AutodynEnableZdd(mgr, CUDD_REORDER_SAME);
3431 break;
3432 case BDD_REORDER_RANDOM:
3433 Cudd_AutodynEnableZdd(mgr, CUDD_REORDER_RANDOM);
3434 break;
3435 case BDD_REORDER_RANDOM_PIVOT:
3436 Cudd_AutodynEnableZdd(mgr, CUDD_REORDER_RANDOM_PIVOT);
3437 break;
3438 case BDD_REORDER_SIFT_CONVERGE:
3439 Cudd_AutodynEnableZdd(mgr,CUDD_REORDER_SIFT_CONVERGE);
3440 break;
3441 case BDD_REORDER_SYMM_SIFT:
3442 Cudd_AutodynEnableZdd(mgr, CUDD_REORDER_SYMM_SIFT);
3443 break;
3444 case BDD_REORDER_SYMM_SIFT_CONV:
3445 Cudd_AutodynEnableZdd(mgr, CUDD_REORDER_SYMM_SIFT_CONV);
3446 break;
3447 case BDD_REORDER_WINDOW2:
3448 Cudd_AutodynEnableZdd(mgr, CUDD_REORDER_WINDOW2);
3449 break;
3450 case BDD_REORDER_WINDOW4:
3451 Cudd_AutodynEnableZdd(mgr, CUDD_REORDER_WINDOW4);
3452 break;
3453 case BDD_REORDER_WINDOW2_CONV:
3454 Cudd_AutodynEnableZdd(mgr, CUDD_REORDER_WINDOW2_CONV);
3455 break;
3456 case BDD_REORDER_WINDOW3:
3457 Cudd_AutodynEnableZdd(mgr, CUDD_REORDER_WINDOW3);
3458 break;
3459 case BDD_REORDER_WINDOW4_CONV:
3460 Cudd_AutodynEnableZdd(mgr, CUDD_REORDER_WINDOW4_CONV);
3461 break;
3462 case BDD_REORDER_GROUP_SIFT:
3463 Cudd_AutodynEnableZdd(mgr, CUDD_REORDER_GROUP_SIFT);
3464 break;
3465 case BDD_REORDER_GROUP_SIFT_CONV:
3466 Cudd_AutodynEnableZdd(mgr, CUDD_REORDER_GROUP_SIFT_CONV);
3467 break;
3468 case BDD_REORDER_ANNEALING:
3469 Cudd_AutodynEnableZdd(mgr, CUDD_REORDER_ANNEALING);
3470 break;
3471 case BDD_REORDER_GENETIC:
3472 Cudd_AutodynEnableZdd(mgr, CUDD_REORDER_GENETIC);
3473 break;
3474 case BDD_REORDER_EXACT:
3475 Cudd_AutodynEnableZdd(mgr, CUDD_REORDER_EXACT);
3476 break;
3477 default:
3478 fprintf(stderr,"CU DD Package: Reordering algorithm not considered\n");
3479 }
3480 if (verbosity == BDD_REORDER_NO_VERBOSITY) {
3481 (void) bdd_disable_reordering_reporting((DdManager *)mgr);
3482 } else if (verbosity == BDD_REORDER_VERBOSITY) {
3483 (void) bdd_enable_reordering_reporting((DdManager *)mgr);
3484 }
3485
3486} /* end of bdd_dynamic_reordering_zdd */
3487
3488
3489/**Function********************************************************************
3490
3491 Synopsis [Calls reordering explicitly.]
3492
3493 SideEffects []
3494
3495******************************************************************************/
3496void
3497bdd_reorder(bdd_manager *mgr)
3498{
3499 /* 10 = whatever (Verbatim from file ddTable.c) */
3500 (void) Cudd_ReduceHeap((DdManager *)mgr,((DdManager *)mgr)->autoMethod,10);
3501 return;
3502
3503} /* end of bdd_reorder */
3504
3505
3506/**Function********************************************************************
3507
3508 Synopsis [Gets the id variable for one level in the BDD.]
3509
3510 SideEffects []
3511
3512******************************************************************************/
3513bdd_variableId
3514bdd_get_id_from_level(bdd_manager *mgr, long level)
3515{
3516 int result;
3517 result = Cudd_ReadInvPerm((DdManager *) mgr, (int)level);
3518 return(result);
3519
3520} /* end of bdd_get_id_from_level */
3521
3522
3523/**Function********************************************************************
3524
3525 Synopsis [Gets the level of the top variable of the BDD.]
3526
3527 SideEffects []
3528
3529******************************************************************************/
3530long
3531bdd_top_var_level(bdd_manager *mgr, bdd_t *fn)
3532{
3533 return((long) cuddI((DdManager *)mgr,Cudd_Regular(fn->node)->index));
3534
3535} /* end of bdd_top_var_level */
3536
3537
3538/**Function********************************************************************
3539
3540 Synopsis [Returns TRUE if the argument BDD is a cube; FALSE
3541 otherwise.]
3542
3543 SideEffects []
3544
3545******************************************************************************/
3546boolean
3547bdd_is_cube(bdd_t *f)
3548{
3549 struct DdManager *manager;
3550
3551 if (f == NULL) {
3552 fail("bdd_is_cube: invalid BDD");
3553 }
3554 if (f->free) fail ("Freed BDD passed to bdd_is_cube");
3555 manager = f->mgr;
3556 return((boolean)cuddCheckCube(manager,f->node));
3557
3558} /* end of bdd_is_cube */
3559
3560
3561/**Function********************************************************************
3562
3563 Synopsis [Builds a group of variables that should stay adjacent
3564 during reordering.]
3565
3566 Description [Builds a group of variables that should stay adjacent
3567 during reordering. The group is made up of n variables. The first
3568 variable in the group is f. The other variables are the n-1
3569 variables following f in the order at the time of invocation of this
3570 function. Returns a handle to the variable group if successful; NULL
3571 otherwise.]
3572
3573 SideEffects [Modifies the variable tree.]
3574
3575******************************************************************************/
3576bdd_block *
3577bdd_new_var_block(bdd_t *f, long n)
3578{
3579 DdManager *manager;
3580 DdNode *node;
3581 MtrNode *group;
3582 int index;
3583
3584 manager = (DdManager *) f->mgr;
3585 node = Cudd_Regular(f->node);
3586 index = node->index;
3587 if (index == CUDD_MAXINDEX)
3588 return(NULL);
3589 group = Cudd_MakeTreeNode(manager, index, n, MTR_DEFAULT);
3590
3591 return((bdd_block *) group);
3592
3593} /* end of bdd_new_var_block */
3594
3595
3596/**Function********************************************************************
3597
3598 Synopsis [Function that creates a variable of a given index.]
3599
3600 SideEffects []
3601
3602******************************************************************************/
3603bdd_t *
3604bdd_var_with_index(bdd_manager *manager, int index)
3605{
3606 DdNode *var;
3607
3608 var = Cudd_bddIthVar((DdManager *) manager, index);
3609 cuddRef(var);
3610 return(bdd_construct_bdd_t(manager, var));
3611
3612} /* end of bdd_var_with_index */
3613
3614
3615/**Function********************************************************************
3616
3617 Synopsis [Checks whether a variable is dependent on others in a
3618 function f. Returns 1 if it is, else 0. ]
3619
3620 SideEffects []
3621
3622******************************************************************************/
3623int
3624bdd_var_is_dependent(bdd_t *f, bdd_t *var)
3625{
3626 return (Cudd_bddVarIsDependent((DdManager *)f->mgr, (DdNode *)f->node,
3627 (DdNode *)var->node));
3628
3629} /* end of bdd_var_is_dependent */
3630
3631
3632/**Function********************************************************************
3633
3634 Synopsis []
3635
3636 SideEffects []
3637
3638******************************************************************************/
3639int
3640bdd_reordering_status(bdd_manager *mgr, bdd_reorder_type_t *method)
3641{
3642 int dyn;
3643
3644 dyn = Cudd_ReorderingStatus((DdManager *)mgr, (Cudd_ReorderingType *)method);
3645 switch (*method) {
3646 case CUDD_REORDER_SIFT:
3647 *method = BDD_REORDER_SIFT;
3648 break;
3649 case CUDD_REORDER_WINDOW3_CONV:
3650 *method = BDD_REORDER_WINDOW3_CONV;
3651 break;
3652 case CUDD_REORDER_NONE:
3653 *method = BDD_REORDER_NONE;
3654 break;
3655 case CUDD_REORDER_SAME:
3656 *method = BDD_REORDER_SAME;
3657 break;
3658 case CUDD_REORDER_RANDOM:
3659 *method = BDD_REORDER_RANDOM;
3660 break;
3661 case CUDD_REORDER_RANDOM_PIVOT:
3662 *method = BDD_REORDER_RANDOM_PIVOT;
3663 break;
3664 case CUDD_REORDER_SIFT_CONVERGE:
3665 *method = BDD_REORDER_SIFT_CONVERGE;
3666 break;
3667 case CUDD_REORDER_SYMM_SIFT:
3668 *method = BDD_REORDER_SYMM_SIFT;
3669 break;
3670 case CUDD_REORDER_SYMM_SIFT_CONV:
3671 *method = BDD_REORDER_SYMM_SIFT_CONV;
3672 break;
3673 case CUDD_REORDER_WINDOW2:
3674 *method = BDD_REORDER_WINDOW2;
3675 break;
3676 case CUDD_REORDER_WINDOW4:
3677 *method = BDD_REORDER_WINDOW4;
3678 break;
3679 case CUDD_REORDER_WINDOW2_CONV:
3680 *method = BDD_REORDER_WINDOW2_CONV;
3681 break;
3682 case CUDD_REORDER_WINDOW3:
3683 *method = BDD_REORDER_WINDOW3;
3684 break;
3685 case CUDD_REORDER_WINDOW4_CONV:
3686 *method = BDD_REORDER_WINDOW4_CONV;
3687 break;
3688 case CUDD_REORDER_GROUP_SIFT:
3689 *method = BDD_REORDER_GROUP_SIFT;
3690 break;
3691 case CUDD_REORDER_GROUP_SIFT_CONV:
3692 *method = BDD_REORDER_GROUP_SIFT_CONV;
3693 break;
3694 case CUDD_REORDER_ANNEALING:
3695 *method = BDD_REORDER_ANNEALING;
3696 break;
3697 case CUDD_REORDER_GENETIC:
3698 *method = BDD_REORDER_GENETIC;
3699 break;
3700 case CUDD_REORDER_EXACT:
3701 *method = BDD_REORDER_EXACT;
3702 break;
3703 default:
3704 break;
3705 }
3706 return(dyn);
3707
3708} /* end of bdd_reordering_status */
3709
3710
3711/**Function********************************************************************
3712
3713 Synopsis []
3714
3715 SideEffects []
3716
3717******************************************************************************/
3718int
3719bdd_reordering_zdd_status(bdd_manager *mgr, bdd_reorder_type_t *method)
3720{
3721 int dyn;
3722 dyn = Cudd_ReorderingStatusZdd((DdManager *)mgr, (Cudd_ReorderingType *)method);
3723 switch (*method) {
3724 case CUDD_REORDER_SIFT:
3725 *method = BDD_REORDER_SIFT;
3726 break;
3727 case CUDD_REORDER_WINDOW3_CONV:
3728 *method = BDD_REORDER_WINDOW3_CONV;
3729 break;
3730 case CUDD_REORDER_NONE:
3731 *method = BDD_REORDER_NONE;
3732 break;
3733 case CUDD_REORDER_SAME:
3734 *method = BDD_REORDER_SAME;
3735 break;
3736 case CUDD_REORDER_RANDOM:
3737 *method = BDD_REORDER_RANDOM;
3738 break;
3739 case CUDD_REORDER_RANDOM_PIVOT:
3740 *method = BDD_REORDER_RANDOM_PIVOT;
3741 break;
3742 case CUDD_REORDER_SIFT_CONVERGE:
3743 *method = BDD_REORDER_SIFT_CONVERGE;
3744 break;
3745 case CUDD_REORDER_SYMM_SIFT:
3746 *method = BDD_REORDER_SYMM_SIFT;
3747 break;
3748 case CUDD_REORDER_SYMM_SIFT_CONV:
3749 *method = BDD_REORDER_SYMM_SIFT_CONV;
3750 break;
3751 case CUDD_REORDER_WINDOW2:
3752 *method = BDD_REORDER_WINDOW2;
3753 break;
3754 case CUDD_REORDER_WINDOW4:
3755 *method = BDD_REORDER_WINDOW4;
3756 break;
3757 case CUDD_REORDER_WINDOW2_CONV:
3758 *method = BDD_REORDER_WINDOW2_CONV;
3759 break;
3760 case CUDD_REORDER_WINDOW3:
3761 *method = BDD_REORDER_WINDOW3;
3762 break;
3763 case CUDD_REORDER_WINDOW4_CONV:
3764 *method = BDD_REORDER_WINDOW4_CONV;
3765 break;
3766 case CUDD_REORDER_GROUP_SIFT:
3767 *method = BDD_REORDER_GROUP_SIFT;
3768 break;
3769 case CUDD_REORDER_GROUP_SIFT_CONV:
3770 *method = BDD_REORDER_GROUP_SIFT_CONV;
3771 break;
3772 case CUDD_REORDER_ANNEALING:
3773 *method = BDD_REORDER_ANNEALING;
3774 break;
3775 case CUDD_REORDER_GENETIC:
3776 *method = BDD_REORDER_GENETIC;
3777 break;
3778 case CUDD_REORDER_EXACT:
3779 *method = BDD_REORDER_EXACT;
3780 break;
3781 default:
3782 break;
3783 }
3784 return(dyn);
3785
3786} /* end of bdd_reordering_zdd_status */
3787
3788
3789/**Function********************************************************************
3790
3791 Synopsis [Converts a bdd to an add.]
3792
3793 SideEffects []
3794
3795******************************************************************************/
3796bdd_node *
3797bdd_bdd_to_add(bdd_manager *mgr, bdd_node *fn)
3798{
3799 DdNode *result;
3800 result = Cudd_BddToAdd((DdManager *)mgr,(DdNode *)fn);
3801 return((bdd_node *)result);
3802
3803} /* end of bdd_bdd_to_add */
3804
3805
3806/**Function********************************************************************
3807
3808 Synopsis [Permutes the variables in a given function using the permut array..]
3809
3810 SideEffects []
3811
3812******************************************************************************/
3813bdd_node *
3814bdd_add_permute(
3815 bdd_manager *mgr,
3816 bdd_node *fn,
3817 int *permut)
3818{
3819 DdNode *result;
3820 result = Cudd_addPermute((DdManager *)mgr, (DdNode *)fn, permut);
3821 return(result);
3822
3823} /* end of bdd_add_permute */
3824
3825
3826/**Function********************************************************************
3827
3828 Synopsis [Permutes the variables in a given function using the permut array..]
3829
3830 SideEffects []
3831
3832******************************************************************************/
3833bdd_node *
3834bdd_bdd_permute(
3835 bdd_manager *mgr,
3836 bdd_node *fn,
3837 int *permut)
3838{
3839 DdNode *result;
3840 result = Cudd_bddPermute((DdManager *)mgr, (DdNode *)fn, permut);
3841 return(result);
3842
3843} /* end of bdd_bdd_permute */
3844
3845
3846/**Function********************************************************************
3847
3848 Synopsis [References a bdd]
3849
3850 SideEffects []
3851
3852******************************************************************************/
3853void
3854bdd_ref(bdd_node *fn)
3855{
3856 Cudd_Ref((DdNode *)fn);
3857 return;
3858
3859} /* end of bdd_ref */
3860
3861
3862/**Function********************************************************************
3863
3864 Synopsis [Decreases the reference count of node.If f dies,
3865 recursively decreases the reference counts of its children. It is
3866 used to dispose of a DD that is no longer needed.]
3867
3868 SideEffects []
3869
3870******************************************************************************/
3871void
3872bdd_recursive_deref(bdd_manager *mgr, bdd_node *f)
3873{
3874 Cudd_RecursiveDeref((DdManager *)mgr, (DdNode *)f);
3875
3876} /* end of bdd_recursive_deref */
3877
3878
3879/**Function********************************************************************
3880
3881 Synopsis [Existentially abstracts out the variables from the function]
3882
3883 SideEffects []
3884
3885******************************************************************************/
3886bdd_node *
3887bdd_add_exist_abstract(
3888 bdd_manager *mgr,
3889 bdd_node *fn,
3890 bdd_node *vars)
3891{
3892 DdNode *result;
3893 result = Cudd_addExistAbstract((DdManager *)mgr, (DdNode *)fn,
3894 (DdNode *)vars);
3895 return(result);
3896
3897} /* end of bdd_add_exist_abstract */
3898
3899
3900/**Function********************************************************************
3901
3902 Synopsis [Performs the apply operation on ADds]
3903
3904 SideEffects []
3905
3906******************************************************************************/
3907bdd_node *
3908bdd_add_apply(
3909 bdd_manager *mgr,
3910 bdd_node *(*operation)(bdd_manager *, bdd_node **, bdd_node **),
3911 bdd_node *fn1,
3912 bdd_node *fn2)
3913{
3914 DdNode *result;
3915 result = Cudd_addApply((DdManager *)mgr,
3916 (DdNode *(*)(DdManager *, DdNode **, DdNode **))
3917 operation, (DdNode *)fn1, (DdNode *)fn2);
3918 return(result);
3919
3920} /* end of bdd_add_apply */
3921
3922
3923/**Function********************************************************************
3924
3925 Synopsis [Performs the non-simple compose on ADds]
3926
3927 SideEffects []
3928
3929******************************************************************************/
3930bdd_node *
3931bdd_add_nonsim_compose(
3932 bdd_manager *mgr,
3933 bdd_node *fn,
3934 bdd_node **vector)
3935{
3936 DdNode *result;
3937 result = Cudd_addNonSimCompose((DdManager *)mgr, (DdNode *)fn,
3938 (DdNode **)vector);
3939 return(result);
3940
3941} /* end of bdd_add_nonsim_compose */
3942
3943
3944/**Function********************************************************************
3945
3946 Synopsis [Computes the residue ADD of n variables with respect to m]
3947
3948 SideEffects []
3949
3950******************************************************************************/
3951bdd_node *
3952bdd_add_residue(
3953 bdd_manager *mgr,
3954 int n,
3955 int m,
3956 int options,
3957 int top)
3958{
3959 DdNode *result;
3960 result = Cudd_addResidue((DdManager *)mgr, n, m, options, top);
3961 return(result);
3962
3963} /* end of bdd_add_residue */
3964
3965
3966/**Function********************************************************************
3967
3968 Synopsis [Performs the vector compose on ADds]
3969
3970 SideEffects []
3971
3972******************************************************************************/
3973bdd_node *
3974bdd_add_vector_compose(
3975 bdd_manager *mgr,
3976 bdd_node *fn,
3977 bdd_node **vector)
3978{
3979 DdNode *result;
3980 result = Cudd_addVectorCompose((DdManager *)mgr, (DdNode *)fn,
3981 (DdNode **)vector);
3982 return(result);
3983
3984} /* end of bdd_add_vector_compose */
3985
3986
3987/**Function********************************************************************
3988
3989 Synopsis [Performs the times (multiplication operation) on Adds]
3990
3991 SideEffects []
3992
3993******************************************************************************/
3994bdd_node *
3995bdd_add_times(
3996 bdd_manager *mgr,
3997 bdd_node **fn1,
3998 bdd_node **fn2)
3999{
4000 DdNode *result;
4001 result = Cudd_addTimes((DdManager *)mgr, (DdNode **)fn1, (DdNode **)fn2);
4002 return(result);
4003
4004} /* end of bdd_add_times */
4005
4006
4007/**Function********************************************************************
4008
4009 Synopsis [Performs the zero reference count check on the manager.]
4010
4011 SideEffects []
4012
4013******************************************************************************/
4014int
4015bdd_check_zero_ref(bdd_manager *mgr)
4016{
4017 int result;
4018 result = Cudd_CheckZeroRef((DdManager *)mgr);
4019 return(result);
4020
4021} /* end of bdd_check_zero_ref */
4022
4023
4024/**Function********************************************************************
4025
4026 Synopsis [Disables dynamic reordering in the manager.]
4027
4028 SideEffects []
4029
4030******************************************************************************/
4031void
4032bdd_dynamic_reordering_disable(bdd_manager *mgr)
4033{
4034 Cudd_AutodynDisable((DdManager *)mgr);
4035 return;
4036
4037} /* end of bdd_dynamic_reordering_disable */
4038
4039
4040/**Function********************************************************************
4041
4042 Synopsis [Disables dynamic reordering for ZDD in the manager.]
4043
4044 SideEffects []
4045
4046******************************************************************************/
4047void
4048bdd_dynamic_reordering_zdd_disable(bdd_manager *mgr)
4049{
4050 Cudd_AutodynDisableZdd((DdManager *)mgr);
4051 return;
4052
4053} /* end of bdd_dynamic_reordering_zdd_disable */
4054
4055
4056/**Function********************************************************************
4057
4058 Synopsis [Performs the xnor (\equiv operation) on Adds]
4059
4060 SideEffects []
4061
4062******************************************************************************/
4063bdd_node *
4064bdd_add_xnor(bdd_manager *mgr, bdd_node **fn1, bdd_node **fn2)
4065{
4066 DdNode *result;
4067 result = Cudd_addXnor((DdManager *)mgr, (DdNode **)fn1, (DdNode **)fn2);
4068 return(result);
4069
4070} /* end of bdd_add_xnor */
4071
4072
4073/**Function********************************************************************
4074
4075 Synopsis [Shuffles the variables in the manager in the given order.]
4076
4077 SideEffects []
4078
4079******************************************************************************/
4080int
4081bdd_shuffle_heap(bdd_manager *mgr, int *permut)
4082{
4083 int result;
4084 result = Cudd_ShuffleHeap((DdManager *)mgr, permut);
4085 return(result);
4086
4087} /* end of bdd_shuffle_heap */
4088
4089
4090/**Function********************************************************************
4091
4092 Synopsis [Performs compose operation on ADds]
4093
4094 SideEffects []
4095
4096******************************************************************************/
4097bdd_node *
4098bdd_add_compose(
4099 bdd_manager *mgr,
4100 bdd_node *fn1,
4101 bdd_node *fn2,
4102 int var)
4103{
4104 DdNode *result;
4105 result = Cudd_addCompose((DdManager *)mgr, (DdNode *)fn1,
4106 (DdNode *)fn2, var);
4107 return(result);
4108
4109} /* end of bdd_add_compose */
4110
4111
4112/**Function********************************************************************
4113
4114 Synopsis [Gets the ith add variable in the manager ]
4115
4116 SideEffects []
4117
4118******************************************************************************/
4119bdd_node *
4120bdd_add_ith_var(bdd_manager *mgr, int i)
4121{
4122 DdNode *result;
4123 result = Cudd_addIthVar((DdManager *)mgr, i);
4124 return(result);
4125
4126} /* end of bdd_add_ith_var */
4127
4128
4129/**Function********************************************************************
4130
4131 Synopsis [Gets the level of the ith variable in the manager ]
4132
4133 SideEffects []
4134
4135******************************************************************************/
4136int
4137bdd_get_level_from_id(bdd_manager *mgr, int id)
4138{
4139 int level;
4140 level = Cudd_ReadPerm((DdManager *)mgr, id);
4141 return(level);
4142
4143} /* end of bdd_get_level_from_id */
4144
4145
4146/**Function********************************************************************
4147
4148 Synopsis [Existentially abstracts out the variables from the function.
4149 Here the fn is assumed to be a BDD function.]
4150
4151 SideEffects []
4152
4153******************************************************************************/
4154bdd_node *
4155bdd_bdd_exist_abstract(bdd_manager *mgr, bdd_node *fn, bdd_node *cube)
4156{
4157 DdNode *result;
4158 result = Cudd_bddExistAbstract((DdManager *)mgr, (DdNode *)fn,
4159 (DdNode *)cube);
4160 return(result);
4161
4162} /* end of bdd_bdd_exist_abstract */
4163
4164
4165/**Function********************************************************************
4166
4167 Synopsis [Compares two ADDs for equality within tolerance. pr is verbosity
4168 level.]
4169
4170 SideEffects []
4171
4172******************************************************************************/
4173int
4174bdd_equal_sup_norm(
4175 bdd_manager *mgr,
4176 bdd_node *fn,
4177 bdd_node *gn,
4178 BDD_VALUE_TYPE tolerance,
4179 int pr)
4180{
4181 int result;
4182 result = Cudd_EqualSupNorm((DdManager *)mgr, (DdNode *)fn,
4183 (DdNode *)gn, (CUDD_VALUE_TYPE)tolerance, pr);
4184 return(result);
4185
4186} /* end of bdd_equal_sup_norm */
4187
4188
4189/**Function********************************************************************
4190
4191 Synopsis [Reads constant logic zero bdd_node.]
4192
4193
4194 SideEffects [bdd_zero]
4195
4196******************************************************************************/
4197bdd_node *
4198bdd_read_logic_zero(bdd_manager *mgr)
4199{
4200 DdNode *result;
4201 result = Cudd_ReadLogicZero((DdManager *)mgr);
4202
4203 return(result);
4204
4205} /* end of bdd_read_logic_zero */
4206
4207
4208/**Function********************************************************************
4209
4210 Synopsis [Get the ith bdd node in the manager.]
4211
4212
4213 SideEffects []
4214
4215******************************************************************************/
4216bdd_node *
4217bdd_bdd_ith_var(bdd_manager *mgr, int i)
4218{
4219 DdNode *result;
4220 result = Cudd_bddIthVar((DdManager *)mgr, i);
4221
4222 return(result);
4223
4224} /* end of bdd_bdd_ith_var */
4225
4226
4227/**Function********************************************************************
4228
4229 Synopsis [Performs the divide operation on ADDs]
4230
4231 SideEffects []
4232
4233******************************************************************************/
4234bdd_node *
4235bdd_add_divide(bdd_manager *mgr, bdd_node **fn1, bdd_node **fn2)
4236{
4237 DdNode *result;
4238 result = Cudd_addDivide((DdManager *)mgr, (DdNode **)fn1, (DdNode **)fn2);
4239
4240 return(result);
4241
4242} /* end of bdd_add_divide */
4243
4244
4245/**Function********************************************************************
4246
4247 Synopsis [Performs the constrain operation.]
4248
4249 SideEffects []
4250
4251******************************************************************************/
4252bdd_node *
4253bdd_bdd_constrain(bdd_manager *mgr, bdd_node *f, bdd_node *c)
4254{
4255 DdNode *result;
4256 result = Cudd_bddConstrain((DdManager *)mgr, (DdNode *)f, (DdNode *)c);
4257
4258 return(result);
4259
4260} /* end of bdd_bdd_constrain */
4261
4262
4263/**Function********************************************************************
4264
4265 Synopsis [Performs the restrict operation.]
4266
4267 SideEffects []
4268
4269******************************************************************************/
4270bdd_node *
4271bdd_bdd_restrict(bdd_manager *mgr, bdd_node *f, bdd_node *c)
4272{
4273 DdNode *result;
4274 result = Cudd_bddRestrict((DdManager *)mgr, (DdNode *)f, (DdNode *)c);
4275
4276 return(result);
4277
4278} /* end of bdd_bdd_restrict */
4279
4280
4281/**Function********************************************************************
4282
4283 Synopsis [Computes the hamming distance ADD between two sets of variables.]
4284
4285 SideEffects []
4286
4287******************************************************************************/
4288bdd_node *
4289bdd_add_hamming(
4290 bdd_manager *mgr,
4291 bdd_node **xVars,
4292 bdd_node **yVars,
4293 int nVars)
4294{
4295 DdNode *result;
4296 result = Cudd_addHamming((DdManager *)mgr, (DdNode **)xVars,
4297 (DdNode **)yVars, nVars);
4298
4299 return(result);
4300
4301} /* end of bdd_add_hamming */
4302
4303
4304/**Function********************************************************************
4305
4306 Synopsis [Performs the ITE operation for ADDs.]
4307
4308 SideEffects []
4309
4310******************************************************************************/
4311bdd_node *
4312bdd_add_ite(
4313 bdd_manager *mgr,
4314 bdd_node *f,
4315 bdd_node *g,
4316 bdd_node *h)
4317{
4318 DdNode *result;
4319 result = Cudd_addIte((DdManager *)mgr, (DdNode *)f, (DdNode *)g,
4320 (DdNode *)h);
4321
4322 return(result);
4323
4324} /* end of bdd_add_ite */
4325
4326
4327/**Function********************************************************************
4328
4329 Synopsis [Finds the maximum discriminant of f. Returns a pointer to a
4330 constant ADD.]
4331
4332 SideEffects []
4333
4334******************************************************************************/
4335bdd_node *
4336bdd_add_find_max(bdd_manager *mgr, bdd_node *f)
4337{
4338 DdNode *result;
4339 result = Cudd_addFindMax((DdManager *)mgr, (DdNode *)f);
4340
4341 return(result);
4342
4343} /* end of bdd_add_find_max */
4344
4345
4346/**Function********************************************************************
4347
4348 Synopsis [Picks one on-set cube randomly from the given DD. The cube is
4349 written into an array of characters. The array must have at least as many
4350 entries as there are variables. Returns 1 if successful; 0 otherwise.]
4351
4352 SideEffects []
4353
4354******************************************************************************/
4355int
4356bdd_bdd_pick_one_cube(bdd_manager *mgr, bdd_node *node, char *string)
4357{
4358 return(Cudd_bddPickOneCube((DdManager *)mgr, (DdNode *)node, string));
4359
4360} /* end of bdd_bdd_pick_one_cube */
4361
4362
4363/**Function********************************************************************
4364
4365 Synopsis [Swap two sets of variables in ADD f]
4366
4367 SideEffects []
4368
4369******************************************************************************/
4370bdd_node *
4371bdd_add_swap_variables(
4372 bdd_manager *mgr,
4373 bdd_node *f,
4374 bdd_node **x,
4375 bdd_node **y,
4376 int n)
4377{
4378 DdNode *result;
4379 result = Cudd_addSwapVariables((DdManager *)mgr, (DdNode *)f,
4380 (DdNode **)x, (DdNode **)y, n);
4381
4382 return(result);
4383
4384} /* end of bdd_add_swap_variables */
4385
4386
4387/**Function********************************************************************
4388
4389 Synopsis [Computes the disjunction of two BDDs f and g.]
4390
4391 SideEffects []
4392
4393******************************************************************************/
4394bdd_node *
4395bdd_bdd_or(bdd_manager *mgr, bdd_node *f, bdd_node *g)
4396{
4397 DdNode *result;
4398 result = Cudd_bddOr((DdManager *)mgr, (DdNode *)f, (DdNode *)g);
4399
4400 return(result);
4401
4402} /* end of bdd_bdd_or */
4403
4404
4405/**Function********************************************************************
4406
4407 Synopsis [Computes the cube of an array of BDD variables.If
4408 non-null, the phase argument indicates which literal of each
4409 variable should appear in the cube. If phase\[i\] is nonzero, then
4410 the positive literal is used. If phase is NULL, the cube is positive
4411 unate. Returns a pointer to the result if successful; NULL
4412 otherwise.]
4413
4414 SideEffects []
4415
4416******************************************************************************/
4417bdd_node *
4418bdd_bdd_compute_cube(
4419 bdd_manager *mgr,
4420 bdd_node **vars,
4421 int *phase,
4422 int n)
4423{
4424 DdNode *result;
4425 result = Cudd_bddComputeCube((DdManager *)mgr, (DdNode **)vars,
4426 phase, n);
4427
4428 return(result);
4429
4430} /* end of bdd_bdd_compute_cube */
4431
4432
4433/**Function********************************************************************
4434
4435 Synopsis [Builds a cube of BDD variables from an array of indices.]
4436
4437 Description [Builds a cube of BDD variables from an array of indices.
4438 Returns a pointer to the result if successful; NULL otherwise.]
4439
4440 SideEffects [None]
4441
4442 SeeAlso [bdd_bdd_compute_cube]
4443
4444******************************************************************************/
4445bdd_node *
4446bdd_indices_to_cube(bdd_manager *mgr, int *idArray, int n)
4447{
4448 DdNode *result;
4449 result = Cudd_IndicesToCube((DdManager *)mgr, idArray, n);
4450
4451 return(result);
4452
4453} /* end of bdd_indices_to_cube */
4454
4455
4456/**Function********************************************************************
4457
4458 Synopsis [Computes the conjunction of two BDDs f and g.]
4459
4460 SideEffects []
4461
4462******************************************************************************/
4463bdd_node *
4464bdd_bdd_and(bdd_manager *mgr, bdd_node *f, bdd_node *g)
4465{
4466 DdNode *result;
4467 result = Cudd_bddAnd((DdManager *)mgr, (DdNode *)f, (DdNode *)g);
4468
4469 return(result);
4470
4471} /* end of bdd_bdd_and */
4472
4473
4474/**Function********************************************************************
4475
4476 Synopsis [Multiply two matrices represented by A and B. A is assumed to
4477 depend on x (rows) and z (columns). B is assumed to depend on z (rows)
4478 and y (columns). The product depends on x and y. Only z needs to be
4479 explicitly identified.]
4480
4481 SideEffects []
4482
4483******************************************************************************/
4484bdd_node *
4485bdd_add_matrix_multiply(
4486 bdd_manager *mgr,
4487 bdd_node *A,
4488 bdd_node *B,
4489 bdd_node **z,
4490 int nz)
4491{
4492 DdNode *result;
4493 result = Cudd_addMatrixMultiply((DdManager *)mgr, (DdNode *)A,
4494 (DdNode *)B, (DdNode **)z, nz);
4495
4496 return(result);
4497
4498} /* end of bdd_add_matrix_multiply */
4499
4500
4501/**Function********************************************************************
4502
4503 Synopsis [Computes the cube of an array of ADD variables. If
4504 non-null, the phase argument indicates which literal of each
4505 variable should appear in the cube. If phase\[i\] is nonzero, then the
4506 positive literal is used. If phase is NULL, the cube is positive unate.
4507 Returns a pointer to the result if successful; NULL otherwise.]
4508
4509 SideEffects []
4510
4511******************************************************************************/
4512bdd_node *
4513bdd_add_compute_cube(
4514 bdd_manager *mgr,
4515 bdd_node **vars,
4516 int *phase,
4517 int n)
4518{
4519 DdNode *result;
4520 result = Cudd_addComputeCube((DdManager *)mgr, (DdNode **)vars, phase, n);
4521
4522 return(result);
4523
4524} /* end of bdd_add_compute_cube */
4525
4526
4527/**Function********************************************************************
4528
4529 Synopsis [Returns the ADD for constant c.]
4530
4531 Description [Returns the ADD for constant c if successful. NULL otherwise.]
4532
4533 SideEffects []
4534
4535******************************************************************************/
4536bdd_node *
4537bdd_add_const(bdd_manager *mgr, BDD_VALUE_TYPE c)
4538{
4539 DdNode *result;
4540 result = Cudd_addConst((DdManager *)mgr, (CUDD_VALUE_TYPE)c);
4541
4542 return(result);
4543
4544} /* end of bdd_add_const */
4545
4546
4547/**Function********************************************************************
4548
4549 Synopsis [Swaps two sets of variables of the same size (x and y) in
4550 the BDD f.]
4551
4552 SideEffects []
4553
4554******************************************************************************/
4555bdd_node *
4556bdd_bdd_swap_variables(
4557 bdd_manager *mgr,
4558 bdd_node *f,
4559 bdd_node **x,
4560 bdd_node **y,
4561 int n)
4562{
4563 DdNode *result;
4564 result = Cudd_bddSwapVariables((DdManager *)mgr, (DdNode *)f,
4565 (DdNode **)x, (DdNode **)y, n);
4566
4567 return(result);
4568
4569} /* end of bdd_bdd_swap_variables */
4570
4571
4572/**Function********************************************************************
4573
4574 Synopsis [Counts the number of minters in the on set of f which depends on
4575 atmost n variables.]
4576
4577 SideEffects []
4578
4579******************************************************************************/
4580double
4581bdd_count_minterm(bdd_manager *mgr, bdd_node *f, int n)
4582{
4583 double result;
4584 result = Cudd_CountMinterm((DdManager *)mgr, (DdNode *)f, n);
4585
4586 return(result);
4587
4588} /* end of bdd_count_minterm */
4589
4590
4591/**Function********************************************************************
4592
4593 Synopsis [Converts an ADD to a BDD by replacing all
4594 discriminants greater than or equal to value with 1, and all other
4595 discriminants with 0. Returns a pointer to the resulting BDD if
4596 successful; NULL otherwise.]
4597
4598 SideEffects []
4599
4600******************************************************************************/
4601bdd_node *
4602bdd_add_bdd_threshold(
4603 bdd_manager *mgr,
4604 bdd_node *f,
4605 BDD_VALUE_TYPE value)
4606{
4607 DdNode *result;
4608 result = Cudd_addBddThreshold((DdManager *) mgr, (DdNode *) f,
4609 (CUDD_VALUE_TYPE)value);
4610
4611 return(result);
4612
4613} /* end of bdd_add_bdd_threshold */
4614
4615
4616/**Function********************************************************************
4617
4618 Synopsis [Converts an ADD to a BDD by replacing all discriminants strictly
4619 greater than value with 1, and all other discriminants with 0. Returns a
4620 pointer to the resulting BDD if successful; NULL otherwise.]
4621
4622 SideEffects []
4623
4624******************************************************************************/
4625bdd_node *
4626bdd_add_bdd_strict_threshold(
4627 bdd_manager *mgr,
4628 bdd_node *f,
4629 BDD_VALUE_TYPE value)
4630{
4631 DdNode *result;
4632 result = Cudd_addBddStrictThreshold((DdManager *) mgr, (DdNode *) f,
4633 (CUDD_VALUE_TYPE)value);
4634
4635 return(result);
4636
4637} /* end of bdd_add_bdd_strict_threshold */
4638
4639
4640/**Function********************************************************************
4641
4642 Synopsis [Reads the epsilon parameter of the manager.]
4643
4644 SideEffects []
4645
4646******************************************************************************/
4647BDD_VALUE_TYPE
4648bdd_read_epsilon(bdd_manager *mgr)
4649{
4650 return((DdManager *)mgr)->epsilon;
4651
4652} /* end of bdd_read_epsilon */
4653
4654
4655/**Function********************************************************************
4656
4657 Synopsis [Reads the constant 1 of the manager.]
4658
4659 SideEffects []
4660
4661******************************************************************************/
4662bdd_node *
4663bdd_read_one(bdd_manager *mgr)
4664{
4665 return(DD_ONE((DdManager *)mgr));
4666
4667} /* end of bdd_read_one */
4668
4669
4670/**Function********************************************************************
4671
4672 Synopsis [Pick a random minterm from the onset of f.]
4673
4674 SideEffects []
4675
4676******************************************************************************/
4677bdd_node *
4678bdd_bdd_pick_one_minterm(
4679 bdd_manager *mgr,
4680 bdd_node *f,
4681 bdd_node **vars,
4682 int n)
4683{
4684 DdNode *result;
4685 result = Cudd_bddPickOneMinterm((DdManager *)mgr, (DdNode *)f,
4686 (DdNode **)vars, n);
4687
4688 return(result);
4689
4690} /* end of bdd_bdd_pick_one_minterm */
4691
4692
4693/**Function********************************************************************
4694
4695 Synopsis [Pick a random minterm from the onset of f.]
4696
4697 SideEffects []
4698
4699******************************************************************************/
4700bdd_t *
4701bdd_pick_one_minterm(bdd_t *f, array_t *varsArray /* of bdd_t * */)
4702{
4703 DdNode **vars, *minterm;
4704 int i, n;
4705
4706 n = array_n(varsArray);
4707 vars = ALLOC(DdNode *, n);
4708 if (vars == NIL(DdNode *)) return NIL(bdd_t);
4709 for (i = 0; i < n; i++) {
4710 bdd_t *var = array_fetch(bdd_t *, varsArray, i);
4711 assert(f->mgr == var->mgr);
4712 vars[i] = var->node;
4713 }
4714 minterm = Cudd_bddPickOneMinterm(f->mgr, f->node, vars, n);
4715 cuddRef(minterm);
4716 FREE(vars);
4717 if (minterm == NIL(DdNode)) return NIL(bdd_t);
4718 return bdd_construct_bdd_t(f->mgr,minterm);
4719
4720} /* end of bdd_pick_one_minterm */
4721
4722
4723/**Function********************************************************************
4724
4725 Synopsis [Pick arbitrary number of minterms evenly distributed from the
4726 onset of f.]
4727
4728 SideEffects []
4729
4730******************************************************************************/
4731array_t *
4732bdd_bdd_pick_arbitrary_minterms(
4733 bdd_t *f,
4734 array_t *varsArray,
4735 int n,
4736 int k)
4737{
4738 int i;
4739 DdNode **minterms, **vars;
4740 bdd_t *var;
4741 array_t *resultArray;
4742
4743 vars = ALLOC(DdNode *, n);
4744 if (vars == NULL)
4745 return((array_t *)NULL);
4746 for (i = 0; i < n; i++) {
4747 var = array_fetch(bdd_t *, varsArray, i);
4748 vars[i] = var->node;
4749 }
4750
4751 minterms = (DdNode **)Cudd_bddPickArbitraryMinterms((DdManager *)f->mgr,
4752 (DdNode *)f->node, (DdNode **)vars, n, k);
4753
4754 resultArray = array_alloc(bdd_t *, k);
4755 for (i = 0; i < k; i++) {
4756 cuddRef(minterms[i]);
4757 array_insert(bdd_t *, resultArray, i,
4758 bdd_construct_bdd_t(f->mgr,minterms[i]));
4759 }
4760
4761 FREE(vars);
4762 FREE(minterms);
4763 return(resultArray);
4764
4765} /* end of bdd_bdd_pick_arbitrary_minterms */
4766
4767
4768/**Function********************************************************************
4769
4770 Synopsis [Extracts a subset from a BDD with mask variables.]
4771
4772 Description [Extracts a subset from a BDD in the following procedure.
4773 1. Compute the weight for each mask variable by counting the number of
4774 minterms for both positive and negative cofactors of the BDD with
4775 respect to each mask variable. (weight = #positive - #negative)
4776 2. Find a representative cube of the BDD by using the weight. From the
4777 top variable of the BDD, for each variable, if the weight is greater
4778 than 0.0, choose THEN branch, othereise ELSE branch, until meeting
4779 the constant 1.
4780 3. Quantify out the variables not in maskVars from the representative
4781 cube and if a variable in maskVars is don't care, replace the
4782 variable with a constant(1 or 0) depending on the weight.
4783 4. Make a subset of the BDD by multiplying with the modified cube.]
4784
4785 SideEffects [None]
4786
4787 SeeAlso []
4788
4789******************************************************************************/
4790bdd_t *
4791bdd_subset_with_mask_vars(bdd_t *f, array_t *varsArray, array_t *maskVarsArray)
4792{
4793 int i;
4794 DdNode *subset, **vars, **maskVars;
4795 bdd_t *var;
4796 int n = array_n(varsArray);
4797 int m = array_n(maskVarsArray);
4798
4799 vars = ALLOC(DdNode *, n);
4800 if (vars == NULL)
4801 return((bdd_t *)NULL);
4802 for (i = 0; i < n; i++) {
4803 var = array_fetch(bdd_t *, varsArray, i);
4804 vars[i] = var->node;
4805 }
4806
4807 maskVars = ALLOC(DdNode *, m);
4808 if (maskVars == NULL) {
4809 FREE(vars);
4810 return((bdd_t *)NULL);
4811 }
4812 for (i = 0; i < m; i++) {
4813 var = array_fetch(bdd_t *, maskVarsArray, i);
4814 maskVars[i] = var->node;
4815 }
4816
4817 subset = (DdNode *)Cudd_SubsetWithMaskVars((DdManager *)f->mgr,
4818 (DdNode *)f->node, (DdNode **)vars, n, (DdNode **)maskVars, m);
4819 if (subset == NULL) return((bdd_t *)NULL);
4820
4821 cuddRef(subset);
4822 FREE(vars);
4823 FREE(maskVars);
4824
4825 return(bdd_construct_bdd_t(f->mgr,subset));
4826
4827} /* end of bdd_subset_with_mask_vars */
4828
4829
4830/**Function********************************************************************
4831
4832 Synopsis [Read constant zero of the manager. This is different from the
4833 logical zero which is the complement of logical one.]
4834
4835 SideEffects [bdd_zero]
4836
4837******************************************************************************/
4838bdd_node *
4839bdd_read_zero(bdd_manager *mgr)
4840{
4841 return(DD_ZERO((DdManager *)mgr));
4842
4843} /* bdd_read_zero */
4844
4845
4846/**Function********************************************************************
4847
4848 Synopsis [Returns a new BDD variable.]
4849
4850 SideEffects []
4851
4852******************************************************************************/
4853bdd_node *
4854bdd_bdd_new_var(bdd_manager *mgr)
4855{
4856 DdNode *result;
4857 result = Cudd_bddNewVar((DdManager *)mgr);
4858
4859 return(result);
4860
4861} /* end of bdd_bdd_new_var */
4862
4863
4864/**Function********************************************************************
4865
4866 Synopsis [Takes the AND of two BDDs and simultaneously abstracts the
4867 variables in cube.]
4868
4869 SideEffects []
4870
4871******************************************************************************/
4872bdd_node *
4873bdd_bdd_and_abstract(
4874 bdd_manager *mgr,
4875 bdd_node *f,
4876 bdd_node *g,
4877 bdd_node *cube)
4878{
4879 DdNode *result;
4880 result = Cudd_bddAndAbstract((DdManager *)mgr, (DdNode *)f,
4881 (DdNode *)g, (DdNode *)cube);
4882 return(result);
4883
4884} /* end of bdd_bdd_and_abstract */
4885
4886
4887/**Function********************************************************************
4888
4889 Synopsis [Decreases the reference count of node.]
4890
4891 SideEffects []
4892
4893******************************************************************************/
4894void
4895bdd_deref(bdd_node *f)
4896{
4897 Cudd_Deref((DdNode *)f);
4898
4899} /* end of bdd_deref */
4900
4901
4902/**Function********************************************************************
4903
4904 Synopsis [Integer and floating point addition.Returns NULL if not
4905 a terminal case; f+g otherwise.]
4906
4907 SideEffects []
4908
4909******************************************************************************/
4910bdd_node *
4911bdd_add_plus(bdd_manager *mgr, bdd_node **fn1, bdd_node **fn2)
4912{
4913 DdNode *result;
4914 result = Cudd_addPlus((DdManager *)mgr, (DdNode **)fn1, (DdNode **)fn2);
4915 return(result);
4916
4917} /* end of bdd_add_plus */
4918
4919
4920/**Function********************************************************************
4921
4922 Synopsis [Returns the number of times reordering has occurred.]
4923
4924 SideEffects []
4925
4926******************************************************************************/
4927int
4928bdd_read_reorderings(bdd_manager *mgr)
4929{
4930 return(Cudd_ReadReorderings((DdManager *)mgr));
4931
4932} /* end of bdd_read_reorderings */
4933
4934
4935/**Function********************************************************************
4936
4937 Synopsis [Returns the threshold for the next dynamic reordering.]
4938
4939 SideEffects []
4940
4941******************************************************************************/
4942int
4943bdd_read_next_reordering(bdd_manager *mgr)
4944{
4945 return(Cudd_ReadNextReordering((DdManager *)mgr));
4946
4947} /* end of bdd_read_next_reordering */
4948
4949
4950/**Function********************************************************************
4951
4952 Synopsis [Sets the threshold for the next dynamic reordering.]
4953
4954 SideEffects []
4955
4956******************************************************************************/
4957void
4958bdd_set_next_reordering(bdd_manager *mgr, int next)
4959{
4960 Cudd_SetNextReordering((DdManager *)mgr, next);
4961
4962} /* end of bdd_set_next_reordering */
4963
4964
4965/**Function********************************************************************
4966
4967 Synopsis [Computes the exclusive-nor of f and g.]
4968
4969 SideEffects []
4970
4971******************************************************************************/
4972bdd_node *
4973bdd_bdd_xnor(bdd_manager *mgr, bdd_node *f, bdd_node *g)
4974{
4975 DdNode *result;
4976 result = Cudd_bddXnor((DdManager *)mgr, (DdNode *)f, (DdNode *)g);
4977
4978 return(result);
4979
4980} /* end of bdd_bdd_xnor */
4981
4982
4983/**Function********************************************************************
4984
4985 Synopsis [Composes a BDD with a vector of BDDs.Given a vector of
4986 BDDs, creates a new BDD by substituting the BDDs for the variables
4987 of the BDD f.]
4988
4989 SideEffects []
4990
4991******************************************************************************/
4992bdd_node *
4993bdd_bdd_vector_compose(bdd_manager *mgr, bdd_node *f, bdd_node **vector)
4994{
4995 DdNode *result;
4996 result = Cudd_bddVectorCompose((DdManager *)mgr, (DdNode *)f,
4997 (DdNode **)vector);
4998 return(result);
4999
5000} /* end of bdd_bdd_vector_compose */
5001
5002
5003/**Function********************************************************************
5004
5005 Synopsis [Extracts a BDD node from the bdd_t structure without making
5006 it regular.]
5007
5008 SideEffects []
5009
5010******************************************************************************/
5011bdd_node *
5012bdd_extract_node_as_is(bdd_t *fn)
5013{
5014 return((bdd_node *)fn->node);
5015
5016} /* end of bdd_extract_node_as_is */
5017
5018
5019/**Function********************************************************************
5020
5021 Synopsis [Returns a zdd node with index i and g and h as its children.]
5022
5023 SideEffects []
5024
5025******************************************************************************/
5026bdd_node *
5027bdd_zdd_get_node(
5028 bdd_manager *mgr,
5029 int id,
5030 bdd_node *g,
5031 bdd_node *h)
5032{
5033 DdNode *result;
5034 result = cuddZddGetNode((DdManager *)mgr, id, (DdNode *)g,
5035 (DdNode *)h);
5036
5037 return(result);
5038
5039} /*end of bdd_zdd_get_node */
5040
5041
5042/**Function********************************************************************
5043
5044 Synopsis [Computes the product of two cover represented by ZDDs. The covers
5045 on which bdd_zdd_product operates use two ZDD variables for each
5046 function variable (one ZDD variable for each literal of the variable). Those
5047 two ZDD variables should be adjacent in the order.]
5048
5049 SideEffects []
5050
5051******************************************************************************/
5052bdd_node *
5053bdd_zdd_product(bdd_manager *mgr, bdd_node *f, bdd_node *g)
5054{
5055 DdNode *result;
5056 result = Cudd_zddProduct((DdManager *)mgr, (DdNode *)f, (DdNode *)g);
5057 return(result);
5058
5059} /* end of bdd_zdd_product */
5060
5061
5062/**Function********************************************************************
5063
5064 Synopsis [Computes the product of two cover represented by ZDDs. The covers
5065 on which bdd_zdd_product_recur operates use two ZDD variables for each
5066 function variable (one ZDD variable for each literal of the variable). Those
5067 two ZDD variables should be adjacent in the order. This is a recursive
5068 procedure. It returns the ZDD of the product if successful. Reference count
5069 of the result is not incremented. NULL is returned if re-ordering takes place
5070 or if memory is exhausted.]
5071
5072 SideEffects []
5073
5074******************************************************************************/
5075bdd_node *
5076bdd_zdd_product_recur(bdd_manager *mgr, bdd_node *f, bdd_node *g)
5077{
5078 DdNode *result;
5079 result = cuddZddProduct((DdManager *)mgr, (DdNode *)f, (DdNode *)g);
5080 return(result);
5081
5082} /* end of bdd_zdd_product_recur */
5083
5084
5085/**Function********************************************************************
5086
5087 Synopsis [Computes the union of two ZDDs.]
5088
5089 Description [Computes the union of two ZDDs. Returns a pointer to the
5090 result if successful; NULL otherwise.]
5091
5092 SideEffects []
5093
5094******************************************************************************/
5095bdd_node *
5096bdd_zdd_union(bdd_manager *mgr, bdd_node *f, bdd_node *g)
5097{
5098 DdNode *result;
5099 result = Cudd_zddUnion((DdManager *)mgr, (DdNode *)f, (DdNode *)g);
5100 return(result);
5101
5102} /* end of bdd_zdd_union */
5103
5104
5105/**Function********************************************************************
5106
5107 Synopsis [Computes the union of two ZDDs.]
5108
5109 Description [Computes the union of two ZDDs. Returns a pointer to the
5110 result if successful; NULL otherwise.]
5111
5112 SideEffects []
5113
5114******************************************************************************/
5115bdd_node *
5116bdd_zdd_union_recur(bdd_manager *mgr, bdd_node *f, bdd_node *g)
5117{
5118 DdNode *result;
5119 result = cuddZddUnion((DdManager *)mgr, (DdNode *)f, (DdNode *)g);
5120 return(result);
5121
5122} /* end of bdd_zdd_union_recur */
5123
5124
5125/**Function********************************************************************
5126
5127 Synopsis [Applies weak division to two ZDDs representing two covers. The
5128 result of weak division depends on the variable order. The covers on which
5129 bdd_zdd_weak_div operates use two ZDD variables for each function
5130 variable (one ZDD variable for each literal of the variable). Those two ZDD
5131 variables should be adjacent in the order.]
5132
5133 SideEffects []
5134
5135******************************************************************************/
5136bdd_node *
5137bdd_zdd_weak_div(bdd_manager *mgr, bdd_node *f, bdd_node *g)
5138{
5139 DdNode *result;
5140 result = Cudd_zddWeakDiv((DdManager *)mgr, (DdNode *)f, (DdNode *)g);
5141 return(result);
5142
5143} /* end of bdd_zdd_weak_div */
5144
5145
5146/**Function********************************************************************
5147
5148 Synopsis [Applies weak division to two ZDDs representing two covers. The
5149 result of weak division depends on the variable order. The covers on which
5150 bdd_zdd_weak_div_recur operates use two ZDD variables for each function
5151 variable (one ZDD variable for each literal of the variable). Those two ZDD
5152 variables should be adjacent in the order. This is a recursive procedure. It
5153 returns a pointer to the result if successful; Reference count of the result
5154 is not incremented. NULL is returned if re-ordering takes place or if memory
5155 is exhausted.]
5156
5157 SideEffects []
5158
5159******************************************************************************/
5160bdd_node *
5161bdd_zdd_weak_div_recur(bdd_manager *mgr, bdd_node *f, bdd_node *g)
5162{
5163 DdNode *result;
5164 result = cuddZddWeakDiv((DdManager *)mgr, (DdNode *)f, (DdNode *)g);
5165
5166 return(result);
5167
5168} /* end of bdd_zdd_weak_div_recur */
5169
5170
5171/**Function********************************************************************
5172
5173 Synopsis [Computes an irredundant sum of products (ISOP) in ZDD form from
5174 BDDs. This is a recursive procedure. Returns the pointer to the ZDD on
5175 success. Reference count of the result is not incremented. NULL in the case
5176 of re-ordering or if memory is exhausted.]
5177
5178 SideEffects [zdd_I holds the pointer to the ZDD for the ISOP on successful
5179 return.]
5180
5181******************************************************************************/
5182bdd_node *
5183bdd_zdd_isop_recur(
5184 bdd_manager *mgr,
5185 bdd_node *L,
5186 bdd_node *U,
5187 bdd_node **zdd_I)
5188{
5189 DdNode *result;
5190 result = cuddZddIsop((DdManager *)mgr, (DdNode *)L, (DdNode *)U,
5191 (DdNode **)zdd_I);
5192
5193 return(result);
5194
5195} /* end of bdd_zdd_isop_recur */
5196
5197
5198/**Function********************************************************************
5199
5200 Synopsis [Computes an irredundant sum of products (ISOP) in ZDD form from
5201 BDDs. This is an interface to an external function.]
5202
5203 SideEffects [zdd_I holds the pointer to the ZDD for the ISOP on successful
5204 return.]
5205
5206 SeeAlso [bdd_zdd_isop_recur]
5207
5208******************************************************************************/
5209bdd_node *
5210bdd_zdd_isop(
5211 bdd_manager *mgr,
5212 bdd_node *L,
5213 bdd_node *U,
5214 bdd_node **zdd_I)
5215{
5216 DdNode *result;
5217 result = Cudd_zddIsop((DdManager *)mgr, (DdNode *)L, (DdNode *)U,
5218 (DdNode **)zdd_I);
5219
5220 return(result);
5221
5222} /* end of bdd_zdd_isop */
5223
5224
5225/**Function********************************************************************
5226
5227 Synopsis [Computes the three-way decomposition of f w.r.t. v.]
5228
5229 Description [Computes the three-way decomposition of function f (represented
5230 by a ZDD) w.r.t respect to variable v. Returns 1 on failure, 0 on
5231 success. Reference counts of f1, f0 and fd are not incremented. ]
5232
5233 SideEffects [The results are returned in f1, f0, and fd. They are NULL in
5234 case of failure.]
5235
5236******************************************************************************/
5237int
5238bdd_zdd_get_cofactors3(
5239 bdd_manager *mgr,
5240 bdd_node *f,
5241 int v,
5242 bdd_node **f1,
5243 bdd_node **f0,
5244 bdd_node **fd)
5245{
5246 int result;
5247 result = cuddZddGetCofactors3((DdManager *)mgr, (DdNode *)f, v,
5248 (DdNode **)f1, (DdNode **)f0,
5249 (DdNode **)fd);
5250
5251 return(result);
5252
5253} /* end of bdd_zdd_get_cofactors3 */
5254
5255
5256/**Function********************************************************************
5257
5258 Synopsis [Recursive procedure to compute AND of two bdd_nodes.]
5259
5260 Description [Recursive procedure to compute AND of two bdd_nodes. Returns
5261 the pointer to the BDD on success. The reference count of the result is not
5262 incremented. NULL is returned in case of reordering or if memory is
5263 exhausted.]
5264
5265 SideEffects []
5266
5267******************************************************************************/
5268bdd_node *
5269bdd_bdd_and_recur(bdd_manager *mgr, bdd_node *f, bdd_node *g)
5270{
5271 DdNode *result;
5272 result = cuddBddAndRecur((DdManager *)mgr, (DdNode *)f,
5273 (DdNode *)g);
5274 return(result);
5275
5276} /* end of bdd_bdd_and_recur */
5277
5278
5279/**Function********************************************************************
5280
5281 Synopsis [Returns a bdd_node whose index is v and g and h as its
5282 children.]
5283
5284 Description [Returns a bdd_node whose index is v and g and h as its
5285 children. Returns the bdd_node after success. The reference count of the
5286 returned BDD is not incremented. Returns NULL in case of reordering or if
5287 memory is exhausted.]
5288
5289 SideEffects [none]
5290
5291******************************************************************************/
5292bdd_node *
5293bdd_unique_inter(
5294 bdd_manager *mgr,
5295 int v,
5296 bdd_node *f,
5297 bdd_node *g)
5298{
5299 DdNode *result;
5300 result = cuddUniqueInter((DdManager *)mgr, v, (DdNode *)f,
5301 (DdNode *)g);
5302 return(result);
5303
5304} /* end of bdd_unique_inter */
5305
5306
5307/**Function********************************************************************
5308
5309 Synopsis [Returns a bdd_node whose index is v and f and g as its
5310 children.]
5311
5312 Description [Returns a bdd_node whose index is v and f and g as its
5313 children. Returns the bdd_node after success. The reference count of the
5314 returned BDD is not incremented. Returns NULL in case of reordering or if
5315 memory is exhausted.]
5316
5317 SideEffects [none]
5318
5319******************************************************************************/
5320bdd_node *
5321bdd_unique_inter_ivo(
5322 bdd_manager *mgr,
5323 int v,
5324 bdd_node *f,
5325 bdd_node *g)
5326{
5327 DdNode *result;
5328 DdNode *t;
5329
5330 t = cuddUniqueInter((DdManager *)mgr, v, (DdNode *)bdd_read_one(mgr),
5331 (DdNode *)bdd_not_bdd_node(bdd_read_one(mgr)));
5332 if (t == NULL)
5333 return(NULL);
5334 Cudd_Ref(t);
5335 result = cuddBddIteRecur((DdManager *)mgr, t, (DdNode *)f, (DdNode *)g);
5336 Cudd_RecursiveDeref((DdManager *)mgr,(DdNode *)t);
5337 return(result);
5338
5339} /* end of bdd_unique_inter_ivo */
5340
5341
5342/**Function********************************************************************
5343
5344 Synopsis [Computes the set difference of two ZDDs.]
5345
5346 Description [Computes the set difference of two ZDDs. Returns a pointer to
5347 the result if successful. The reference count of the result is not
5348 incremented. NULL is returned in case of re-ordering of if memory is
5349 exhausted.]
5350
5351 SideEffects [none]
5352
5353******************************************************************************/
5354bdd_node *
5355bdd_zdd_diff(bdd_manager *mgr, bdd_node *f, bdd_node *g)
5356{
5357 DdNode *result;
5358 result = Cudd_zddDiff((DdManager *)mgr, (DdNode *)f, (DdNode *)g);
5359 return(result);
5360
5361} /* end of bdd_zdd_diff */
5362
5363
5364/**Function********************************************************************
5365
5366 Synopsis [Computes the set difference of two ZDDs.]
5367
5368 Description [Computes the set difference of two ZDDs. Returns a pointer to
5369 the result if successful. The reference count of the result is not
5370 incremented. NULL is returned in case of re-ordering of if memory is
5371 exhausted.]
5372
5373 SideEffects [none]
5374
5375******************************************************************************/
5376bdd_node *
5377bdd_zdd_diff_recur(bdd_manager *mgr, bdd_node *f, bdd_node *g)
5378{
5379 DdNode *result;
5380 result = cuddZddDiff((DdManager *)mgr, (DdNode *)f, (DdNode *)g);
5381 return(result);
5382
5383} /* end of bdd_zdd_diff_recur */
5384
5385
5386/**Function********************************************************************
5387
5388 Synopsis [Returns the number of ZDD variables.]
5389
5390 Description [Returns the number of ZDD variables.]
5391
5392 SideEffects [none]
5393
5394******************************************************************************/
5395int
5396bdd_num_zdd_vars(bdd_manager *mgr)
5397{
5398 return(((DdManager *)mgr)->sizeZ);
5399
5400} /* end of bdd_num_zdd_vars */
5401
5402
5403/**Function********************************************************************
5404
5405 Synopsis [Makes the bdd_node a regular one.]
5406
5407 Description [Makes the bdd_node a retular one.]
5408
5409 SideEffects [none]
5410
5411******************************************************************************/
5412bdd_node *
5413bdd_regular(bdd_node *f)
5414{
5415 return(Cudd_Regular((DdNode *)f));
5416
5417} /* end of bdd_regular */
5418
5419
5420/**Function********************************************************************
5421
5422 Synopsis [Returns 1 if the bdd_node is a constant; 0 otherwise.]
5423
5424 Description [Returns 1 if the bdd_node is a constant; 0 otherwise.]
5425
5426 SideEffects [none]
5427
5428******************************************************************************/
5429int
5430bdd_is_constant(bdd_node *f)
5431{
5432 return(Cudd_IsConstant((DdNode *)f));
5433
5434} /* end of bdd_is_constant */
5435
5436
5437/**Function********************************************************************
5438
5439 Synopsis [Returns 1 if the bdd_node is complemented. 0 otherwise.]
5440
5441 Description [Returns 1 if the bdd_node is complemented. 0 otherwise.]]
5442
5443 SideEffects [none]
5444
5445******************************************************************************/
5446int
5447bdd_is_complement(bdd_node *f)
5448{
5449 return(Cudd_IsComplement((DdNode *)f));
5450
5451} /* end of bdd_is_complement */
5452
5453
5454/**Function********************************************************************
5455
5456 Synopsis [Returns the then child of f.]
5457
5458 Description [Returns the then child of f. This is different from
5459 bdd_then.]
5460
5461 SideEffects [none]
5462
5463 SeeAlso [bdd_then]
5464
5465******************************************************************************/
5466bdd_node *
5467bdd_bdd_T(bdd_node *f)
5468{
5469 return(Cudd_T((DdNode *)f));
5470
5471} /* end of bdd_bdd_T */
5472
5473
5474/**Function********************************************************************
5475
5476 Synopsis [Returns the else child of f.]
5477
5478 Description [Returns the else child of f. This is different from
5479 bdd_else.]
5480
5481 SideEffects []
5482
5483 SeeAlso [bdd_else]
5484******************************************************************************/
5485bdd_node *
5486bdd_bdd_E(bdd_node *f)
5487{
5488 return(Cudd_E((DdNode *)f));
5489
5490} /* end of bdd_bdd_E */
5491
5492
5493/**Function********************************************************************
5494
5495 Synopsis [Returns the complement of a bdd_node.]
5496
5497 Description [Returns the complement of a bdd_node.]
5498
5499 SideEffects []
5500
5501 SeeAlso [bdd_not]
5502******************************************************************************/
5503bdd_node *
5504bdd_not_bdd_node(bdd_node *f)
5505{
5506 return(Cudd_Not((DdNode *)f));
5507
5508} /* end of bdd_not_bdd_node */
5509
5510
5511/**Function********************************************************************
5512
5513 Synopsis [Recursively derefs a ZDD.]
5514
5515 Description [Recursively derefs a ZDD.]
5516
5517 SideEffects [bdd_recursive_deref]
5518
5519
5520******************************************************************************/
5521void
5522bdd_recursive_deref_zdd(bdd_manager *mgr, bdd_node *f)
5523{
5524 Cudd_RecursiveDerefZdd((DdManager *)mgr, (DdNode *)f);
5525
5526} /* end of bdd_recursive_deref_zdd */
5527
5528
5529/**Function********************************************************************
5530
5531 Synopsis [Count the number of mintems of a ZDD.]
5532
5533 Description [Count the number of mintems of a ZDD.]
5534
5535 SideEffects []
5536
5537******************************************************************************/
5538int
5539bdd_zdd_count(bdd_manager *mgr, bdd_node *f)
5540{
5541 return(Cudd_zddCount((DdManager *)mgr, (DdNode *)f));
5542
5543} /* end of bdd_zdd_count */
5544
5545
5546/**Function********************************************************************
5547
5548 Synopsis [Returns the level of a of a bdd_node with index, index.]
5549
5550 Description [Returns the level of a of a bdd_node with index, index.]
5551
5552 SideEffects []
5553
5554******************************************************************************/
5555int
5556bdd_read_zdd_level(bdd_manager *mgr, int index)
5557{
5558 return(Cudd_ReadPermZdd((DdManager *)mgr, index));
5559
5560} /* end of bdd_read_zdd_level */
5561
5562
5563/**Function********************************************************************
5564
5565 Synopsis [Creates multiplicity number of ZDD vars for each BDD var.]
5566
5567 Description [Creates one or more ZDD variables for each BDD variable. If
5568 some ZDD variables already exist, only the missing variables are created.
5569 Parameter multiplicity allows the caller to control how many variables are
5570 created for each BDD variable in existence. For instance, if ZDDs are used to
5571 represent covers, two ZDD variables are required for each BDD variable. The
5572 order of the BDD variables is transferred to the ZDD variables. If a variable
5573 group tree exists for the BDD variables, a corresponding ZDD variable group
5574 tree is created by expanding the BDD variable tree. In any case, the ZDD
5575 variables derived from the same BDD variable are merged in a ZDD variable
5576 group. If a ZDD variable group tree exists, it is freed. Returns 1 if
5577 successful; 0 otherwise.]
5578
5579 SideEffects []
5580
5581******************************************************************************/
5582int
5583bdd_zdd_vars_from_bdd_vars(bdd_manager *mgr, int multiplicity)
5584{
5585 return(Cudd_zddVarsFromBddVars((DdManager *)mgr, multiplicity));
5586
5587} /* end of bdd_zdd_vars_from_bdd_vars */
5588
5589
5590/**Function********************************************************************
5591
5592 Synopsis [Enables the alignment of ZDD vars with that of corresponding BDD
5593 vars.]
5594
5595 Description [Enables the alignment of ZDD vars with that of corresponding BDD
5596 vars.]
5597
5598 SideEffects []
5599
5600******************************************************************************/
5601void
5602bdd_zdd_realign_enable(bdd_manager *mgr)
5603{
5604 Cudd_zddRealignEnable((DdManager *)mgr);
5605
5606} /* end of bdd_zdd_realign_enable */
5607
5608
5609/**Function********************************************************************
5610
5611 Synopsis [Disables the alignment of ZDD vars with that of corresponding BDD
5612 vars.]
5613
5614 Description [Disables the alignment of ZDD vars with that of corresponding BDD
5615 vars.]
5616
5617 SideEffects []
5618
5619******************************************************************************/
5620void
5621bdd_zdd_realign_disable(bdd_manager *mgr)
5622{
5623 Cudd_zddRealignDisable((DdManager *)mgr);
5624
5625} /* end of bdd_zdd_realign_disable */
5626
5627
5628/**Function********************************************************************
5629
5630 Synopsis [Returns the value of the variable for the alignment of ZDD vars
5631 with that of corresponding BDD vars.]
5632
5633 Description [Returns the value of the variable for the alignment of ZDD vars
5634 with that of corresponding BDD vars.]
5635
5636 SideEffects []
5637
5638******************************************************************************/
5639int
5640bdd_zdd_realignment_enabled(bdd_manager *mgr)
5641{
5642 return(Cudd_zddRealignmentEnabled((DdManager *)mgr));
5643
5644} /* end of bdd_zdd_realignment_enabled */
5645
5646
5647/**Function********************************************************************
5648
5649 Synopsis [Enables the alignment of BDD vars with that of corresponding ZDD
5650 vars.]
5651
5652 Description [Enables the alignment of BDD vars with that of corresponding ZDD
5653 vars.]
5654
5655 SideEffects []
5656
5657******************************************************************************/
5658void
5659bdd_realign_enable(bdd_manager *mgr)
5660{
5661 Cudd_bddRealignEnable((DdManager *)mgr);
5662
5663} /* end of bdd_realign_enable */
5664
5665
5666/**Function********************************************************************
5667
5668 Synopsis [Disables the alignment of BDD vars with that of corresponding ZDD
5669 vars.]
5670
5671 Description [Disables the alignment of BDD vars with that of corresponding ZDD
5672 vars.]
5673
5674 SideEffects []
5675
5676******************************************************************************/
5677void
5678bdd_realign_disable(bdd_manager *mgr)
5679{
5680 Cudd_bddRealignDisable((DdManager *)mgr);
5681
5682} /* end of bdd_realign_disable */
5683
5684
5685/**Function********************************************************************
5686
5687 Synopsis [Returns the value of the variable for the alignment of BDD vars
5688 with that of corresponding ZDD vars.]
5689
5690 Description [Returns the value of the variable for the alignment of BDD vars
5691 with that of corresponding ZDD vars.]
5692
5693 SideEffects []
5694
5695******************************************************************************/
5696int
5697bdd_realignment_enabled(bdd_manager *mgr)
5698{
5699 return(Cudd_bddRealignmentEnabled((DdManager *)mgr));
5700
5701} /* end of bdd_realignment_enabled */
5702
5703
5704/**Function********************************************************************
5705
5706 Synopsis [Returns the index of bdd_node f.]
5707
5708 Description [Returns the index of bdd_node f.]
5709
5710 SideEffects []
5711
5712 SeeAlso [bdd_top_var_id]
5713
5714******************************************************************************/
5715int
5716bdd_node_read_index(bdd_node *f)
5717{
5718 return(Cudd_NodeReadIndex((DdNode *)f));
5719
5720} /* end of bdd_node_read_index */
5721
5722
5723/**Function********************************************************************
5724
5725 Synopsis [Reads the next field of a DdNode.]
5726
5727 Description [Reads the next field of a DdNode.]
5728
5729 SideEffects []
5730
5731******************************************************************************/
5732bdd_node *
5733bdd_read_next(bdd_node *f)
5734{
5735 return(((DdNode *)f)->next);
5736
5737} /* end of bdd_read_next */
5738
5739
5740/**Function********************************************************************
5741
5742 Synopsis [Sets the next field of a DdNode. This function should NOT be used
5743 by an external user. This is provided here as a patch. This will not be a
5744 part of any further release.]
5745
5746 Description [Sets the next field of a DdNode. This function should NOT be
5747 used by an external user. This is provided here as a patch. This will not be
5748 a part of any further release.]
5749
5750 SideEffects []
5751
5752******************************************************************************/
5753void
5754bdd_set_next(bdd_node *f, bdd_node *g)
5755{
5756 ((DdNode *)f)->next = (DdNode *)g;
5757
5758} /* end of bdd_set_next */
5759
5760
5761/**Function********************************************************************
5762
5763 Synopsis [Read the reordered field of the manager.]
5764
5765 Description [Read the reordered field of the manager.]
5766
5767 SideEffects []
5768
5769******************************************************************************/
5770int
5771bdd_read_reordered_field(bdd_manager *mgr)
5772{
5773 return(((DdManager *)mgr)->reordered);
5774
5775} /* end of bdd_read_reordered_field */
5776
5777
5778/**Function********************************************************************
5779
5780 Synopsis [Set the reordered field of the manager.This is NOT to be
5781 used by an external user. This function will not be a part of future
5782 release.]
5783
5784 Description [Set the reordered field of the manager.This is NOT to be
5785 used by an external user. This function will not be a part of future
5786 release.]
5787
5788 SideEffects []
5789
5790******************************************************************************/
5791void
5792bdd_set_reordered_field(bdd_manager *mgr, int n)
5793{
5794 ((DdManager *)mgr)->reordered = n;
5795
5796} /* end of bdd_set_reordered_field */
5797
5798
5799/**Function********************************************************************
5800
5801 Synopsis [Implements the recursive call of bdd_add_apply.]
5802
5803 Description [Implements the recursive call of bdd_add_apply. This should be
5804 used only in recursive procedures where the order of the variables needs to
5805 remain constant during the entire operation of the procedure. Returns a
5806 pointer to the result if successful. NULL is returned if reordering takes
5807 place or if memory is exhausted.]
5808
5809 SideEffects []
5810
5811******************************************************************************/
5812bdd_node *
5813bdd_add_apply_recur(
5814 bdd_manager *mgr,
5815 bdd_node *(*operation)(bdd_manager *, bdd_node **, bdd_node **),
5816 bdd_node *fn1,
5817 bdd_node *fn2)
5818{
5819 DdNode *result;
5820 result = cuddAddApplyRecur((DdManager *)mgr,
5821 (DdNode *(*)(DdManager *, DdNode **, DdNode **))
5822 operation, (DdNode *)fn1, (DdNode *)fn2);
5823 return(result);
5824
5825} /* end of bdd_add_apply_recur */
5826
5827
5828/**Function********************************************************************
5829
5830 Synopsis [Returns the value of the ADD node.]
5831
5832 Description [Returns the value of the ADD node.]
5833
5834 SideEffects []
5835
5836******************************************************************************/
5837BDD_VALUE_TYPE
5838bdd_add_value(bdd_node *f)
5839{
5840 return(Cudd_V((DdNode *)f));
5841
5842} /* end of bdd_add_value */
5843
5844
5845/**Function********************************************************************
5846
5847 Synopsis [Prints minterms of the bdd.]
5848
5849 Description [.]
5850
5851 SideEffects []
5852
5853******************************************************************************/
5854int
5855bdd_print_minterm(bdd_t *f)
5856{
5857 int result;
5858 result = Cudd_PrintMinterm((DdManager *)f->mgr, (DdNode *)f->node);
5859 return result;
5860
5861} /* end of bdd_print_minterm */
5862
5863
5864/**Function********************************************************************
5865
5866 Synopsis [Prints cover of the bdd.]
5867
5868 Description [.]
5869
5870 SideEffects []
5871
5872******************************************************************************/
5873int
5874bdd_print_cover(bdd_t *f)
5875{
5876 int result;
5877 result = Cudd_bddPrintCover((DdManager *)f->mgr,
5878 (DdNode *)f->node, (DdNode *)f->node);
5879 return result;
5880
5881} /* end of bdd_print_cover */
5882
5883
5884/**Function********************************************************************
5885
5886 Synopsis [Reads the plus inifinity field of the BDD manager.]
5887
5888 Description [Reads the plus inifinity field of the BDD manager.]
5889
5890 SideEffects []
5891
5892******************************************************************************/
5893bdd_node *
5894bdd_read_plus_infinity(bdd_manager *mgr)
5895{
5896 DdNode *result;
5897 result = Cudd_ReadPlusInfinity((DdManager *)mgr);
5898 return (bdd_node *)result;
5899
5900} /* end of bdd_read_plus_infinity */
5901
5902
5903/**Function********************************************************************
5904
5905 Synopsis [Selects pairs from R using a priority function.]
5906
5907 Description [Selects pairs from a relation R(x,y) (given as a BDD)
5908 in such a way that a given x appears in one pair only. Uses a
5909 priority function to determine which y should be paired to a given
5910 x. bdd_priority_select returns a pointer to the selected function
5911 if successful; NULL otherwise. Three of the arguments--x, y, and
5912 z--are vectors of BDD variables. The first two are the variables on
5913 which R depends. The third is a vector of auxiliary variables, used
5914 during the computation. This vector is optional. If a NULL value is
5915 passed instead, bdd_priority_select will create the working
5916 variables on the fly. The sizes of x and y (and z if it is not
5917 NULL) should equal n. The priority function Pi can be passed as a
5918 BDD, or can be built by Cudd_PrioritySelect. If NULL is passed
5919 instead of a bdd_node *, parameter Pifunc is used by
5920 Cudd_PrioritySelect to build a BDD for the priority
5921 function. (Pifunc is a pointer to a C function.) If Pi is not NULL,
5922 then Pifunc is ignored. Pifunc should have the same interface as the
5923 standard priority functions (e.g., bdd_dxygtdxz).]
5924
5925 SideEffects [If called with z == NULL, will create new variables in
5926 the manager.]
5927
5928 SeeAlso [bdd_dxygtdxz bdd_xgty]
5929
5930******************************************************************************/
5931bdd_node *
5932bdd_priority_select(
5933 bdd_manager *mgr,
5934 bdd_node *R,
5935 bdd_node **x,
5936 bdd_node **y,
5937 bdd_node **z,
5938 bdd_node *Pi,
5939 int n,
5940 bdd_node *(*Pifunc)(bdd_manager *, int, bdd_node **, bdd_node **, bdd_node **))
5941{
5942 DdNode *result;
5943 result = Cudd_PrioritySelect((DdManager *)mgr,(DdNode *)R,
5944 (DdNode **)x,(DdNode **)y,
5945 (DdNode **)z,(DdNode *)Pi,
5946 n,(DdNode *(*)(DdManager *, int, DdNode **,
5947 DdNode **, DdNode **))Pifunc);
5948 return (bdd_node *)result;
5949
5950} /* end of bdd_priority_select */
5951
5952
5953/**Function********************************************************************
5954
5955 Synopsis [Set the background value of BDD manager.]
5956
5957 Description [Set the background value of BDD manager.]
5958
5959 SideEffects []
5960
5961******************************************************************************/
5962void
5963bdd_set_background(bdd_manager *mgr, bdd_node *f)
5964{
5965 Cudd_SetBackground((DdManager *)mgr,(DdNode *)f);
5966
5967} /* end of bdd_set_background */
5968
5969
5970/**Function********************************************************************
5971
5972 Synopsis [Read the background value of BDD manager.]
5973
5974 Description [Read the background value of BDD manager.]
5975
5976 SideEffects []
5977
5978******************************************************************************/
5979bdd_node *
5980bdd_read_background(bdd_manager *mgr)
5981{
5982 DdNode *result;
5983 result = Cudd_ReadBackground((DdManager *)mgr);
5984 return (bdd_node *)result;
5985
5986} /* end of bdd_read_background */
5987
5988
5989/**Function********************************************************************
5990
5991 Synopsis [Returns the cofactor of f w.r.t g]
5992
5993 Description [Returns the cofactor of f w.r.t g]
5994
5995 SideEffects []
5996
5997******************************************************************************/
5998bdd_node *
5999bdd_bdd_cofactor(bdd_manager *mgr, bdd_node *f, bdd_node *g)
6000{
6001 DdNode *result;
6002 result = Cudd_Cofactor((DdManager *)mgr,(DdNode *)f,
6003 (DdNode *)g);
6004 return (bdd_node *)result;
6005
6006} /* end of bdd_bdd_cofactor */
6007
6008
6009/**Function********************************************************************
6010
6011 Synopsis [Returns the ITE of f,g and h]
6012
6013 Description [Returns the ITE of f,g and h]
6014
6015 SideEffects []
6016
6017******************************************************************************/
6018bdd_node *
6019bdd_bdd_ite(bdd_manager *mgr, bdd_node *f, bdd_node *g, bdd_node *h)
6020{
6021 DdNode *result;
6022 result = Cudd_bddIte((DdManager *)mgr,(DdNode *)f,
6023 (DdNode *)g,(DdNode *)h);
6024 return (bdd_node *)result;
6025
6026} /* end of bdd_bdd_ite */
6027
6028
6029/**Function********************************************************************
6030
6031 Synopsis [Integer and floating point subtraction.Returns NULL if not a
6032 terminal case; f-g otherwise.]
6033
6034 SideEffects []
6035
6036******************************************************************************/
6037bdd_node *
6038bdd_add_minus(bdd_manager *mgr, bdd_node **fn1, bdd_node **fn2)
6039{
6040 DdNode *result;
6041 result = Cudd_addMinus((DdManager *)mgr, (DdNode **)fn1, (DdNode **)fn2);
6042 return((bdd_node *)result);
6043
6044} /* end of bdd_add_plus */
6045
6046
6047/**Function********************************************************************
6048
6049 Synopsis [Generates a BDD for the function d(x,y) &gt; d(x,z).]
6050
6051 Description [This function generates a BDD for the function d(x,y)
6052 &gt; d(x,z);
6053 x, y, and z are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\],
6054 y\[0\] y\[1\] ... y\[N-1\], and z\[0\] z\[1\] ... z\[N-1\],
6055 with 0 the most significant bit.
6056 The distance d(x,y) is defined as:
6057 \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}).
6058 The BDD is built bottom-up.
6059 It has 7*N-3 internal nodes, if the variables are ordered as follows:
6060 x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ]
6061
6062 SideEffects [None]
6063
6064 SeeAlso [bdd_xgty]
6065
6066******************************************************************************/
6067bdd_node *
6068bdd_dxygtdxz(
6069 bdd_manager *mgr,
6070 int N,
6071 bdd_node **x,
6072 bdd_node **y,
6073 bdd_node **z)
6074{
6075 DdNode *result;
6076 result = Cudd_Dxygtdxz((DdManager *)mgr,N,(DdNode **)x,
6077 (DdNode **)y,(DdNode **)z);
6078 return((bdd_node *)result);
6079
6080} /* end of bdd_dxygtdxz */
6081
6082
6083/**Function********************************************************************
6084
6085 Synopsis [Universally abstracts out the variables from the function]
6086
6087 SideEffects []
6088
6089******************************************************************************/
6090bdd_node *
6091bdd_bdd_univ_abstract(bdd_manager *mgr, bdd_node *fn, bdd_node *vars)
6092{
6093 DdNode *result;
6094 result = Cudd_bddUnivAbstract((DdManager *)mgr, (DdNode *)fn,
6095 (DdNode *)vars);
6096 return((bdd_node *)result);
6097
6098} /* end of bdd_bdd_univ_abstract */
6099
6100
6101/**Function********************************************************************
6102
6103 Synopsis [Computes the compatible projection of R w.r.t. cube Y.]
6104
6105 Description [Computes the compatible projection of relation R with
6106 respect to cube Y.]
6107
6108 SideEffects [None]
6109
6110******************************************************************************/
6111bdd_node *
6112bdd_bdd_cprojection(bdd_manager *mgr, bdd_node *R, bdd_node *Y)
6113{
6114 DdNode *result;
6115 result = Cudd_CProjection((DdManager *)mgr,(DdNode *)R,
6116 (DdNode *)Y);
6117 return (bdd_node *)result;
6118
6119} /* end of bdd_bdd_cprojection */
6120
6121
6122/**Function********************************************************************
6123
6124 Synopsis [Computes the correlation of f and g.]
6125
6126 Description [Computes the correlation of f and g. If f == g, their
6127 correlation is 1. If f == g', their correlation is 0. Returns the
6128 fraction of minterms in the ON-set of the EXNOR of f and g.]
6129
6130 SideEffects [None]
6131
6132******************************************************************************/
6133double
6134bdd_correlation(bdd_t *f, bdd_t *g)
6135{
6136 double result ;
6137 assert(f->mgr == g->mgr);
6138 result = Cudd_bddCorrelation(f->mgr, f->node, g->node);
6139 return (result);
6140
6141} /* end of bdd_correlation */
6142
6143
6144/**Function********************************************************************
6145
6146 Synopsis [Computes 2 partitions of a function.]
6147
6148 Description [Computes 2 partitions of a function. Method based on
6149 DAC98 - Ravi, Somenzi. Picks decomposition points and replaces one
6150 child in each conjunct with 1 (0). returns 2 conjuncts(disjuncts).]
6151
6152 SideEffects []
6153
6154******************************************************************************/
6155int
6156bdd_gen_decomp(bdd_t *f, bdd_partition_type_t partType, bdd_t ***conjArray)
6157{
6158 DdNode **ddArray = NULL;
6159 int i, num = 0;
6160 bdd_t *result;
6161
6162 switch (partType) {
6163 case BDD_CONJUNCTS:
6164 num = Cudd_bddGenConjDecomp(f->mgr, f->node, &ddArray);
6165 break;
6166 case BDD_DISJUNCTS:
6167 num = Cudd_bddGenDisjDecomp(f->mgr, f->node, &ddArray);
6168 break;
6169 }
6170 if ((ddArray == NULL) || (!num)) {
6171 return 0;
6172 }
6173
6174 *conjArray = ALLOC(bdd_t *, num);
6175 if ((*conjArray) == NULL) goto outOfMem;
6176 for (i = 0; i < num; i++) {
6177 result = ALLOC(bdd_t, 1);
6178 if (result == NULL) {
6179 FREE(*conjArray);
6180 goto outOfMem;
6181 }
6182 result->mgr = f->mgr;
6183 result->node = ddArray[i];
6184 result->free = FALSE;
6185 (*conjArray)[i] = result;
6186 }
6187 FREE(ddArray);
6188 return (num);
6189
6190 outOfMem:
6191 for (i = 0; i < num; i++) {
6192 Cudd_RecursiveDeref((DdManager *)f->mgr,(DdNode *)ddArray[i]);
6193 }
6194 FREE(ddArray);
6195 return(0);
6196
6197} /* end of bdd_gen_decomp */
6198
6199
6200/**Function********************************************************************
6201
6202 Synopsis [Computes 2 partitions of a function.]
6203
6204 Description [Computes 2 partitions of a function. Method based on
6205 Cabodi 94. Picks a var and replaces one child in each conjunct with
6206 1 (0). returns 2 conjuncts(disjuncts).]
6207
6208 SideEffects []
6209
6210******************************************************************************/
6211int
6212bdd_var_decomp(bdd_t *f, bdd_partition_type_t partType, bdd_t ***conjArray)
6213{
6214 DdNode **ddArray = NULL;
6215 int i, num = 0;
6216 bdd_t *result;
6217
6218 switch (partType) {
6219 case BDD_CONJUNCTS:
6220 num = Cudd_bddVarConjDecomp(f->mgr, f->node, &ddArray);
6221 break;
6222 case BDD_DISJUNCTS:
6223 num = Cudd_bddVarDisjDecomp(f->mgr, f->node, &ddArray);
6224 break;
6225 }
6226 if ((ddArray == NULL) || (!num)) {
6227 return 0;
6228 }
6229
6230 *conjArray = ALLOC(bdd_t *, num);
6231 if ((*conjArray) == NULL) goto outOfMem;
6232 for (i = 0; i < num; i++) {
6233 result = ALLOC(bdd_t, 1);
6234 if (result == NULL) {
6235 FREE(*conjArray);
6236 goto outOfMem;
6237 }
6238 result->mgr = f->mgr;
6239 result->node = (ddArray)[i];
6240 result->free = FALSE;
6241 (*conjArray)[i] = result;
6242 }
6243 FREE(ddArray);
6244 return (num);
6245
6246 outOfMem:
6247 for (i = 0; i < num; i++) {
6248 Cudd_RecursiveDeref((DdManager *)f->mgr,(DdNode *)ddArray[i]);
6249 }
6250 FREE(ddArray);
6251 return(0);
6252
6253} /* end of bdd_var_decomp */
6254
6255
6256/**Function********************************************************************
6257
6258 Synopsis [Computes 2 partitions of a function.]
6259
6260 Description [Computes 2 partitions of a function. Picks a subset of
6261 a function and minimizes the rest of the function w.r.t. the subset.
6262 returns 2 conjuncts(disjuncts).]
6263
6264 SideEffects []
6265
6266******************************************************************************/
6267int
6268bdd_approx_decomp(bdd_t *f, bdd_partition_type_t partType, bdd_t ***conjArray)
6269{
6270 DdNode **ddArray = NULL;
6271 int i, num = 0;
6272 bdd_t *result;
6273
6274 switch (partType) {
6275 case BDD_CONJUNCTS:
6276 num = Cudd_bddApproxConjDecomp(f->mgr, f->node, &ddArray);
6277 break;
6278 case BDD_DISJUNCTS:
6279 num = Cudd_bddApproxDisjDecomp(f->mgr, f->node, &ddArray);
6280 break;
6281 }
6282 if ((ddArray == NULL) || (!num)) {
6283 return 0;
6284 }
6285
6286 *conjArray = ALLOC(bdd_t *, num);
6287 if ((*conjArray) == NULL) goto outOfMem;
6288 for (i = 0; i < num; i++) {
6289 result = ALLOC(bdd_t, 1);
6290 if (result == NULL) {
6291 FREE(*conjArray);
6292 goto outOfMem;
6293 }
6294 result->mgr = f->mgr;
6295 result->node = ddArray[i];
6296 result->free = FALSE;
6297 (*conjArray)[i] = result;
6298 }
6299 FREE(ddArray);
6300 return (num);
6301
6302 outOfMem:
6303 for (i = 0; i < num; i++) {
6304 Cudd_RecursiveDeref((DdManager *)f->mgr,(DdNode *)ddArray[i]);
6305 }
6306 FREE(ddArray);
6307 return(0);
6308
6309} /* end of bdd_approx_decomp */
6310
6311
6312/**Function********************************************************************
6313
6314 Synopsis [Computes 2 partitions of a function.]
6315
6316 Description [Computes 2 partitions of a function. Picks a subset of
6317 a function and minimizes the rest of the function w.r.t. the
6318 subset. Performs this iteratively. returns 2 conjuncts(disjuncts).]
6319
6320 SideEffects []
6321
6322******************************************************************************/
6323int
6324bdd_iter_decomp(bdd_t *f, bdd_partition_type_t partType, bdd_t ***conjArray)
6325{
6326 DdNode **ddArray;
6327 int i, num = 0;
6328 bdd_t *result;
6329
6330 switch (partType) {
6331 case BDD_CONJUNCTS:
6332 num = Cudd_bddIterConjDecomp(f->mgr, f->node, &ddArray);
6333 break;
6334 case BDD_DISJUNCTS:
6335 num = Cudd_bddIterDisjDecomp(f->mgr, f->node, &ddArray);
6336 break;
6337 }
6338 if ((ddArray == NULL) || (!num)) {
6339 return 0;
6340 }
6341
6342 *conjArray = ALLOC(bdd_t *, num);
6343 if ((*conjArray) == NULL) goto outOfMem;
6344 for (i = 0; i < num; i++) {
6345 result = ALLOC(bdd_t, 1);
6346 if (result == NULL) {
6347 FREE(*conjArray);
6348 goto outOfMem;
6349 }
6350 result->mgr = f->mgr;
6351 result->node = ddArray[i];
6352 result->free = FALSE;
6353 (*conjArray)[i] = result;
6354 }
6355 FREE(ddArray);
6356 return (num);
6357
6358 outOfMem:
6359 for (i = 0; i < num; i++) {
6360 Cudd_RecursiveDeref((DdManager *)f->mgr,(DdNode *)ddArray[i]);
6361 }
6362 FREE(ddArray);
6363 return(0);
6364
6365} /* end of bdd_iter_decomp */
6366
6367
6368/**Function********************************************************************
6369
6370 Synopsis [Solves a Boolean equation.]
6371
6372 SideEffects [The array passed in g is filled with the solutions.]
6373
6374******************************************************************************/
6375bdd_t *
6376bdd_solve_eqn(
6377 bdd_t *f,
6378 array_t *g /* of bdd_t *'s, initially empty */,
6379 array_t *unknowns /* of bdd_t *'s */)
6380{
6381 int i;
6382 bdd_t *variable;
6383 DdNode *cube, *tmpDd, *result, **G;
6384 DdManager *mgr;
6385 int *yIndex = NIL(int);
6386
6387 /* CUDD needs the y variables passed as a cube.
6388 * Therefore we must build that cube from the indices of variables
6389 * in the array before calling the procedure.
6390 */
6391 mgr = f->mgr;
6392 Cudd_Ref(cube = DD_ONE(mgr));
6393 for (i = 0; i < array_n(unknowns); i++) {
6394 variable = array_fetch(bdd_t *,unknowns,i);
6395
6396 /* Make sure the variable belongs to the same manager. */
6397 assert(mgr == variable->mgr);
6398
6399 tmpDd = Cudd_bddAnd(mgr,cube,variable->node);
6400 if (tmpDd == NULL) {
6401 Cudd_RecursiveDeref(mgr,cube);
6402 return(NULL);
6403 }
6404 cuddRef(tmpDd);
6405 Cudd_RecursiveDeref(mgr, cube);
6406 cube = tmpDd;
6407 }
6408
6409 /* Allocate memory for the solutions. */
6410 G = ALLOC(DdNode *,array_n(unknowns));
6411 for (i = 0; i < array_n(unknowns); i++) {
6412 G[i] = NIL(DdNode);
6413 }
6414
6415 /* Solve the equation */
6416 result = Cudd_SolveEqn(mgr,f->node,cube,G,&yIndex,array_n(unknowns));
6417 if (result == NULL) {
6418 Cudd_RecursiveDeref(mgr, cube);
6419 return(NULL);
6420 }
6421 cuddRef(result);
6422 /* Get rid of temporary results. */
6423 Cudd_RecursiveDeref(mgr, cube);
6424
6425 /* Build the bdd_t structure for the solutions. */
6426 for (i = 0; i < array_n(unknowns); i++) {
6427 bdd_t *tmp = bdd_construct_bdd_t(mgr,G[i]);
6428 array_insert_last(bdd_t *, g, tmp);
6429 }
6430
6431 return(bdd_construct_bdd_t(mgr,result));
6432
6433} /* end of bdd_slve_eqn */
6434
6435
6436/**Function********************************************************************
6437
6438 Synopsis [Reports the number of nodes in the manager.]
6439
6440 SideEffects []
6441
6442******************************************************************************/
6443int
6444bdd_read_node_count(bdd_manager *mgr)
6445{
6446 return(Cudd_ReadNodeCount((DdManager *)mgr));
6447
6448} /* end of bdd_read_node_count */
6449
6450
6451/**Function********************************************************************
6452
6453 Synopsis [Computes the fraction of minterms in the on-set of all the
6454 positive cofactors of a BDD, called signatures.]
6455
6456 SideEffects [Creates an array of doubles as large as the number of
6457 variables in the manager + 1. The extra position is to the fraction
6458 of minterms in the on-set of the function.]
6459
6460******************************************************************************/
6461double *
6462bdd_cof_minterm(bdd_t *f)
6463{
6464 double *signatures;
6465 signatures = Cudd_CofMinterm((DdManager *)f->mgr, (DdNode *)f->node);
6466 return (signatures);
6467
6468} /* end of bdd_cof_minterm */
6469
6470
6471/**Function********************************************************************
6472
6473 Synopsis [Estimates the size of the cofactor of f with respect to
6474 var in the specified phase. Return the number of nodes in the
6475 estimated size.]
6476
6477 SideEffects []
6478
6479******************************************************************************/
6480int
6481bdd_estimate_cofactor(bdd_t *f, bdd_t *var, int phase)
6482{
6483 return (Cudd_EstimateCofactor((DdManager *)f->mgr, (DdNode *)f->node,
6484 (int)bdd_top_var_id(var), phase));
6485
6486} /* end of bdd_estimate_cofactor */
6487
6488
6489/**Function********************************************************************
6490
6491 Synopsis [Tests if the varid is unate in f in the specified
6492 phase. If yes, return 1, else 0.]
6493
6494 SideEffects []
6495
6496******************************************************************************/
6497int
6498bdd_test_unate(bdd_t *f, int varId, int phase)
6499{
6500 DdNode *result;
6501 DdNode *one = DD_ONE((DdManager *)f->mgr);
6502
6503 if (phase) {
6504 result = Cudd_Increasing((DdManager *)f->mgr, (DdNode *)f->node, varId);
6505 } else {
6506 result = Cudd_Decreasing((DdManager *)f->mgr, (DdNode *)f->node, varId);
6507 }
6508
6509 if (result == one) {
6510 return 1;
6511 } else {
6512 return 0;
6513 }
6514
6515} /* end of bdd_test_unate */
6516
6517
6518/**Function********************************************************************
6519
6520 Synopsis [Finds the essential variable in a bdd f. Returns an
6521 array_t of vars which are the projection variables with the proper
6522 phase.]
6523
6524 SideEffects [Creates an array_t of bdd_t. Freed by the caller. ]
6525
6526******************************************************************************/
6527array_t *
6528bdd_find_essential(bdd_t *f)
6529{
6530 DdNode *C, *result, *scan, *cube;
6531 array_t *varArray = NIL(array_t);
6532 bdd_t *var;
6533
6534 result = Cudd_FindEssential((DdManager *)f->mgr, (DdNode *)f->node);
6535 if (result == NULL) return NULL;
6536 cuddRef(result);
6537
6538 cube = result;
6539 C = Cudd_Regular(cube);
6540 varArray = array_alloc(bdd_t *, 0);
6541 while (!cuddIsConstant(C)) {
6542 var = bdd_var_with_index(f->mgr, C->index);
6543 scan = cuddT(C);
6544 if (Cudd_NotCond(scan, !Cudd_IsComplement(cube)) == DD_ONE(f->mgr)) {
6545 array_insert_last(bdd_t *, varArray, bdd_not(var));
6546 bdd_free(var);
6547 scan = cuddE(C);
6548 } else {
6549 array_insert_last(bdd_t *, varArray, var);
6550 }
6551 cube = Cudd_NotCond(scan, Cudd_IsComplement(cube));
6552 C = Cudd_Regular(cube);
6553 }
6554
6555 Cudd_RecursiveDeref((DdManager *)f->mgr,result);
6556 return varArray;
6557
6558} /* end of bdd_find_essential */
6559
6560
6561/**Function********************************************************************
6562
6563 Synopsis [Finds the essential variables in a bdd f. Returns a cube
6564 of the variables.]
6565
6566 SideEffects [ ]
6567
6568******************************************************************************/
6569bdd_t *
6570bdd_find_essential_cube(bdd_t *f)
6571{
6572 DdNode *cube;
6573 bdd_t *result;
6574
6575 cube = Cudd_FindEssential((DdManager *)f->mgr, (DdNode *)f->node);
6576 if (cube == NULL) return NULL;
6577 cuddRef(cube);
6578 result = bdd_construct_bdd_t(f->mgr,cube);
6579
6580 return(result);
6581
6582} /* end of bdd_find_essential_cube */
6583
6584
6585/**Function********************************************************************
6586
6587 Synopsis [Generates a BDD for the function x==y.]]
6588
6589 SideEffects []
6590
6591******************************************************************************/
6592bdd_node *
6593bdd_xeqy(
6594 bdd_manager *mgr,
6595 int N,
6596 bdd_node **x,
6597 bdd_node **y)
6598{
6599 DdNode *result;
6600 result = Cudd_Xeqy((DdManager *)mgr,N,(DdNode **)x,
6601 (DdNode **)y);
6602 return((bdd_node *)result);
6603
6604} /* end of bdd_xeqy */
6605
6606
6607/**Function********************************************************************
6608
6609 Synopsis [Rounds off the discriminants of an ADD.]
6610
6611 SideEffects []
6612
6613******************************************************************************/
6614bdd_node *
6615bdd_add_roundoff(bdd_manager *mgr, bdd_node *f, int N)
6616{
6617 DdNode *result;
6618 result = Cudd_addRoundOff((DdManager *)mgr,(DdNode *)f,N);
6619 return((bdd_node *)result);
6620
6621} /* end of bdd_add_roundoff */
6622
6623
6624/**Function********************************************************************
6625
6626 Synopsis [Generates a BDD for the function x &gt; y.]
6627
6628 Description [This function generates a BDD for the function x &gt; y.
6629 Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and
6630 y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit.
6631 The BDD is built bottom-up.
6632 It has 3*N-1 internal nodes, if the variables are ordered as follows:
6633 x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\].]
6634
6635 SideEffects [None]
6636
6637 SeeAlso [bdd_dxygtdxz]
6638
6639******************************************************************************/
6640bdd_node *
6641bdd_xgty(
6642 bdd_manager *mgr,
6643 int N,
6644 bdd_node **x,
6645 bdd_node **y)
6646{
6647 DdNode *result;
6648 result = Cudd_Xgty((DdManager *)mgr,N, NIL(DdNode *),
6649 (DdNode **)x, (DdNode **)y);
6650 return((bdd_node *)result);
6651
6652} /* end of bdd_xgty */
6653
6654
6655/**Function********************************************************************
6656
6657 Synopsis [Computes the complement of an ADD a la C language.]
6658
6659 SideEffects []
6660
6661******************************************************************************/
6662bdd_node *
6663bdd_add_cmpl(bdd_manager *mgr, bdd_node *f)
6664{
6665 DdNode *result;
6666 result = Cudd_addCmpl((DdManager *)mgr,(DdNode *)f);
6667 return((bdd_node *)result);
6668
6669} /* end of bdd_add_cmpl */
6670
6671
6672/**Function********************************************************************
6673
6674 Synopsis [Returns m minterms from a BDD.]
6675
6676 Description [Returns <code>m</code> minterms from a BDD whose
6677 support has <code>n</code> variables at most. The procedure tries
6678 to create as few extra nodes as possible. The function represented
6679 by <code>f</code> depends on at most <code>n</code> of the variables
6680 in <code>x</code>. Returns a BDD with <code>m</code> minterms of the
6681 on-set of f if successful; NULL otherwise.]
6682
6683 SideEffects [None]
6684
6685 SeeAlso []
6686
6687******************************************************************************/
6688bdd_node *
6689bdd_split_set(
6690 bdd_manager *mgr,
6691 bdd_node *f,
6692 bdd_node **x,
6693 int n,
6694 double m)
6695{
6696 DdNode *result;
6697 result = Cudd_SplitSet((DdManager *)mgr,(DdNode *)f,
6698 (DdNode **)x, n, m);
6699 return((bdd_node *)result);
6700
6701} /* end of bdd_split_set */
6702
6703
6704/**Function********************************************************************
6705
6706 Synopsis [Checks for inconsistencies in the BDD manager.]
6707
6708 Description [Checks for inconsistencies in the BDD manager.]
6709
6710 SideEffects [None]
6711
6712 SeeAlso [Cudd_DebugCheck]
6713
6714******************************************************************************/
6715int
6716bdd_debug_check(bdd_manager *mgr)
6717{
6718 return Cudd_DebugCheck((DdManager *)mgr);
6719
6720} /* end of bdd_debug_check */
6721
6722
6723/**Function********************************************************************
6724
6725 Synopsis [Prints the minterns of f in the file stream fp. Precision
6726 can be specified in the last argument. Result is 1 if printing is
6727 successful, else 0.]
6728
6729 SideEffects []
6730
6731******************************************************************************/
6732int
6733bdd_print_apa_minterm(
6734 FILE *fp,
6735 bdd_t *f,
6736 int nvars,
6737 int precision)
6738{
6739 int result;
6740 result = Cudd_ApaPrintMintermExp(fp, (DdManager *)f->mgr,(DdNode *)f->node, nvars, precision);
6741 return(result);
6742
6743} /* end of bdd_print_apa_minterm */
6744
6745
6746/**Function********************************************************************
6747
6748 Synopsis [Compares the ratios of the minterms of 2 bdds and two numbers.
6749 The ratio compared is ((Min(f1)/f1Num)/(Min(f2)/f2Num)). The procedure
6750 returns 1 if the ratio is greater than 1, 0 if they are equal and -1 if the
6751 ratio is less than 1. ]
6752
6753 SideEffects []
6754
6755******************************************************************************/
6756int
6757bdd_apa_compare_ratios(
6758 int nvars,
6759 bdd_t *f1,
6760 bdd_t *f2,
6761 int f1Num,
6762 int f2Num)
6763{
6764 int result;
6765 DdApaNumber f1Min, f2Min;
6766 int digits1, digits2;
6767
6768 f1Min = Cudd_ApaCountMinterm((DdManager *)f1->mgr, (DdNode *)f1->node, nvars, &digits1);
6769 f2Min = Cudd_ApaCountMinterm((DdManager *)f2->mgr, (DdNode *)f2->node, nvars, &digits2);
6770
6771 result = Cudd_ApaCompareRatios(digits1, f1Min, f1Num, digits2, f2Min, f2Num);
6772 return(result);
6773
6774} /* end of bdd_apa_compare_ratios */
6775
6776
6777/**Function********************************************************************
6778
6779 Synopsis [Computes the exclusive-or of f and g.]
6780
6781 SideEffects []
6782
6783******************************************************************************/
6784bdd_node *
6785bdd_bdd_xor(bdd_manager *mgr, bdd_node *f, bdd_node *g)
6786{
6787 DdNode *result;
6788 result = Cudd_bddXor((DdManager *)mgr, (DdNode *)f, (DdNode *)g);
6789
6790 return(result);
6791
6792} /* end of bdd_bdd_xor */
6793
6794
6795/**Function********************************************************************
6796
6797 Synopsis [Generates a blif file by dumpping BDDs. nBdds is the number
6798 of BDDs, bdds is the array of BDDs, inames is the array of primary
6799 input variable names, onames is the array of variable names of BDDs,
6800 and model is a model name in BLIF. inames, onames and model can be
6801 NULL.]
6802
6803 SideEffects []
6804
6805******************************************************************************/
6806void
6807bdd_dump_blif(
6808 bdd_manager *mgr,
6809 int nBdds,
6810 bdd_node **bdds,
6811 char **inames,
6812 char **onames,
6813 char *model,
6814 FILE *fp)
6815{
6816 Cudd_DumpBlif((DdManager *)mgr, nBdds, (DdNode **)bdds, inames, onames,
6817 model, fp, 0);
6818
6819} /* end of bdd_dump_blif */
6820
6821
6822/**Function********************************************************************
6823
6824 Synopsis [Generates a blif body by dumpping BDDs. nBdds is the number
6825 of BDDs, bdds is the array of BDDs, inames is the array of primary
6826 input variable names, onames is the array of variable names of BDDs,
6827 and inames, onames and model can be NULL. This function prints out
6828 only .names body.]
6829
6830 SideEffects []
6831
6832******************************************************************************/
6833void
6834bdd_dump_blif_body(
6835 bdd_manager *mgr,
6836 int nBdds,
6837 bdd_node **bdds,
6838 char **inames,
6839 char **onames,
6840 FILE *fp)
6841{
6842 Cudd_DumpBlifBody((DdManager *)mgr, nBdds, (DdNode **)bdds, inames, onames,
6843 fp, 0);
6844
6845} /* end of bdd_dump_blif_body */
6846
6847
6848/**Function********************************************************************
6849
6850 Synopsis [Generates a dot file by dumpping BDDs. nBdds is the number
6851 of BDDs, bdds is the array of BDDs, inames is the array of primary
6852 input variable names, and onames is the array of variable names of BDDs.
6853 inames, onames and model can be NULL.]
6854
6855 SideEffects []
6856
6857******************************************************************************/
6858void
6859bdd_dump_dot(
6860 bdd_manager *mgr,
6861 int nBdds,
6862 bdd_node **bdds,
6863 char **inames,
6864 char **onames,
6865 FILE *fp)
6866{
6867 Cudd_DumpDot((DdManager *)mgr, nBdds, (DdNode **)bdds, inames, onames, fp);
6868
6869} /* end of bdd_dump_dot */
6870
6871
6872/**Function********************************************************************
6873
6874 Synopsis [Converts a ZDD cover to a BDD graph.]
6875
6876 SideEffects []
6877
6878******************************************************************************/
6879bdd_node *
6880bdd_make_bdd_from_zdd_cover(bdd_manager *mgr, bdd_node *node)
6881{
6882 return((bdd_node *)Cudd_MakeBddFromZddCover((DdManager *)mgr, (DdNode *)node));
6883
6884} /* end of bdd_make_bdd_from_zdd_cover */
6885
6886
6887/**Function********************************************************************
6888
6889 Synopsis [Computes the complement of a ZDD cover.]
6890
6891 SideEffects []
6892
6893******************************************************************************/
6894bdd_node *
6895bdd_zdd_complement(bdd_manager *mgr, bdd_node *node)
6896{
6897 return((bdd_node *)Cudd_zddComplement((DdManager *)mgr, (DdNode *)node));
6898
6899} /* end of bdd_zdd_complement */
6900
6901
6902/**Function********************************************************************
6903
6904 Synopsis [Finds the variables on which a set of DDs depends.]
6905
6906 SideEffects []
6907
6908******************************************************************************/
6909bdd_node *
6910bdd_bdd_vector_support(bdd_manager *mgr, bdd_node **F, int n)
6911{
6912 return((bdd_node *)Cudd_VectorSupport((DdManager *)mgr,(DdNode **)F,n));
6913
6914} /* end of bdd_bdd_vector_support */
6915
6916
6917/**Function********************************************************************
6918
6919 Synopsis [Count the variables on which a set of DDs depend.]
6920
6921 SideEffects []
6922
6923******************************************************************************/
6924int
6925bdd_bdd_vector_support_size(bdd_manager *mgr, bdd_node **F, int n)
6926{
6927 return(Cudd_VectorSupportSize((DdManager *)mgr,(DdNode **)F,n));
6928
6929} /* end of bdd_bdd_vector_support_size */
6930
6931
6932/**Function********************************************************************
6933
6934 Synopsis [Count the variables on which a DD depends.]
6935
6936 SideEffects []
6937
6938******************************************************************************/
6939int
6940bdd_bdd_support_size(bdd_manager *mgr, bdd_node *F)
6941{
6942 return(Cudd_SupportSize((DdManager *)mgr,(DdNode *)F));
6943
6944} /* end of bdd_bdd_support_size */
6945
6946
6947/**Function********************************************************************
6948
6949 Synopsis [Returns the BDD of the variables on which F depends.]
6950
6951 SideEffects []
6952
6953******************************************************************************/
6954bdd_node *
6955bdd_bdd_support(bdd_manager *mgr, bdd_node *F)
6956{
6957 return((bdd_node *)Cudd_Support((DdManager *)mgr,(DdNode *)F));
6958
6959} /* end of bdd_bdd_support */
6960
6961
6962/**Function********************************************************************
6963
6964 Synopsis [Composes an ADD with a vector of ADDs.]
6965
6966 SideEffects []
6967
6968******************************************************************************/
6969bdd_node *
6970bdd_add_general_vector_compose(
6971 bdd_manager *mgr,
6972 bdd_node *f,
6973 bdd_node **vectorOn,
6974 bdd_node **vectorOff)
6975{
6976 return((bdd_node *)Cudd_addGeneralVectorCompose((DdManager *)mgr,
6977 (DdNode *)f,
6978 (DdNode **)vectorOn,
6979 (DdNode **)vectorOff));
6980
6981} /* end of bdd_add_general_vector_compose */
6982
6983
6984/**Function********************************************************************
6985
6986 Synopsis [Computes the boolean difference of f w.r.t to variable x.]
6987
6988 SideEffects []
6989
6990******************************************************************************/
6991bdd_node *
6992bdd_bdd_boolean_diff(bdd_manager *mgr, bdd_node *f, int x)
6993{
6994 return ((bdd_node *)Cudd_bddBooleanDiff((DdManager *)mgr,(DdNode *)f,x));
6995
6996} /* end of bdd_bdd_boolean_diff */
6997
6998
6999/**Function********************************************************************
7000
7001 Synopsis [Check whether two BDDs intersect.]
7002
7003 SideEffects []
7004
7005******************************************************************************/
7006int
7007bdd_bdd_leq(bdd_manager *mgr, bdd_node *f, bdd_node *g)
7008{
7009 return Cudd_bddLeq((DdManager *)mgr,(DdNode *)f,(DdNode *)g);
7010
7011} /* end of bdd_bdd_leq */
7012
7013
7014/**Function********************************************************************
7015
7016 Synopsis [Checks whether two bdds are same.]
7017
7018 SideEffects []
7019
7020******************************************************************************/
7021int
7022bdd_ptrcmp(bdd_t *f, bdd_t *g)
7023{
7024 if (f->node == g->node)
7025 return(0);
7026 else
7027 return(1);
7028
7029} /* end of bdd_ptrcmp */
7030
7031
7032/**Function********************************************************************
7033
7034 Synopsis [Returns the hash value of a bdd.]
7035
7036 SideEffects []
7037
7038******************************************************************************/
7039int
7040bdd_ptrhash(bdd_t *f, int size)
7041{
7042 int hash;
7043
7044 hash = (int)((unsigned long)f->node >> 2) % size;
7045 return(hash);
7046
7047} /* end of bdd_ptrhash */
7048
7049
7050/**Function********************************************************************
7051
7052 Synopsis [Returns the peak memory in use.]
7053
7054 SideEffects []
7055
7056******************************************************************************/
7057long
7058bdd_read_peak_memory(bdd_manager *mgr)
7059{
7060 return((long) Cudd_ReadMemoryInUse((DdManager *) mgr));
7061
7062} /* end of bdd_read_peak_memory */
7063
7064
7065/**Function********************************************************************
7066
7067 Synopsis [Returns the peak live node count.]
7068
7069 SideEffects []
7070
7071******************************************************************************/
7072int
7073bdd_read_peak_live_node(bdd_manager *mgr)
7074{
7075 return(Cudd_ReadPeakLiveNodeCount((DdManager *) mgr));
7076
7077} /* end of bdd_read_peak_live_node */
7078
7079
7080/**Function********************************************************************
7081
7082 Synopsis [Sets a variable type to primary input.]
7083
7084 SideEffects [none]
7085
7086******************************************************************************/
7087int
7088bdd_set_pi_var(bdd_manager *mgr, int index)
7089{
7090 return Cudd_bddSetPiVar((DdManager *) mgr, index);
7091
7092} /* bdd_set_pi_var */
7093
7094
7095/**Function********************************************************************
7096
7097 Synopsis [Sets a variable type to present state.]
7098
7099 SideEffects [none]
7100
7101******************************************************************************/
7102int
7103bdd_set_ps_var(bdd_manager *mgr, int index)
7104{
7105 return Cudd_bddSetPsVar((DdManager *) mgr, index);
7106
7107} /* end of bdd_set_ps_var */
7108
7109
7110/**Function********************************************************************
7111
7112 Synopsis [Sets a variable type to next state.]
7113
7114 SideEffects [none]
7115
7116******************************************************************************/
7117int
7118bdd_set_ns_var(bdd_manager *mgr, int index)
7119{
7120 return Cudd_bddSetNsVar((DdManager *) mgr, index);
7121
7122} /* end of bdd_set_ns_var */
7123
7124
7125/**Function********************************************************************
7126
7127 Synopsis [Checks whether a variable is primary input.]
7128
7129 SideEffects [none]
7130
7131******************************************************************************/
7132int
7133bdd_is_pi_var(bdd_manager *mgr, int index)
7134{
7135 return Cudd_bddIsPiVar((DdManager *) mgr, index);
7136
7137} /* end of bdd_is_pi_var */
7138
7139
7140/**Function********************************************************************
7141
7142 Synopsis [Checks whether a variable is present state.]
7143
7144 SideEffects [none]
7145
7146******************************************************************************/
7147int
7148bdd_is_ps_var(bdd_manager *mgr, int index)
7149{
7150 return Cudd_bddIsPsVar((DdManager *) mgr, index);
7151
7152} /* end of bdd_is_ps_var */
7153
7154
7155/**Function********************************************************************
7156
7157 Synopsis [Checks whether a variable is next state.]
7158
7159 SideEffects [none]
7160
7161******************************************************************************/
7162int
7163bdd_is_ns_var(bdd_manager *mgr, int index)
7164{
7165 return Cudd_bddIsNsVar((DdManager *) mgr, index);
7166
7167} /* end of bdd_is_ns_var */
7168
7169
7170/**Function********************************************************************
7171
7172 Synopsis [Sets a corresponding pair index for a given index.]
7173
7174 Description [Sets a corresponding pair index for a given index.
7175 These pair indices are present and next state variable.]
7176
7177 SideEffects [none]
7178
7179******************************************************************************/
7180int
7181bdd_set_pair_index(bdd_manager *mgr, int index, int pairidx)
7182{
7183 return Cudd_bddSetPairIndex((DdManager *) mgr, index, pairidx);
7184
7185} /* end of bdd_set_pair_index */
7186
7187
7188/**Function********************************************************************
7189
7190 Synopsis [Reads a corresponding pair index for a given index.]
7191
7192 Description [Reads a corresponding pair index for a given index.
7193 These pair indices are present and next state variable.]
7194
7195 SideEffects [none]
7196
7197******************************************************************************/
7198int
7199bdd_read_pair_index(bdd_manager *mgr, int index)
7200{
7201 return Cudd_bddReadPairIndex((DdManager *) mgr, index);
7202
7203} /* end of bdd_read_pair_index */
7204
7205
7206/**Function********************************************************************
7207
7208 Synopsis [Sets a variable to be grouped.]
7209
7210 Description [Sets a variable to be grouped. This function is used for
7211 lazy sifting.]
7212
7213 SideEffects [none]
7214
7215******************************************************************************/
7216int
7217bdd_set_var_to_be_grouped(bdd_manager *mgr, int index)
7218{
7219 return Cudd_bddSetVarToBeGrouped((DdManager *) mgr, index);
7220
7221} /* end of bdd_set_var_to_be_grouped */
7222
7223
7224/**Function********************************************************************
7225
7226 Synopsis [Sets a variable to be a hard group.]
7227
7228 Description [Sets a variable to be a hard group. This function is used
7229 for lazy sifting.]
7230
7231 SideEffects [none]
7232
7233******************************************************************************/
7234int
7235bdd_set_var_hard_group(bdd_manager *mgr, int index)
7236{
7237 return Cudd_bddSetVarHardGroup((DdManager *) mgr, index);
7238
7239} /* end of bdd_set_var_hard_group */
7240
7241
7242/**Function********************************************************************
7243
7244 Synopsis [Resets a variable not to be grouped.]
7245
7246 Description [Resets a variable not to be grouped. This function is
7247 used for lazy sifting.]
7248
7249 SideEffects [none]
7250
7251******************************************************************************/
7252int
7253bdd_reset_var_to_be_grouped(bdd_manager *mgr, int index)
7254{
7255 return Cudd_bddResetVarToBeGrouped((DdManager *) mgr, index);
7256
7257} /* end of bdd_reset_var_to_be_grouped */
7258
7259
7260/**Function********************************************************************
7261
7262 Synopsis [Checks whether a variable is set to be grouped.]
7263
7264 Description [Checks whether a variable is set to be grouped. This
7265 function is used for lazy sifting.]
7266
7267 SideEffects [none]
7268
7269******************************************************************************/
7270int
7271bdd_is_var_to_be_grouped(bdd_manager *mgr, int index)
7272{
7273 return Cudd_bddIsVarToBeGrouped((DdManager *) mgr, index);
7274
7275} /* end of bdd_is_var_to_be_grouped */
7276
7277
7278/**Function********************************************************************
7279
7280 Synopsis [Checks whether a variable is set to be a hard group.]
7281
7282 Description [Checks whether a variable is set to be a hard group. This
7283 function is used for lazy sifting.]
7284
7285 SideEffects [none]
7286
7287******************************************************************************/
7288int
7289bdd_is_var_hard_group(bdd_manager *mgr, int index)
7290{
7291 return Cudd_bddIsVarHardGroup((DdManager *) mgr, index);
7292
7293} /* end of bdd_is_var_hard_group */
7294
7295
7296/**Function********************************************************************
7297
7298 Synopsis [Sets a variable to be ungrouped.]
7299
7300 Description [Sets a variable to be ungrouped. This function is used
7301 for lazy sifting.]
7302
7303 SideEffects [none]
7304
7305******************************************************************************/
7306int
7307bdd_is_var_to_be_ungrouped(bdd_manager *mgr, int index)
7308{
7309 return Cudd_bddIsVarToBeUngrouped((DdManager *) mgr, index);
7310
7311} /* end of bdd_is_var_to_be_ungrouped */
7312
7313
7314/**Function********************************************************************
7315
7316 Synopsis [Sets a variable to be ungrouped.]
7317
7318 Description [Sets a variable to be ungrouped. This function is used
7319 for lazy sifting.]
7320
7321 SideEffects [none]
7322
7323******************************************************************************/
7324int
7325bdd_set_var_to_be_ungrouped(bdd_manager *mgr, int index)
7326{
7327 return Cudd_bddSetVarToBeUngrouped((DdManager *) mgr, index);
7328
7329} /* end of bdd_set_var_to_be_ungrouped */
7330
7331
7332/**Function********************************************************************
7333
7334 Synopsis [Prevents sifting of a variable.]
7335
7336 Description [This function sets a flag to prevent sifting of a
7337 variable. Returns 1 if successful; 0 otherwise (i.e., invalid
7338 variable index).]
7339
7340 SideEffects [Changes the "bindVar" flag in DdSubtable.]
7341
7342******************************************************************************/
7343int
7344bdd_bind_var(bdd_manager *mgr, int index)
7345{
7346 return Cudd_bddBindVar((DdManager *) mgr, index);
7347
7348} /* end of bdd_bind_var */
7349
7350
7351/**Function********************************************************************
7352
7353 Synopsis [Allows the sifting of a variable.]
7354
7355 Description [This function resets the flag that prevents the sifting
7356 of a variable. In successive variable reorderings, the variable will
7357 NOT be skipped, that is, sifted. Initially all variables can be
7358 sifted. It is necessary to call this function only to re-enable
7359 sifting after a call to Cudd_bddBindVar. Returns 1 if successful; 0
7360 otherwise (i.e., invalid variable index).]
7361
7362 SideEffects [Changes the "bindVar" flag in DdSubtable.]
7363
7364******************************************************************************/
7365int
7366bdd_unbind_var(bdd_manager *mgr, int index)
7367{
7368 return Cudd_bddUnbindVar((DdManager *) mgr, index);
7369
7370} /* end of bdd_unbind_var */
7371
7372
7373/**Function********************************************************************
7374
7375 Synopsis [Checks whether lazy sifting is on.]
7376
7377 SideEffects [none]
7378
7379******************************************************************************/
7380int
7381bdd_is_lazy_sift(bdd_manager *mgr)
7382{
7383 Cudd_ReorderingType method;
7384
7385 Cudd_ReorderingStatus((DdManager *) mgr, &method);
7386 if (method == CUDD_REORDER_LAZY_SIFT)
7387 return(1);
7388 return(0);
7389
7390} /* end of bdd_is_lazy_sift */
7391
7392
7393/**Function********************************************************************
7394
7395 Synopsis [Frees the variable group tree of the manager.]
7396
7397 SideEffects [None]
7398
7399******************************************************************************/
7400void
7401bdd_discard_all_var_groups(bdd_manager *mgr)
7402{
7403 Cudd_FreeTree((DdManager *) mgr);
7404
7405} /* end of bdd_discard_all_var_groups */
7406
7407
7408/*---------------------------------------------------------------------------*/
7409/* Definition of internal functions */
7410/*---------------------------------------------------------------------------*/
7411
7412
7413/*---------------------------------------------------------------------------*/
7414/* Definition of static functions */
7415/*---------------------------------------------------------------------------*/
7416
7417/**Function********************************************************************
7418
7419 Synopsis [Function to print a warning that an illegal value was read.]
7420
7421 SideEffects []
7422
7423 SeeAlso [bdd_set_parameters]
7424
7425******************************************************************************/
7426static void
7427InvalidType(FILE *file, const char *field, const char *expected)
7428{
7429 (void) fprintf(file, "Warning: In parameter \"%s\"\n", field);
7430 (void) fprintf(file, "Illegal type detected. %s expected\n", expected);
7431
7432} /* end of InvalidType */
Note: See TracBrowser for help on using the repository browser.