SVF
cuddBddIte.c
Go to the documentation of this file.
1 
78 #include "CUDD/util.h"
79 #include "CUDD/cuddInt.h"
80 
81 
82 /*---------------------------------------------------------------------------*/
83 /* Constant declarations */
84 /*---------------------------------------------------------------------------*/
85 
86 
87 /*---------------------------------------------------------------------------*/
88 /* Stucture declarations */
89 /*---------------------------------------------------------------------------*/
90 
91 
92 /*---------------------------------------------------------------------------*/
93 /* Type declarations */
94 /*---------------------------------------------------------------------------*/
95 
96 
97 /*---------------------------------------------------------------------------*/
98 /* Variable declarations */
99 /*---------------------------------------------------------------------------*/
100 
101 #ifndef lint
102 static char rcsid[] DD_UNUSED = "$Id: cuddBddIte.c,v 1.26 2012/02/05 01:07:18 fabio Exp $";
103 #endif
104 
105 /*---------------------------------------------------------------------------*/
106 /* Macro declarations */
107 /*---------------------------------------------------------------------------*/
108 
109 
112 /*---------------------------------------------------------------------------*/
113 /* Static function prototypes */
114 /*---------------------------------------------------------------------------*/
115 
116 static void bddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one);
117 static int bddVarToCanonical (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp);
118 static int bddVarToCanonicalSimple (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp);
119 
123 /*---------------------------------------------------------------------------*/
124 /* Definition of exported functions */
125 /*---------------------------------------------------------------------------*/
126 
127 
141 DdNode *
143  DdManager * dd,
144  DdNode * f,
145  DdNode * g,
146  DdNode * h)
147 {
148  DdNode *res;
149 
150  do {
151  dd->reordered = 0;
152  res = cuddBddIteRecur(dd,f,g,h);
153  } while (dd->reordered == 1);
154  return(res);
155 
156 } /* end of Cudd_bddIte */
157 
158 
174 DdNode *
176  DdManager * dd,
177  DdNode * f,
178  DdNode * g,
179  DdNode * h,
180  unsigned int limit)
181 {
182  DdNode *res;
183  unsigned int saveLimit = dd->maxLive;
184 
185  dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit;
186  do {
187  dd->reordered = 0;
188  res = cuddBddIteRecur(dd,f,g,h);
189  } while (dd->reordered == 1);
190  dd->maxLive = saveLimit;
191  return(res);
192 
193 } /* end of Cudd_bddIteLimit */
194 
195 
209 DdNode *
211  DdManager * dd,
212  DdNode * f,
213  DdNode * g,
214  DdNode * h)
215 {
216  DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e;
217  DdNode *one = DD_ONE(dd);
218  DdNode *zero = Cudd_Not(one);
219  int comple;
220  unsigned int topf, topg, toph, v;
221 
222  statLine(dd);
223  /* Trivial cases. */
224  if (f == one) /* ITE(1,G,H) => G */
225  return(g);
226 
227  if (f == zero) /* ITE(0,G,H) => H */
228  return(h);
229 
230  /* f now not a constant. */
231  bddVarToConst(f, &g, &h, one); /* possibly convert g or h */
232  /* to constants */
233 
234  if (g == h) /* ITE(F,G,G) => G */
235  return(g);
236 
237  if (Cudd_IsConstant(g) && Cudd_IsConstant(h))
238  return(DD_NON_CONSTANT); /* ITE(F,1,0) or ITE(F,0,1) */
239  /* => DD_NON_CONSTANT */
240 
241  if (g == Cudd_Not(h))
242  return(DD_NON_CONSTANT); /* ITE(F,G,G') => DD_NON_CONSTANT */
243  /* if F != G and F != G' */
244 
245  comple = bddVarToCanonical(dd, &f, &g, &h, &topf, &topg, &toph);
246 
247  /* Cache lookup. */
249  if (r != NULL) {
250  return(Cudd_NotCond(r,comple && r != DD_NON_CONSTANT));
251  }
252 
253  v = ddMin(topg, toph);
254 
255  /* ITE(F,G,H) = (v,G,H) (non constant) if F = (v,1,0), v < top(G,H). */
256  if (topf < v && cuddT(f) == one && cuddE(f) == zero) {
257  return(DD_NON_CONSTANT);
258  }
259 
260  /* Compute cofactors. */
261  if (topf <= v) {
262  v = ddMin(topf, v); /* v = top_var(F,G,H) */
263  Fv = cuddT(f); Fnv = cuddE(f);
264  } else {
265  Fv = Fnv = f;
266  }
267 
268  if (topg == v) {
269  Gv = cuddT(g); Gnv = cuddE(g);
270  } else {
271  Gv = Gnv = g;
272  }
273 
274  if (toph == v) {
275  H = Cudd_Regular(h);
276  Hv = cuddT(H); Hnv = cuddE(H);
277  if (Cudd_IsComplement(h)) {
278  Hv = Cudd_Not(Hv);
279  Hnv = Cudd_Not(Hnv);
280  }
281  } else {
282  Hv = Hnv = h;
283  }
284 
285  /* Recursion. */
286  t = Cudd_bddIteConstant(dd, Fv, Gv, Hv);
287  if (t == DD_NON_CONSTANT || !Cudd_IsConstant(t)) {
289  return(DD_NON_CONSTANT);
290  }
291  e = Cudd_bddIteConstant(dd, Fnv, Gnv, Hnv);
292  if (e == DD_NON_CONSTANT || !Cudd_IsConstant(e) || t != e) {
294  return(DD_NON_CONSTANT);
295  }
296  cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, t);
297  return(Cudd_NotCond(t,comple));
298 
299 } /* end of Cudd_bddIteConstant */
300 
301 
317 DdNode *
319  DdManager * dd /* manager */,
320  DdNode * f /* first operand */,
321  DdNode * g /* second operand */)
322 {
323  DdNode *res;
324 
325  do {
326  dd->reordered = 0;
327  res = cuddBddIntersectRecur(dd,f,g);
328  } while (dd->reordered == 1);
329 
330  return(res);
331 
332 } /* end of Cudd_bddIntersect */
333 
334 
349 DdNode *
351  DdManager * dd,
352  DdNode * f,
353  DdNode * g)
354 {
355  DdNode *res;
356 
357  do {
358  dd->reordered = 0;
359  res = cuddBddAndRecur(dd,f,g);
360  } while (dd->reordered == 1);
361  return(res);
362 
363 } /* end of Cudd_bddAnd */
364 
365 
381 DdNode *
383  DdManager * dd,
384  DdNode * f,
385  DdNode * g,
386  unsigned int limit)
387 {
388  DdNode *res;
389  unsigned int saveLimit = dd->maxLive;
390 
391  dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit;
392  do {
393  dd->reordered = 0;
394  res = cuddBddAndRecur(dd,f,g);
395  } while (dd->reordered == 1);
396  dd->maxLive = saveLimit;
397  return(res);
398 
399 } /* end of Cudd_bddAndLimit */
400 
401 
416 DdNode *
418  DdManager * dd,
419  DdNode * f,
420  DdNode * g)
421 {
422  DdNode *res;
423 
424  do {
425  dd->reordered = 0;
426  res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g));
427  } while (dd->reordered == 1);
428  res = Cudd_NotCond(res,res != NULL);
429  return(res);
430 
431 } /* end of Cudd_bddOr */
432 
433 
449 DdNode *
451  DdManager * dd,
452  DdNode * f,
453  DdNode * g,
454  unsigned int limit)
455 {
456  DdNode *res;
457  unsigned int saveLimit = dd->maxLive;
458 
459  dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit;
460  do {
461  dd->reordered = 0;
462  res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g));
463  } while (dd->reordered == 1);
464  dd->maxLive = saveLimit;
465  res = Cudd_NotCond(res,res != NULL);
466  return(res);
467 
468 } /* end of Cudd_bddOrLimit */
469 
470 
485 DdNode *
487  DdManager * dd,
488  DdNode * f,
489  DdNode * g)
490 {
491  DdNode *res;
492 
493  do {
494  dd->reordered = 0;
495  res = cuddBddAndRecur(dd,f,g);
496  } while (dd->reordered == 1);
497  res = Cudd_NotCond(res,res != NULL);
498  return(res);
499 
500 } /* end of Cudd_bddNand */
501 
502 
517 DdNode *
519  DdManager * dd,
520  DdNode * f,
521  DdNode * g)
522 {
523  DdNode *res;
524 
525  do {
526  dd->reordered = 0;
527  res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g));
528  } while (dd->reordered == 1);
529  return(res);
530 
531 } /* end of Cudd_bddNor */
532 
533 
548 DdNode *
550  DdManager * dd,
551  DdNode * f,
552  DdNode * g)
553 {
554  DdNode *res;
555 
556  do {
557  dd->reordered = 0;
558  res = cuddBddXorRecur(dd,f,g);
559  } while (dd->reordered == 1);
560  return(res);
561 
562 } /* end of Cudd_bddXor */
563 
564 
579 DdNode *
581  DdManager * dd,
582  DdNode * f,
583  DdNode * g)
584 {
585  DdNode *res;
586 
587  do {
588  dd->reordered = 0;
589  res = cuddBddXorRecur(dd,f,Cudd_Not(g));
590  } while (dd->reordered == 1);
591  return(res);
592 
593 } /* end of Cudd_bddXnor */
594 
595 
611 DdNode *
613  DdManager * dd,
614  DdNode * f,
615  DdNode * g,
616  unsigned int limit)
617 {
618  DdNode *res;
619  unsigned int saveLimit = dd->maxLive;
620 
621  dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit;
622  do {
623  dd->reordered = 0;
624  res = cuddBddXorRecur(dd,f,Cudd_Not(g));
625  } while (dd->reordered == 1);
626  dd->maxLive = saveLimit;
627  return(res);
628 
629 } /* end of Cudd_bddXnorLimit */
630 
631 
644 int
646  DdManager * dd,
647  DdNode * f,
648  DdNode * g)
649 {
650  DdNode *one, *zero, *tmp, *F, *fv, *fvn, *gv, *gvn;
651  unsigned int topf, topg, res;
652 
653  statLine(dd);
654  /* Terminal cases and normalization. */
655  if (f == g) return(1);
656 
657  if (Cudd_IsComplement(g)) {
658  /* Special case: if f is regular and g is complemented,
659  ** f(1,...,1) = 1 > 0 = g(1,...,1).
660  */
661  if (!Cudd_IsComplement(f)) return(0);
662  /* Both are complemented: Swap and complement because
663  ** f <= g <=> g' <= f' and we want the second argument to be regular.
664  */
665  tmp = g;
666  g = Cudd_Not(f);
667  f = Cudd_Not(tmp);
668  } else if (Cudd_IsComplement(f) && g < f) {
669  tmp = g;
670  g = Cudd_Not(f);
671  f = Cudd_Not(tmp);
672  }
673 
674  /* Now g is regular and, if f is not regular, f < g. */
675  one = DD_ONE(dd);
676  if (g == one) return(1); /* no need to test against zero */
677  if (f == one) return(0); /* since at this point g != one */
678  if (Cudd_Not(f) == g) return(0); /* because neither is constant */
679  zero = Cudd_Not(one);
680  if (f == zero) return(1);
681 
682  /* Here neither f nor g is constant. */
683 
684  /* Check cache. */
685  tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_bddLeq,f,g);
686  if (tmp != NULL) {
687  return(tmp == one);
688  }
689 
690  /* Compute cofactors. */
691  F = Cudd_Regular(f);
692  topf = dd->perm[F->index];
693  topg = dd->perm[g->index];
694  if (topf <= topg) {
695  fv = cuddT(F); fvn = cuddE(F);
696  if (f != F) {
697  fv = Cudd_Not(fv);
698  fvn = Cudd_Not(fvn);
699  }
700  } else {
701  fv = fvn = f;
702  }
703  if (topg <= topf) {
704  gv = cuddT(g); gvn = cuddE(g);
705  } else {
706  gv = gvn = g;
707  }
708 
709  /* Recursive calls. Since we want to maximize the probability of
710  ** the special case f(1,...,1) > g(1,...,1), we consider the negative
711  ** cofactors first. Indeed, the complementation parity of the positive
712  ** cofactors is the same as the one of the parent functions.
713  */
714  res = Cudd_bddLeq(dd,fvn,gvn) && Cudd_bddLeq(dd,fv,gv);
715 
716  /* Store result in cache and return. */
717  cuddCacheInsert2(dd,(DD_CTFP)Cudd_bddLeq,f,g,(res ? one : zero));
718  return(res);
719 
720 } /* end of Cudd_bddLeq */
721 
722 
723 /*---------------------------------------------------------------------------*/
724 /* Definition of internal functions */
725 /*---------------------------------------------------------------------------*/
726 
727 
741 DdNode *
743  DdManager * dd,
744  DdNode * f,
745  DdNode * g,
746  DdNode * h)
747 {
748  DdNode *one, *zero, *res;
749  DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e;
750  unsigned int topf, topg, toph, v;
751  int index;
752  int comple;
753 
754  statLine(dd);
755  /* Terminal cases. */
756 
757  /* One variable cases. */
758  if (f == (one = DD_ONE(dd))) /* ITE(1,G,H) = G */
759  return(g);
760 
761  if (f == (zero = Cudd_Not(one))) /* ITE(0,G,H) = H */
762  return(h);
763 
764  /* From now on, f is known not to be a constant. */
765  if (g == one || f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
766  if (h == zero) { /* ITE(F,1,0) = F */
767  return(f);
768  } else {
769  res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(h));
770  return(Cudd_NotCond(res,res != NULL));
771  }
772  } else if (g == zero || f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */
773  if (h == one) { /* ITE(F,0,1) = !F */
774  return(Cudd_Not(f));
775  } else {
776  res = cuddBddAndRecur(dd,Cudd_Not(f),h);
777  return(res);
778  }
779  }
780  if (h == zero || f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
781  res = cuddBddAndRecur(dd,f,g);
782  return(res);
783  } else if (h == one || f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */
784  res = cuddBddAndRecur(dd,f,Cudd_Not(g));
785  return(Cudd_NotCond(res,res != NULL));
786  }
787 
788  /* Check remaining one variable case. */
789  if (g == h) { /* ITE(F,G,G) = G */
790  return(g);
791  } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = F <-> G */
792  res = cuddBddXorRecur(dd,f,h);
793  return(res);
794  }
795 
796  /* From here, there are no constants. */
797  comple = bddVarToCanonicalSimple(dd, &f, &g, &h, &topf, &topg, &toph);
798 
799  /* f & g are now regular pointers */
800 
801  v = ddMin(topg, toph);
802 
803  /* A shortcut: ITE(F,G,H) = (v,G,H) if F = (v,1,0), v < top(G,H). */
804  if (topf < v && cuddT(f) == one && cuddE(f) == zero) {
805  r = cuddUniqueInter(dd, (int) f->index, g, h);
806  return(Cudd_NotCond(r,comple && r != NULL));
807  }
808 
809  /* Check cache. */
810  r = cuddCacheLookup(dd, DD_BDD_ITE_TAG, f, g, h);
811  if (r != NULL) {
812  return(Cudd_NotCond(r,comple));
813  }
814 
815  /* Compute cofactors. */
816  if (topf <= v) {
817  v = ddMin(topf, v); /* v = top_var(F,G,H) */
818  index = f->index;
819  Fv = cuddT(f); Fnv = cuddE(f);
820  } else {
821  Fv = Fnv = f;
822  }
823  if (topg == v) {
824  index = g->index;
825  Gv = cuddT(g); Gnv = cuddE(g);
826  } else {
827  Gv = Gnv = g;
828  }
829  if (toph == v) {
830  H = Cudd_Regular(h);
831  index = H->index;
832  Hv = cuddT(H); Hnv = cuddE(H);
833  if (Cudd_IsComplement(h)) {
834  Hv = Cudd_Not(Hv);
835  Hnv = Cudd_Not(Hnv);
836  }
837  } else {
838  Hv = Hnv = h;
839  }
840 
841  /* Recursive step. */
842  t = cuddBddIteRecur(dd,Fv,Gv,Hv);
843  if (t == NULL) return(NULL);
844  cuddRef(t);
845 
846  e = cuddBddIteRecur(dd,Fnv,Gnv,Hnv);
847  if (e == NULL) {
848  Cudd_IterDerefBdd(dd,t);
849  return(NULL);
850  }
851  cuddRef(e);
852 
853  r = (t == e) ? t : cuddUniqueInter(dd,index,t,e);
854  if (r == NULL) {
855  Cudd_IterDerefBdd(dd,t);
856  Cudd_IterDerefBdd(dd,e);
857  return(NULL);
858  }
859  cuddDeref(t);
860  cuddDeref(e);
861 
862  cuddCacheInsert(dd, DD_BDD_ITE_TAG, f, g, h, r);
863  return(Cudd_NotCond(r,comple));
864 
865 } /* end of cuddBddIteRecur */
866 
867 
879 DdNode *
881  DdManager * dd,
882  DdNode * f,
883  DdNode * g)
884 {
885  DdNode *res;
886  DdNode *F, *G, *t, *e;
887  DdNode *fv, *fnv, *gv, *gnv;
888  DdNode *one, *zero;
889  unsigned int index, topf, topg;
890 
891  statLine(dd);
892  one = DD_ONE(dd);
893  zero = Cudd_Not(one);
894 
895  /* Terminal cases. */
896  if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
897  if (f == g || g == one) return(f);
898  if (f == one) return(g);
899 
900  /* At this point f and g are not constant. */
901  if (f > g) { DdNode *tmp = f; f = g; g = tmp; }
902  res = cuddCacheLookup2(dd,Cudd_bddIntersect,f,g);
903  if (res != NULL) return(res);
904 
905  /* Find splitting variable. Here we can skip the use of cuddI,
906  ** because the operands are known to be non-constant.
907  */
908  F = Cudd_Regular(f);
909  topf = dd->perm[F->index];
910  G = Cudd_Regular(g);
911  topg = dd->perm[G->index];
912 
913  /* Compute cofactors. */
914  if (topf <= topg) {
915  index = F->index;
916  fv = cuddT(F);
917  fnv = cuddE(F);
918  if (Cudd_IsComplement(f)) {
919  fv = Cudd_Not(fv);
920  fnv = Cudd_Not(fnv);
921  }
922  } else {
923  index = G->index;
924  fv = fnv = f;
925  }
926 
927  if (topg <= topf) {
928  gv = cuddT(G);
929  gnv = cuddE(G);
930  if (Cudd_IsComplement(g)) {
931  gv = Cudd_Not(gv);
932  gnv = Cudd_Not(gnv);
933  }
934  } else {
935  gv = gnv = g;
936  }
937 
938  /* Compute partial results. */
939  t = cuddBddIntersectRecur(dd,fv,gv);
940  if (t == NULL) return(NULL);
941  cuddRef(t);
942  if (t != zero) {
943  e = zero;
944  } else {
945  e = cuddBddIntersectRecur(dd,fnv,gnv);
946  if (e == NULL) {
947  Cudd_IterDerefBdd(dd, t);
948  return(NULL);
949  }
950  }
951  cuddRef(e);
952 
953  if (t == e) { /* both equal zero */
954  res = t;
955  } else if (Cudd_IsComplement(t)) {
956  res = cuddUniqueInter(dd,(int)index,Cudd_Not(t),Cudd_Not(e));
957  if (res == NULL) {
958  Cudd_IterDerefBdd(dd, t);
959  Cudd_IterDerefBdd(dd, e);
960  return(NULL);
961  }
962  res = Cudd_Not(res);
963  } else {
964  res = cuddUniqueInter(dd,(int)index,t,e);
965  if (res == NULL) {
966  Cudd_IterDerefBdd(dd, t);
967  Cudd_IterDerefBdd(dd, e);
968  return(NULL);
969  }
970  }
971  cuddDeref(e);
972  cuddDeref(t);
973 
975 
976  return(res);
977 
978 } /* end of cuddBddIntersectRecur */
979 
980 
994 DdNode *
996  DdManager * manager,
997  DdNode * f,
998  DdNode * g)
999 {
1000  DdNode *F, *fv, *fnv, *G, *gv, *gnv;
1001  DdNode *one, *r, *t, *e;
1002  unsigned int topf, topg, index;
1003 
1004  statLine(manager);
1005  one = DD_ONE(manager);
1006 
1007  /* Terminal cases. */
1008  F = Cudd_Regular(f);
1009  G = Cudd_Regular(g);
1010  if (F == G) {
1011  if (f == g) return(f);
1012  else return(Cudd_Not(one));
1013  }
1014  if (F == one) {
1015  if (f == one) return(g);
1016  else return(f);
1017  }
1018  if (G == one) {
1019  if (g == one) return(f);
1020  else return(g);
1021  }
1022 
1023  /* At this point f and g are not constant. */
1024  if (f > g) { /* Try to increase cache efficiency. */
1025  DdNode *tmp = f;
1026  f = g;
1027  g = tmp;
1028  F = Cudd_Regular(f);
1029  G = Cudd_Regular(g);
1030  }
1031 
1032  /* Check cache. */
1033  if (F->ref != 1 || G->ref != 1) {
1034  r = cuddCacheLookup2(manager, Cudd_bddAnd, f, g);
1035  if (r != NULL) return(r);
1036  }
1037 
1038  /* Here we can skip the use of cuddI, because the operands are known
1039  ** to be non-constant.
1040  */
1041  topf = manager->perm[F->index];
1042  topg = manager->perm[G->index];
1043 
1044  /* Compute cofactors. */
1045  if (topf <= topg) {
1046  index = F->index;
1047  fv = cuddT(F);
1048  fnv = cuddE(F);
1049  if (Cudd_IsComplement(f)) {
1050  fv = Cudd_Not(fv);
1051  fnv = Cudd_Not(fnv);
1052  }
1053  } else {
1054  index = G->index;
1055  fv = fnv = f;
1056  }
1057 
1058  if (topg <= topf) {
1059  gv = cuddT(G);
1060  gnv = cuddE(G);
1061  if (Cudd_IsComplement(g)) {
1062  gv = Cudd_Not(gv);
1063  gnv = Cudd_Not(gnv);
1064  }
1065  } else {
1066  gv = gnv = g;
1067  }
1068 
1069  t = cuddBddAndRecur(manager, fv, gv);
1070  if (t == NULL) return(NULL);
1071  cuddRef(t);
1072 
1073  e = cuddBddAndRecur(manager, fnv, gnv);
1074  if (e == NULL) {
1075  Cudd_IterDerefBdd(manager, t);
1076  return(NULL);
1077  }
1078  cuddRef(e);
1079 
1080  if (t == e) {
1081  r = t;
1082  } else {
1083  if (Cudd_IsComplement(t)) {
1084  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
1085  if (r == NULL) {
1086  Cudd_IterDerefBdd(manager, t);
1087  Cudd_IterDerefBdd(manager, e);
1088  return(NULL);
1089  }
1090  r = Cudd_Not(r);
1091  } else {
1092  r = cuddUniqueInter(manager,(int)index,t,e);
1093  if (r == NULL) {
1094  Cudd_IterDerefBdd(manager, t);
1095  Cudd_IterDerefBdd(manager, e);
1096  return(NULL);
1097  }
1098  }
1099  }
1100  cuddDeref(e);
1101  cuddDeref(t);
1102  if (F->ref != 1 || G->ref != 1)
1103  cuddCacheInsert2(manager, Cudd_bddAnd, f, g, r);
1104  return(r);
1105 
1106 } /* end of cuddBddAndRecur */
1107 
1108 
1122 DdNode *
1124  DdManager * manager,
1125  DdNode * f,
1126  DdNode * g)
1127 {
1128  DdNode *fv, *fnv, *G, *gv, *gnv;
1129  DdNode *one, *zero, *r, *t, *e;
1130  unsigned int topf, topg, index;
1131 
1132  statLine(manager);
1133  one = DD_ONE(manager);
1134  zero = Cudd_Not(one);
1135 
1136  /* Terminal cases. */
1137  if (f == g) return(zero);
1138  if (f == Cudd_Not(g)) return(one);
1139  if (f > g) { /* Try to increase cache efficiency and simplify tests. */
1140  DdNode *tmp = f;
1141  f = g;
1142  g = tmp;
1143  }
1144  if (g == zero) return(f);
1145  if (g == one) return(Cudd_Not(f));
1146  if (Cudd_IsComplement(f)) {
1147  f = Cudd_Not(f);
1148  g = Cudd_Not(g);
1149  }
1150  /* Now the first argument is regular. */
1151  if (f == one) return(Cudd_Not(g));
1152 
1153  /* At this point f and g are not constant. */
1154 
1155  /* Check cache. */
1156  r = cuddCacheLookup2(manager, Cudd_bddXor, f, g);
1157  if (r != NULL) return(r);
1158 
1159  /* Here we can skip the use of cuddI, because the operands are known
1160  ** to be non-constant.
1161  */
1162  topf = manager->perm[f->index];
1163  G = Cudd_Regular(g);
1164  topg = manager->perm[G->index];
1165 
1166  /* Compute cofactors. */
1167  if (topf <= topg) {
1168  index = f->index;
1169  fv = cuddT(f);
1170  fnv = cuddE(f);
1171  } else {
1172  index = G->index;
1173  fv = fnv = f;
1174  }
1175 
1176  if (topg <= topf) {
1177  gv = cuddT(G);
1178  gnv = cuddE(G);
1179  if (Cudd_IsComplement(g)) {
1180  gv = Cudd_Not(gv);
1181  gnv = Cudd_Not(gnv);
1182  }
1183  } else {
1184  gv = gnv = g;
1185  }
1186 
1187  t = cuddBddXorRecur(manager, fv, gv);
1188  if (t == NULL) return(NULL);
1189  cuddRef(t);
1190 
1191  e = cuddBddXorRecur(manager, fnv, gnv);
1192  if (e == NULL) {
1193  Cudd_IterDerefBdd(manager, t);
1194  return(NULL);
1195  }
1196  cuddRef(e);
1197 
1198  if (t == e) {
1199  r = t;
1200  } else {
1201  if (Cudd_IsComplement(t)) {
1202  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
1203  if (r == NULL) {
1204  Cudd_IterDerefBdd(manager, t);
1205  Cudd_IterDerefBdd(manager, e);
1206  return(NULL);
1207  }
1208  r = Cudd_Not(r);
1209  } else {
1210  r = cuddUniqueInter(manager,(int)index,t,e);
1211  if (r == NULL) {
1212  Cudd_IterDerefBdd(manager, t);
1213  Cudd_IterDerefBdd(manager, e);
1214  return(NULL);
1215  }
1216  }
1217  }
1218  cuddDeref(e);
1219  cuddDeref(t);
1220  cuddCacheInsert2(manager, Cudd_bddXor, f, g, r);
1221  return(r);
1222 
1223 } /* end of cuddBddXorRecur */
1224 
1225 
1226 /*---------------------------------------------------------------------------*/
1227 /* Definition of static functions */
1228 /*---------------------------------------------------------------------------*/
1229 
1230 
1243 static void
1245  DdNode * f,
1246  DdNode ** gp,
1247  DdNode ** hp,
1248  DdNode * one)
1249 {
1250  DdNode *g = *gp;
1251  DdNode *h = *hp;
1252 
1253  if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
1254  *gp = one;
1255  } else if (f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */
1256  *gp = Cudd_Not(one);
1257  }
1258  if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
1259  *hp = Cudd_Not(one);
1260  } else if (f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */
1261  *hp = one;
1262  }
1263 
1264 } /* end of bddVarToConst */
1265 
1266 
1278 static int
1280  DdManager * dd,
1281  DdNode ** fp,
1282  DdNode ** gp,
1283  DdNode ** hp,
1284  unsigned int * topfp,
1285  unsigned int * topgp,
1286  unsigned int * tophp)
1287 {
1288  register DdNode *F, *G, *H, *r, *f, *g, *h;
1289  register unsigned int topf, topg, toph;
1290  DdNode *one = dd->one;
1291  int comple, change;
1292 
1293  f = *fp;
1294  g = *gp;
1295  h = *hp;
1296  F = Cudd_Regular(f);
1297  G = Cudd_Regular(g);
1298  H = Cudd_Regular(h);
1299  topf = cuddI(dd,F->index);
1300  topg = cuddI(dd,G->index);
1301  toph = cuddI(dd,H->index);
1302 
1303  change = 0;
1304 
1305  if (G == one) { /* ITE(F,c,H) */
1306  if ((topf > toph) || (topf == toph && f > h)) {
1307  r = h;
1308  h = f;
1309  f = r; /* ITE(F,1,H) = ITE(H,1,F) */
1310  if (g != one) { /* g == zero */
1311  f = Cudd_Not(f); /* ITE(F,0,H) = ITE(!H,0,!F) */
1312  h = Cudd_Not(h);
1313  }
1314  change = 1;
1315  }
1316  } else if (H == one) { /* ITE(F,G,c) */
1317  if ((topf > topg) || (topf == topg && f > g)) {
1318  r = g;
1319  g = f;
1320  f = r; /* ITE(F,G,0) = ITE(G,F,0) */
1321  if (h == one) {
1322  f = Cudd_Not(f); /* ITE(F,G,1) = ITE(!G,!F,1) */
1323  g = Cudd_Not(g);
1324  }
1325  change = 1;
1326  }
1327  } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = ITE(G,F,!F) */
1328  if ((topf > topg) || (topf == topg && f > g)) {
1329  r = f;
1330  f = g;
1331  g = r;
1332  h = Cudd_Not(r);
1333  change = 1;
1334  }
1335  }
1336  /* adjust pointers so that the first 2 arguments to ITE are regular */
1337  if (Cudd_IsComplement(f) != 0) { /* ITE(!F,G,H) = ITE(F,H,G) */
1338  f = Cudd_Not(f);
1339  r = g;
1340  g = h;
1341  h = r;
1342  change = 1;
1343  }
1344  comple = 0;
1345  if (Cudd_IsComplement(g) != 0) { /* ITE(F,!G,H) = !ITE(F,G,!H) */
1346  g = Cudd_Not(g);
1347  h = Cudd_Not(h);
1348  change = 1;
1349  comple = 1;
1350  }
1351  if (change != 0) {
1352  *fp = f;
1353  *gp = g;
1354  *hp = h;
1355  }
1356  *topfp = cuddI(dd,f->index);
1357  *topgp = cuddI(dd,g->index);
1358  *tophp = cuddI(dd,Cudd_Regular(h)->index);
1359 
1360  return(comple);
1361 
1362 } /* end of bddVarToCanonical */
1363 
1364 
1380 static int
1382  DdManager * dd,
1383  DdNode ** fp,
1384  DdNode ** gp,
1385  DdNode ** hp,
1386  unsigned int * topfp,
1387  unsigned int * topgp,
1388  unsigned int * tophp)
1389 {
1390  register DdNode *r, *f, *g, *h;
1391  int comple, change;
1392 
1393  f = *fp;
1394  g = *gp;
1395  h = *hp;
1396 
1397  change = 0;
1398 
1399  /* adjust pointers so that the first 2 arguments to ITE are regular */
1400  if (Cudd_IsComplement(f)) { /* ITE(!F,G,H) = ITE(F,H,G) */
1401  f = Cudd_Not(f);
1402  r = g;
1403  g = h;
1404  h = r;
1405  change = 1;
1406  }
1407  comple = 0;
1408  if (Cudd_IsComplement(g)) { /* ITE(F,!G,H) = !ITE(F,G,!H) */
1409  g = Cudd_Not(g);
1410  h = Cudd_Not(h);
1411  change = 1;
1412  comple = 1;
1413  }
1414  if (change) {
1415  *fp = f;
1416  *gp = g;
1417  *hp = h;
1418  }
1419 
1420  /* Here we can skip the use of cuddI, because the operands are known
1421  ** to be non-constant.
1422  */
1423  *topfp = dd->perm[f->index];
1424  *topgp = dd->perm[g->index];
1425  *tophp = dd->perm[Cudd_Regular(h)->index];
1426 
1427  return(comple);
1428 
1429 } /* end of bddVarToCanonicalSimple */
1430 
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
DdHalfWord ref
Definition: cudd.h:272
DdNode * Cudd_bddIntersect(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:318
#define cuddRef(n)
Definition: cuddInt.h:557
static int bddVarToCanonical(DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)
Definition: cuddBddIte.c:1279
DdNode * Cudd_bddOr(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:417
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
unsigned int deadZ
Definition: cuddInt.h:356
DdNode * Cudd_bddXnorLimit(DdManager *dd, DdNode *f, DdNode *g, unsigned int limit)
Definition: cuddBddIte.c:612
#define DD_BDD_ITE_CONSTANT_TAG
Definition: cuddInt.h:187
DdNode * cuddCacheLookup2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
#define Cudd_IsConstant(node)
Definition: cudd.h:339
#define Cudd_Regular(node)
Definition: cudd.h:384
static int bddVarToCanonicalSimple(DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)
Definition: cuddBddIte.c:1381
DdNode * Cudd_bddAndLimit(DdManager *dd, DdNode *f, DdNode *g, unsigned int limit)
Definition: cuddBddIte.c:382
DdNode * Cudd_bddIteConstant(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:210
DdNode * Cudd_bddNor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:518
#define statLine(dd)
Definition: cuddInt.h:990
static char rcsid [] DD_UNUSED
Definition: cuddBddIte.c:102
int reordered
Definition: cuddInt.h:392
unsigned int dead
Definition: cuddInt.h:355
static DdNode * one
Definition: cuddSat.c:105
static void bddVarToConst(DdNode *f, DdNode **gp, DdNode **hp, DdNode *one)
Definition: cuddBddIte.c:1244
#define Cudd_IsComplement(node)
Definition: cudd.h:412
unsigned int maxLive
Definition: cuddInt.h:357
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:308
unsigned int keys
Definition: cuddInt.h:353
DdNode * Cudd_bddXnor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:580
DdNode * Cudd_bddXor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:549
#define ddMin(x, y)
Definition: cuddInt.h:771
#define DD_BDD_ITE_TAG
Definition: cuddInt.h:176
#define cuddT(node)
Definition: cuddInt.h:609
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:645
DdNode * Cudd_bddIteLimit(DdManager *dd, DdNode *f, DdNode *g, DdNode *h, unsigned int limit)
Definition: cuddBddIte.c:175
#define cuddI(dd, index)
Definition: cuddInt.h:659
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:347
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
DdNode * cuddBddIntersectRecur(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:880
static DdNode * zero
Definition: cuddSat.c:105
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1123
DdNode * cuddConstantLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:690
DdNode * one
Definition: cuddInt.h:329
DdNode * Cudd_bddNand(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:486
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:370
DdNode * Cudd_bddOrLimit(DdManager *dd, DdNode *f, DdNode *g, unsigned int limit)
Definition: cuddBddIte.c:450
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:350
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:217
#define DD_ONE(dd)
Definition: cuddInt.h:864
unsigned int keysZ
Definition: cuddInt.h:354
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995
int * perm
Definition: cuddInt.h:369
DdNode * Cudd_bddIte(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:142
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137
#define DD_NON_CONSTANT
Definition: cuddInt.h:124
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:742