abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddZddSetop.c
Go to the documentation of this file.
1 /**CFile***********************************************************************
2 
3  FileName [cuddZddSetop.c]
4 
5  PackageName [cudd]
6 
7  Synopsis [Set operations on ZDDs.]
8 
9  Description [External procedures included in this module:
10  <ul>
11  <li> Cudd_zddIte()
12  <li> Cudd_zddUnion()
13  <li> Cudd_zddIntersect()
14  <li> Cudd_zddDiff()
15  <li> Cudd_zddDiffConst()
16  <li> Cudd_zddSubset1()
17  <li> Cudd_zddSubset0()
18  <li> Cudd_zddChange()
19  </ul>
20  Internal procedures included in this module:
21  <ul>
22  <li> cuddZddIte()
23  <li> cuddZddUnion()
24  <li> cuddZddIntersect()
25  <li> cuddZddDiff()
26  <li> cuddZddChangeAux()
27  <li> cuddZddSubset1()
28  <li> cuddZddSubset0()
29  </ul>
30  Static procedures included in this module:
31  <ul>
32  <li> zdd_subset1_aux()
33  <li> zdd_subset0_aux()
34  <li> zddVarToConst()
35  </ul>
36  ]
37 
38  SeeAlso []
39 
40  Author [Hyong-Kyoon Shin, In-Ho Moon]
41 
42  Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
43 
44  All rights reserved.
45 
46  Redistribution and use in source and binary forms, with or without
47  modification, are permitted provided that the following conditions
48  are met:
49 
50  Redistributions of source code must retain the above copyright
51  notice, this list of conditions and the following disclaimer.
52 
53  Redistributions in binary form must reproduce the above copyright
54  notice, this list of conditions and the following disclaimer in the
55  documentation and/or other materials provided with the distribution.
56 
57  Neither the name of the University of Colorado nor the names of its
58  contributors may be used to endorse or promote products derived from
59  this software without specific prior written permission.
60 
61  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
62  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
63  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
64  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
65  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
66  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
67  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
68  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
69  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
70  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
71  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
72  POSSIBILITY OF SUCH DAMAGE.]
73 
74 ******************************************************************************/
75 
76 #include "misc/util/util_hack.h"
77 #include "cuddInt.h"
78 
80 
81 
82 
83 /*---------------------------------------------------------------------------*/
84 /* Constant declarations */
85 /*---------------------------------------------------------------------------*/
86 
87 
88 /*---------------------------------------------------------------------------*/
89 /* Stucture declarations */
90 /*---------------------------------------------------------------------------*/
91 
92 
93 /*---------------------------------------------------------------------------*/
94 /* Type declarations */
95 /*---------------------------------------------------------------------------*/
96 
97 
98 /*---------------------------------------------------------------------------*/
99 /* Variable declarations */
100 /*---------------------------------------------------------------------------*/
101 
102 #ifndef lint
103 static char rcsid[] DD_UNUSED = "$Id: cuddZddSetop.c,v 1.25 2004/08/13 18:04:54 fabio Exp $";
104 #endif
105 
106 /*---------------------------------------------------------------------------*/
107 /* Macro declarations */
108 /*---------------------------------------------------------------------------*/
109 
110 #ifdef __cplusplus
111 extern "C" {
112 #endif
113 
114 /**AutomaticStart*************************************************************/
115 
116 /*---------------------------------------------------------------------------*/
117 /* Static function prototypes */
118 /*---------------------------------------------------------------------------*/
119 
120 static DdNode * zdd_subset1_aux (DdManager *zdd, DdNode *P, DdNode *zvar);
121 static DdNode * zdd_subset0_aux (DdManager *zdd, DdNode *P, DdNode *zvar);
122 static void zddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *base, DdNode *empty);
123 
124 /**AutomaticEnd***************************************************************/
125 
126 #ifdef __cplusplus
127 }
128 #endif
129 
130 /*---------------------------------------------------------------------------*/
131 /* Definition of exported functions */
132 /*---------------------------------------------------------------------------*/
133 
134 
135 /**Function********************************************************************
136 
137  Synopsis [Computes the ITE of three ZDDs.]
138 
139  Description [Computes the ITE of three ZDDs. Returns a pointer to the
140  result if successful; NULL otherwise.]
141 
142  SideEffects [None]
143 
144  SeeAlso []
145 
146 ******************************************************************************/
147 DdNode *
149  DdManager * dd,
150  DdNode * f,
151  DdNode * g,
152  DdNode * h)
153 {
154  DdNode *res;
155 
156  do {
157  dd->reordered = 0;
158  res = cuddZddIte(dd, f, g, h);
159  } while (dd->reordered == 1);
160  return(res);
161 
162 } /* end of Cudd_zddIte */
163 
164 
165 /**Function********************************************************************
166 
167  Synopsis [Computes the union of two ZDDs.]
168 
169  Description [Computes the union of two ZDDs. Returns a pointer to the
170  result if successful; NULL otherwise.]
171 
172  SideEffects [None]
173 
174  SeeAlso []
175 
176 ******************************************************************************/
177 DdNode *
179  DdManager * dd,
180  DdNode * P,
181  DdNode * Q)
182 {
183  DdNode *res;
184 
185  do {
186  dd->reordered = 0;
187  res = cuddZddUnion(dd, P, Q);
188  } while (dd->reordered == 1);
189  return(res);
190 
191 } /* end of Cudd_zddUnion */
192 
193 
194 /**Function********************************************************************
195 
196  Synopsis [Computes the intersection of two ZDDs.]
197 
198  Description [Computes the intersection of two ZDDs. Returns a pointer to
199  the result if successful; NULL otherwise.]
200 
201  SideEffects [None]
202 
203  SeeAlso []
204 
205 ******************************************************************************/
206 DdNode *
208  DdManager * dd,
209  DdNode * P,
210  DdNode * Q)
211 {
212  DdNode *res;
213 
214  do {
215  dd->reordered = 0;
216  res = cuddZddIntersect(dd, P, Q);
217  } while (dd->reordered == 1);
218  return(res);
219 
220 } /* end of Cudd_zddIntersect */
221 
222 
223 /**Function********************************************************************
224 
225  Synopsis [Computes the difference of two ZDDs.]
226 
227  Description [Computes the difference of two ZDDs. Returns a pointer to the
228  result if successful; NULL otherwise.]
229 
230  SideEffects [None]
231 
232  SeeAlso [Cudd_zddDiffConst]
233 
234 ******************************************************************************/
235 DdNode *
237  DdManager * dd,
238  DdNode * P,
239  DdNode * Q)
240 {
241  DdNode *res;
242 
243  do {
244  dd->reordered = 0;
245  res = cuddZddDiff(dd, P, Q);
246  } while (dd->reordered == 1);
247  return(res);
248 
249 } /* end of Cudd_zddDiff */
250 
251 
252 /**Function********************************************************************
253 
254  Synopsis [Performs the inclusion test for ZDDs (P implies Q).]
255 
256  Description [Inclusion test for ZDDs (P implies Q). No new nodes are
257  generated by this procedure. Returns empty if true;
258  a valid pointer different from empty or DD_NON_CONSTANT otherwise.]
259 
260  SideEffects [None]
261 
262  SeeAlso [Cudd_zddDiff]
263 
264 ******************************************************************************/
265 DdNode *
267  DdManager * zdd,
268  DdNode * P,
269  DdNode * Q)
270 {
271  int p_top, q_top;
272  DdNode *empty = DD_ZERO(zdd), *t, *res;
273  DdManager *table = zdd;
274 
275  statLine(zdd);
276  if (P == empty)
277  return(empty);
278  if (Q == empty)
279  return(P);
280  if (P == Q)
281  return(empty);
282 
283  /* Check cache. The cache is shared by cuddZddDiff(). */
284  res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q);
285  if (res != NULL)
286  return(res);
287 
288  if (cuddIsConstant(P))
289  p_top = P->index;
290  else
291  p_top = zdd->permZ[P->index];
292  if (cuddIsConstant(Q))
293  q_top = Q->index;
294  else
295  q_top = zdd->permZ[Q->index];
296  if (p_top < q_top) {
297  res = DD_NON_CONSTANT;
298  } else if (p_top > q_top) {
299  res = Cudd_zddDiffConst(zdd, P, cuddE(Q));
300  } else {
301  t = Cudd_zddDiffConst(zdd, cuddT(P), cuddT(Q));
302  if (t != empty)
303  res = DD_NON_CONSTANT;
304  else
305  res = Cudd_zddDiffConst(zdd, cuddE(P), cuddE(Q));
306  }
307 
308  cuddCacheInsert2(table, cuddZddDiff, P, Q, res);
309 
310  return(res);
311 
312 } /* end of Cudd_zddDiffConst */
313 
314 
315 /**Function********************************************************************
316 
317  Synopsis [Computes the positive cofactor of a ZDD w.r.t. a variable.]
318 
319  Description [Computes the positive cofactor of a ZDD w.r.t. a
320  variable. In terms of combinations, the result is the set of all
321  combinations in which the variable is asserted. Returns a pointer to
322  the result if successful; NULL otherwise.]
323 
324  SideEffects [None]
325 
326  SeeAlso [Cudd_zddSubset0]
327 
328 ******************************************************************************/
329 DdNode *
331  DdManager * dd,
332  DdNode * P,
333  int var)
334 {
335  DdNode *r;
336 
337  do {
338  dd->reordered = 0;
339  r = cuddZddSubset1(dd, P, var);
340  } while (dd->reordered == 1);
341 
342  return(r);
343 
344 } /* end of Cudd_zddSubset1 */
345 
346 
347 /**Function********************************************************************
348 
349  Synopsis [Computes the negative cofactor of a ZDD w.r.t. a variable.]
350 
351  Description [Computes the negative cofactor of a ZDD w.r.t. a
352  variable. In terms of combinations, the result is the set of all
353  combinations in which the variable is negated. Returns a pointer to
354  the result if successful; NULL otherwise.]
355 
356  SideEffects [None]
357 
358  SeeAlso [Cudd_zddSubset1]
359 
360 ******************************************************************************/
361 DdNode *
363  DdManager * dd,
364  DdNode * P,
365  int var)
366 {
367  DdNode *r;
368 
369  do {
370  dd->reordered = 0;
371  r = cuddZddSubset0(dd, P, var);
372  } while (dd->reordered == 1);
373 
374  return(r);
375 
376 } /* end of Cudd_zddSubset0 */
377 
378 
379 /**Function********************************************************************
380 
381  Synopsis [Substitutes a variable with its complement in a ZDD.]
382 
383  Description [Substitutes a variable with its complement in a ZDD.
384  returns a pointer to the result if successful; NULL otherwise.]
385 
386  SideEffects [None]
387 
388  SeeAlso []
389 
390 ******************************************************************************/
391 DdNode *
393  DdManager * dd,
394  DdNode * P,
395  int var)
396 {
397  DdNode *res;
398 
399  if ((unsigned int) var >= CUDD_MAXINDEX - 1) return(NULL);
400 
401  do {
402  dd->reordered = 0;
403  res = cuddZddChange(dd, P, var);
404  } while (dd->reordered == 1);
405  return(res);
406 
407 } /* end of Cudd_zddChange */
408 
409 
410 /*---------------------------------------------------------------------------*/
411 /* Definition of internal functions */
412 /*---------------------------------------------------------------------------*/
413 
414 
415 /**Function********************************************************************
416 
417  Synopsis [Performs the recursive step of Cudd_zddIte.]
418 
419  Description []
420 
421  SideEffects [None]
422 
423  SeeAlso []
424 
425 ******************************************************************************/
426 DdNode *
428  DdManager * dd,
429  DdNode * f,
430  DdNode * g,
431  DdNode * h)
432 {
434  DdNode *r,*Gv,*Gvn,*Hv,*Hvn,*t,*e;
435  unsigned int topf,topg,toph,v,top;
436  int index;
437 
438  statLine(dd);
439  /* Trivial cases. */
440  /* One variable cases. */
441  if (f == (empty = DD_ZERO(dd))) { /* ITE(0,G,H) = H */
442  return(h);
443  }
444  topf = cuddIZ(dd,f->index);
445  topg = cuddIZ(dd,g->index);
446  toph = cuddIZ(dd,h->index);
447  v = ddMin(topg,toph);
448  top = ddMin(topf,v);
449 
450  tautology = (top == CUDD_MAXINDEX) ? DD_ONE(dd) : dd->univ[top];
451  if (f == tautology) { /* ITE(1,G,H) = G */
452  return(g);
453  }
454 
455  /* From now on, f is known to not be a constant. */
456  zddVarToConst(f,&g,&h,tautology,empty);
457 
458  /* Check remaining one variable cases. */
459  if (g == h) { /* ITE(F,G,G) = G */
460  return(g);
461  }
462 
463  if (g == tautology) { /* ITE(F,1,0) = F */
464  if (h == empty) return(f);
465  }
466 
467  /* Check cache. */
468  r = cuddCacheLookupZdd(dd,DD_ZDD_ITE_TAG,f,g,h);
469  if (r != NULL) {
470  return(r);
471  }
472 
473  /* Recompute these because they may have changed in zddVarToConst. */
474  topg = cuddIZ(dd,g->index);
475  toph = cuddIZ(dd,h->index);
476  v = ddMin(topg,toph);
477 
478  if (topf < v) {
479  r = cuddZddIte(dd,cuddE(f),g,h);
480  if (r == NULL) return(NULL);
481  } else if (topf > v) {
482  if (topg > v) {
483  Gvn = g;
484  index = h->index;
485  } else {
486  Gvn = cuddE(g);
487  index = g->index;
488  }
489  if (toph > v) {
490  Hv = empty; Hvn = h;
491  } else {
492  Hv = cuddT(h); Hvn = cuddE(h);
493  }
494  e = cuddZddIte(dd,f,Gvn,Hvn);
495  if (e == NULL) return(NULL);
496  cuddRef(e);
497  r = cuddZddGetNode(dd,index,Hv,e);
498  if (r == NULL) {
500  return(NULL);
501  }
502  cuddDeref(e);
503  } else {
504  index = f->index;
505  if (topg > v) {
506  Gv = empty; Gvn = g;
507  } else {
508  Gv = cuddT(g); Gvn = cuddE(g);
509  }
510  if (toph > v) {
511  Hv = empty; Hvn = h;
512  } else {
513  Hv = cuddT(h); Hvn = cuddE(h);
514  }
515  e = cuddZddIte(dd,cuddE(f),Gvn,Hvn);
516  if (e == NULL) return(NULL);
517  cuddRef(e);
518  t = cuddZddIte(dd,cuddT(f),Gv,Hv);
519  if (t == NULL) {
521  return(NULL);
522  }
523  cuddRef(t);
524  r = cuddZddGetNode(dd,index,t,e);
525  if (r == NULL) {
528  return(NULL);
529  }
530  cuddDeref(t);
531  cuddDeref(e);
532  }
533 
534  cuddCacheInsert(dd,DD_ZDD_ITE_TAG,f,g,h,r);
535 
536  return(r);
537 
538 } /* end of cuddZddIte */
539 
540 
541 /**Function********************************************************************
542 
543  Synopsis [Performs the recursive step of Cudd_zddUnion.]
544 
545  Description []
546 
547  SideEffects [None]
548 
549  SeeAlso []
550 
551 ******************************************************************************/
552 DdNode *
554  DdManager * zdd,
555  DdNode * P,
556  DdNode * Q)
557 {
558  int p_top, q_top;
559  DdNode *empty = DD_ZERO(zdd), *t, *e, *res;
560  DdManager *table = zdd;
561 
562  statLine(zdd);
563  if (P == empty)
564  return(Q);
565  if (Q == empty)
566  return(P);
567  if (P == Q)
568  return(P);
569 
570  /* Check cache */
571  res = cuddCacheLookup2Zdd(table, cuddZddUnion, P, Q);
572  if (res != NULL)
573  return(res);
574 
575  if (cuddIsConstant(P))
576  p_top = P->index;
577  else
578  p_top = zdd->permZ[P->index];
579  if (cuddIsConstant(Q))
580  q_top = Q->index;
581  else
582  q_top = zdd->permZ[Q->index];
583  if (p_top < q_top) {
584  e = cuddZddUnion(zdd, cuddE(P), Q);
585  if (e == NULL) return (NULL);
586  cuddRef(e);
587  res = cuddZddGetNode(zdd, P->index, cuddT(P), e);
588  if (res == NULL) {
589  Cudd_RecursiveDerefZdd(table, e);
590  return(NULL);
591  }
592  cuddDeref(e);
593  } else if (p_top > q_top) {
594  e = cuddZddUnion(zdd, P, cuddE(Q));
595  if (e == NULL) return(NULL);
596  cuddRef(e);
597  res = cuddZddGetNode(zdd, Q->index, cuddT(Q), e);
598  if (res == NULL) {
599  Cudd_RecursiveDerefZdd(table, e);
600  return(NULL);
601  }
602  cuddDeref(e);
603  } else {
604  t = cuddZddUnion(zdd, cuddT(P), cuddT(Q));
605  if (t == NULL) return(NULL);
606  cuddRef(t);
607  e = cuddZddUnion(zdd, cuddE(P), cuddE(Q));
608  if (e == NULL) {
609  Cudd_RecursiveDerefZdd(table, t);
610  return(NULL);
611  }
612  cuddRef(e);
613  res = cuddZddGetNode(zdd, P->index, t, e);
614  if (res == NULL) {
615  Cudd_RecursiveDerefZdd(table, t);
616  Cudd_RecursiveDerefZdd(table, e);
617  return(NULL);
618  }
619  cuddDeref(t);
620  cuddDeref(e);
621  }
622 
623  cuddCacheInsert2(table, cuddZddUnion, P, Q, res);
624 
625  return(res);
626 
627 } /* end of cuddZddUnion */
628 
629 
630 /**Function********************************************************************
631 
632  Synopsis [Performs the recursive step of Cudd_zddIntersect.]
633 
634  Description []
635 
636  SideEffects [None]
637 
638  SeeAlso []
639 
640 ******************************************************************************/
641 DdNode *
643  DdManager * zdd,
644  DdNode * P,
645  DdNode * Q)
646 {
647  int p_top, q_top;
648  DdNode *empty = DD_ZERO(zdd), *t, *e, *res;
649  DdManager *table = zdd;
650 
651  statLine(zdd);
652  if (P == empty)
653  return(empty);
654  if (Q == empty)
655  return(empty);
656  if (P == Q)
657  return(P);
658 
659  /* Check cache. */
660  res = cuddCacheLookup2Zdd(table, cuddZddIntersect, P, Q);
661  if (res != NULL)
662  return(res);
663 
664  if (cuddIsConstant(P))
665  p_top = P->index;
666  else
667  p_top = zdd->permZ[P->index];
668  if (cuddIsConstant(Q))
669  q_top = Q->index;
670  else
671  q_top = zdd->permZ[Q->index];
672  if (p_top < q_top) {
673  res = cuddZddIntersect(zdd, cuddE(P), Q);
674  if (res == NULL) return(NULL);
675  } else if (p_top > q_top) {
676  res = cuddZddIntersect(zdd, P, cuddE(Q));
677  if (res == NULL) return(NULL);
678  } else {
679  t = cuddZddIntersect(zdd, cuddT(P), cuddT(Q));
680  if (t == NULL) return(NULL);
681  cuddRef(t);
682  e = cuddZddIntersect(zdd, cuddE(P), cuddE(Q));
683  if (e == NULL) {
684  Cudd_RecursiveDerefZdd(table, t);
685  return(NULL);
686  }
687  cuddRef(e);
688  res = cuddZddGetNode(zdd, P->index, t, e);
689  if (res == NULL) {
690  Cudd_RecursiveDerefZdd(table, t);
691  Cudd_RecursiveDerefZdd(table, e);
692  return(NULL);
693  }
694  cuddDeref(t);
695  cuddDeref(e);
696  }
697 
698  cuddCacheInsert2(table, cuddZddIntersect, P, Q, res);
699 
700  return(res);
701 
702 } /* end of cuddZddIntersect */
703 
704 
705 /**Function********************************************************************
706 
707  Synopsis [Performs the recursive step of Cudd_zddDiff.]
708 
709  Description []
710 
711  SideEffects [None]
712 
713  SeeAlso []
714 
715 ******************************************************************************/
716 DdNode *
718  DdManager * zdd,
719  DdNode * P,
720  DdNode * Q)
721 {
722  int p_top, q_top;
723  DdNode *empty = DD_ZERO(zdd), *t, *e, *res;
724  DdManager *table = zdd;
725 
726  statLine(zdd);
727  if (P == empty)
728  return(empty);
729  if (Q == empty)
730  return(P);
731  if (P == Q)
732  return(empty);
733 
734  /* Check cache. The cache is shared by Cudd_zddDiffConst(). */
735  res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q);
736  if (res != NULL && res != DD_NON_CONSTANT)
737  return(res);
738 
739  if (cuddIsConstant(P))
740  p_top = P->index;
741  else
742  p_top = zdd->permZ[P->index];
743  if (cuddIsConstant(Q))
744  q_top = Q->index;
745  else
746  q_top = zdd->permZ[Q->index];
747  if (p_top < q_top) {
748  e = cuddZddDiff(zdd, cuddE(P), Q);
749  if (e == NULL) return(NULL);
750  cuddRef(e);
751  res = cuddZddGetNode(zdd, P->index, cuddT(P), e);
752  if (res == NULL) {
753  Cudd_RecursiveDerefZdd(table, e);
754  return(NULL);
755  }
756  cuddDeref(e);
757  } else if (p_top > q_top) {
758  res = cuddZddDiff(zdd, P, cuddE(Q));
759  if (res == NULL) return(NULL);
760  } else {
761  t = cuddZddDiff(zdd, cuddT(P), cuddT(Q));
762  if (t == NULL) return(NULL);
763  cuddRef(t);
764  e = cuddZddDiff(zdd, cuddE(P), cuddE(Q));
765  if (e == NULL) {
766  Cudd_RecursiveDerefZdd(table, t);
767  return(NULL);
768  }
769  cuddRef(e);
770  res = cuddZddGetNode(zdd, P->index, t, e);
771  if (res == NULL) {
772  Cudd_RecursiveDerefZdd(table, t);
773  Cudd_RecursiveDerefZdd(table, e);
774  return(NULL);
775  }
776  cuddDeref(t);
777  cuddDeref(e);
778  }
779 
780  cuddCacheInsert2(table, cuddZddDiff, P, Q, res);
781 
782  return(res);
783 
784 } /* end of cuddZddDiff */
785 
786 
787 /**Function********************************************************************
788 
789  Synopsis [Performs the recursive step of Cudd_zddChange.]
790 
791  Description []
792 
793  SideEffects [None]
794 
795  SeeAlso []
796 
797 ******************************************************************************/
798 DdNode *
800  DdManager * zdd,
801  DdNode * P,
802  DdNode * zvar)
803 {
804  int top_var, level;
805  DdNode *res, *t, *e;
806  DdNode *base = DD_ONE(zdd);
807  DdNode *empty = DD_ZERO(zdd);
808 
809  statLine(zdd);
810  if (P == empty)
811  return(empty);
812  if (P == base)
813  return(zvar);
814 
815  /* Check cache. */
816  res = cuddCacheLookup2Zdd(zdd, cuddZddChangeAux, P, zvar);
817  if (res != NULL)
818  return(res);
819 
820  top_var = zdd->permZ[P->index];
821  level = zdd->permZ[zvar->index];
822 
823  if (top_var > level) {
824  res = cuddZddGetNode(zdd, zvar->index, P, DD_ZERO(zdd));
825  if (res == NULL) return(NULL);
826  } else if (top_var == level) {
827  res = cuddZddGetNode(zdd, zvar->index, cuddE(P), cuddT(P));
828  if (res == NULL) return(NULL);
829  } else {
830  t = cuddZddChangeAux(zdd, cuddT(P), zvar);
831  if (t == NULL) return(NULL);
832  cuddRef(t);
833  e = cuddZddChangeAux(zdd, cuddE(P), zvar);
834  if (e == NULL) {
835  Cudd_RecursiveDerefZdd(zdd, t);
836  return(NULL);
837  }
838  cuddRef(e);
839  res = cuddZddGetNode(zdd, P->index, t, e);
840  if (res == NULL) {
841  Cudd_RecursiveDerefZdd(zdd, t);
842  Cudd_RecursiveDerefZdd(zdd, e);
843  return(NULL);
844  }
845  cuddDeref(t);
846  cuddDeref(e);
847  }
848 
849  cuddCacheInsert2(zdd, cuddZddChangeAux, P, zvar, res);
850 
851  return(res);
852 
853 } /* end of cuddZddChangeAux */
854 
855 
856 /**Function********************************************************************
857 
858  Synopsis [Computes the positive cofactor of a ZDD w.r.t. a variable.]
859 
860  Description [Computes the positive cofactor of a ZDD w.r.t. a
861  variable. In terms of combinations, the result is the set of all
862  combinations in which the variable is asserted. Returns a pointer to
863  the result if successful; NULL otherwise. cuddZddSubset1 performs
864  the same function as Cudd_zddSubset1, but does not restart if
865  reordering has taken place. Therefore it can be called from within a
866  recursive procedure.]
867 
868  SideEffects [None]
869 
870  SeeAlso [cuddZddSubset0 Cudd_zddSubset1]
871 
872 ******************************************************************************/
873 DdNode *
875  DdManager * dd,
876  DdNode * P,
877  int var)
878 {
879  DdNode *zvar, *r;
880  DdNode *base, *empty;
881 
882  base = DD_ONE(dd);
883  empty = DD_ZERO(dd);
884 
885  zvar = cuddUniqueInterZdd(dd, var, base, empty);
886  if (zvar == NULL) {
887  return(NULL);
888  } else {
889  cuddRef(zvar);
890  r = zdd_subset1_aux(dd, P, zvar);
891  if (r == NULL) {
892  Cudd_RecursiveDerefZdd(dd, zvar);
893  return(NULL);
894  }
895  cuddRef(r);
896  Cudd_RecursiveDerefZdd(dd, zvar);
897  }
898 
899  cuddDeref(r);
900  return(r);
901 
902 } /* end of cuddZddSubset1 */
903 
904 
905 /**Function********************************************************************
906 
907  Synopsis [Computes the negative cofactor of a ZDD w.r.t. a variable.]
908 
909  Description [Computes the negative cofactor of a ZDD w.r.t. a
910  variable. In terms of combinations, the result is the set of all
911  combinations in which the variable is negated. Returns a pointer to
912  the result if successful; NULL otherwise. cuddZddSubset0 performs
913  the same function as Cudd_zddSubset0, but does not restart if
914  reordering has taken place. Therefore it can be called from within a
915  recursive procedure.]
916 
917  SideEffects [None]
918 
919  SeeAlso [cuddZddSubset1 Cudd_zddSubset0]
920 
921 ******************************************************************************/
922 DdNode *
924  DdManager * dd,
925  DdNode * P,
926  int var)
927 {
928  DdNode *zvar, *r;
929  DdNode *base, *empty;
930 
931  base = DD_ONE(dd);
932  empty = DD_ZERO(dd);
933 
934  zvar = cuddUniqueInterZdd(dd, var, base, empty);
935  if (zvar == NULL) {
936  return(NULL);
937  } else {
938  cuddRef(zvar);
939  r = zdd_subset0_aux(dd, P, zvar);
940  if (r == NULL) {
941  Cudd_RecursiveDerefZdd(dd, zvar);
942  return(NULL);
943  }
944  cuddRef(r);
945  Cudd_RecursiveDerefZdd(dd, zvar);
946  }
947 
948  cuddDeref(r);
949  return(r);
950 
951 } /* end of cuddZddSubset0 */
952 
953 
954 /**Function********************************************************************
955 
956  Synopsis [Substitutes a variable with its complement in a ZDD.]
957 
958  Description [Substitutes a variable with its complement in a ZDD.
959  returns a pointer to the result if successful; NULL
960  otherwise. cuddZddChange performs the same function as
961  Cudd_zddChange, but does not restart if reordering has taken
962  place. Therefore it can be called from within a recursive
963  procedure.]
964 
965  SideEffects [None]
966 
967  SeeAlso [Cudd_zddChange]
968 
969 ******************************************************************************/
970 DdNode *
972  DdManager * dd,
973  DdNode * P,
974  int var)
975 {
976  DdNode *zvar, *res;
977 
978  zvar = cuddUniqueInterZdd(dd, var, DD_ONE(dd), DD_ZERO(dd));
979  if (zvar == NULL) return(NULL);
980  cuddRef(zvar);
981 
982  res = cuddZddChangeAux(dd, P, zvar);
983  if (res == NULL) {
984  Cudd_RecursiveDerefZdd(dd,zvar);
985  return(NULL);
986  }
987  cuddRef(res);
988  Cudd_RecursiveDerefZdd(dd,zvar);
989  cuddDeref(res);
990  return(res);
991 
992 } /* end of cuddZddChange */
993 
994 
995 /*---------------------------------------------------------------------------*/
996 /* Definition of static functions */
997 /*---------------------------------------------------------------------------*/
998 
999 
1000 /**Function********************************************************************
1001 
1002  Synopsis [Performs the recursive step of Cudd_zddSubset1.]
1003 
1004  Description []
1005 
1006  SideEffects [None]
1007 
1008  SeeAlso []
1009 
1010 ******************************************************************************/
1011 static DdNode *
1013  DdManager * zdd,
1014  DdNode * P,
1015  DdNode * zvar)
1016 {
1017  int top_var, level;
1018  DdNode *res, *t, *e;
1019  DdNode *empty;
1020 
1021  statLine(zdd);
1022  empty = DD_ZERO(zdd);
1023 
1024  /* Check cache. */
1025  res = cuddCacheLookup2Zdd(zdd, zdd_subset1_aux, P, zvar);
1026  if (res != NULL)
1027  return(res);
1028 
1029  if (cuddIsConstant(P)) {
1030  res = empty;
1031  cuddCacheInsert2(zdd, zdd_subset1_aux, P, zvar, res);
1032  return(res);
1033  }
1034 
1035  top_var = zdd->permZ[P->index];
1036  level = zdd->permZ[zvar->index];
1037 
1038  if (top_var > level) {
1039  res = empty;
1040  } else if (top_var == level) {
1041  res = cuddT(P);
1042  } else {
1043  t = zdd_subset1_aux(zdd, cuddT(P), zvar);
1044  if (t == NULL) return(NULL);
1045  cuddRef(t);
1046  e = zdd_subset1_aux(zdd, cuddE(P), zvar);
1047  if (e == NULL) {
1048  Cudd_RecursiveDerefZdd(zdd, t);
1049  return(NULL);
1050  }
1051  cuddRef(e);
1052  res = cuddZddGetNode(zdd, P->index, t, e);
1053  if (res == NULL) {
1054  Cudd_RecursiveDerefZdd(zdd, t);
1055  Cudd_RecursiveDerefZdd(zdd, e);
1056  return(NULL);
1057  }
1058  cuddDeref(t);
1059  cuddDeref(e);
1060  }
1061 
1062  cuddCacheInsert2(zdd, zdd_subset1_aux, P, zvar, res);
1063 
1064  return(res);
1065 
1066 } /* end of zdd_subset1_aux */
1067 
1068 
1069 /**Function********************************************************************
1070 
1071  Synopsis [Performs the recursive step of Cudd_zddSubset0.]
1072 
1073  Description []
1074 
1075  SideEffects [None]
1076 
1077  SeeAlso []
1078 
1079 ******************************************************************************/
1080 static DdNode *
1082  DdManager * zdd,
1083  DdNode * P,
1084  DdNode * zvar)
1085 {
1086  int top_var, level;
1087  DdNode *res, *t, *e;
1088 
1089  statLine(zdd);
1090 
1091  /* Check cache. */
1092  res = cuddCacheLookup2Zdd(zdd, zdd_subset0_aux, P, zvar);
1093  if (res != NULL)
1094  return(res);
1095 
1096  if (cuddIsConstant(P)) {
1097  res = P;
1098  cuddCacheInsert2(zdd, zdd_subset0_aux, P, zvar, res);
1099  return(res);
1100  }
1101 
1102  top_var = zdd->permZ[P->index];
1103  level = zdd->permZ[zvar->index];
1104 
1105  if (top_var > level) {
1106  res = P;
1107  }
1108  else if (top_var == level) {
1109  res = cuddE(P);
1110  }
1111  else {
1112  t = zdd_subset0_aux(zdd, cuddT(P), zvar);
1113  if (t == NULL) return(NULL);
1114  cuddRef(t);
1115  e = zdd_subset0_aux(zdd, cuddE(P), zvar);
1116  if (e == NULL) {
1117  Cudd_RecursiveDerefZdd(zdd, t);
1118  return(NULL);
1119  }
1120  cuddRef(e);
1121  res = cuddZddGetNode(zdd, P->index, t, e);
1122  if (res == NULL) {
1123  Cudd_RecursiveDerefZdd(zdd, t);
1124  Cudd_RecursiveDerefZdd(zdd, e);
1125  return(NULL);
1126  }
1127  cuddDeref(t);
1128  cuddDeref(e);
1129  }
1130 
1131  cuddCacheInsert2(zdd, zdd_subset0_aux, P, zvar, res);
1132 
1133  return(res);
1134 
1135 } /* end of zdd_subset0_aux */
1136 
1137 
1138 /**Function********************************************************************
1139 
1140  Synopsis [Replaces variables with constants if possible (part of
1141  canonical form).]
1142 
1143  Description []
1144 
1145  SideEffects [None]
1146 
1147  SeeAlso []
1148 
1149 ******************************************************************************/
1150 static void
1152  DdNode * f,
1153  DdNode ** gp,
1154  DdNode ** hp,
1155  DdNode * base,
1156  DdNode * empty)
1157 {
1158  DdNode *g = *gp;
1159  DdNode *h = *hp;
1160 
1161  if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
1162  *gp = base;
1163  }
1164 
1165  if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
1166  *hp = empty;
1167  }
1168 
1169 } /* end of zddVarToConst */
1170 
1171 
1173 
1174 
DdNode * cuddZddIte(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddZddSetop.c:427
DdNode * cuddCacheLookupZdd(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:435
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:610
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
DdNode * Cudd_zddIte(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddZddSetop.c:148
#define cuddDeref(n)
Definition: cuddInt.h:604
#define cuddIZ(dd, index)
Definition: cuddInt.h:704
DdNode * Cudd_zddIntersect(DdManager *dd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:207
Definition: cudd.h:278
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1041
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
bool tautology()
static byte P[256]
Definition: kitPerm.c:76
DdNode * cuddZddUnion(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:553
DdNode * Cudd_zddSubset0(DdManager *dd, DdNode *P, int var)
Definition: cuddZddSetop.c:362
int var(Lit p)
Definition: SolverTypes.h:62
DdNode * cuddZddSubset0(DdManager *dd, DdNode *P, int var)
Definition: cuddZddSetop.c:923
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:222
DdNode * cuddZddSubset1(DdManager *dd, DdNode *P, int var)
Definition: cuddZddSetop.c:874
int * permZ
Definition: cuddInt.h:387
#define statLine(dd)
Definition: cuddInt.h:1037
static void zddVarToConst(DdNode *f, DdNode **gp, DdNode **hp, DdNode *base, DdNode *empty)
static DdNode * zdd_subset1_aux(DdManager *zdd, DdNode *P, DdNode *zvar)
int reordered
Definition: cuddInt.h:409
DdNode * cuddZddChange(DdManager *dd, DdNode *P, int var)
Definition: cuddZddSetop.c:971
DdNode * cuddZddIntersect(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:642
DdNode * Cudd_zddChange(DdManager *dd, DdNode *P, int var)
Definition: cuddZddSetop.c:392
DdNode * Cudd_zddUnion(DdManager *dd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:178
DdNode * Cudd_zddSubset1(DdManager *dd, DdNode *P, int var)
Definition: cuddZddSetop.c:330
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
#define cuddIsConstant(node)
Definition: cuddInt.h:620
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1343
#define ddMin(x, y)
Definition: cuddInt.h:818
#define cuddT(node)
Definition: cuddInt.h:636
#define DD_ZDD_ITE_TAG
Definition: cuddInt.h:183
DdNode * Cudd_zddDiffConst(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:266
DdNode * Cudd_zddDiff(DdManager *dd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:236
static DdNode * zdd_subset0_aux(DdManager *zdd, DdNode *P, DdNode *zvar)
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
DdNode * cuddZddChangeAux(DdManager *zdd, DdNode *P, DdNode *zvar)
Definition: cuddZddSetop.c:799
DdNode * cuddZddDiff(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:717
DdHalfWord index
Definition: cudd.h:279
static ABC_NAMESPACE_IMPL_START char rcsid[] DD_UNUSED
Definition: cuddZddSetop.c:103
#define CUDD_MAXINDEX
Definition: cudd.h:112
#define cuddE(node)
Definition: cuddInt.h:652
static DdNode * empty
Definition: cuddZddLin.c:98
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode ** univ
Definition: cuddInt.h:392
#define DD_NON_CONSTANT
Definition: cuddInt.h:123
#define DD_ZERO(dd)
Definition: cuddInt.h:927