source: vis_dev/glu-2.1/src/cuPort/cuPort.c @ 8

Last change on this file since 8 was 8, checked in by cecile, 13 years ago

src glu

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