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

Last change on this file since 104 was 21, checked in by cecile, 13 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.