SVF
cuddAddIte.c
Go to the documentation of this file.
1 
63 #include "CUDD/util.h"
64 #include "CUDD/cuddInt.h"
65 
66 /*---------------------------------------------------------------------------*/
67 /* Constant declarations */
68 /*---------------------------------------------------------------------------*/
69 
70 
71 /*---------------------------------------------------------------------------*/
72 /* Stucture declarations */
73 /*---------------------------------------------------------------------------*/
74 
75 
76 /*---------------------------------------------------------------------------*/
77 /* Type declarations */
78 /*---------------------------------------------------------------------------*/
79 
80 
81 /*---------------------------------------------------------------------------*/
82 /* Variable declarations */
83 /*---------------------------------------------------------------------------*/
84 
85 #ifndef lint
86 static char rcsid[] DD_UNUSED = "$Id: cuddAddIte.c,v 1.16 2012/02/05 01:07:18 fabio Exp $";
87 #endif
88 
89 
90 /*---------------------------------------------------------------------------*/
91 /* Macro declarations */
92 /*---------------------------------------------------------------------------*/
93 
94 
97 /*---------------------------------------------------------------------------*/
98 /* Static function prototypes */
99 /*---------------------------------------------------------------------------*/
100 
101 static void addVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one, DdNode *zero);
102 
106 /*---------------------------------------------------------------------------*/
107 /* Definition of exported functions */
108 /*---------------------------------------------------------------------------*/
109 
110 
124 DdNode *
126  DdManager * dd,
127  DdNode * f,
128  DdNode * g,
129  DdNode * h)
130 {
131  DdNode *res;
132 
133  do {
134  dd->reordered = 0;
135  res = cuddAddIteRecur(dd,f,g,h);
136  } while (dd->reordered == 1);
137  return(res);
138 
139 } /* end of Cudd_addIte */
140 
141 
158 DdNode *
160  DdManager * dd,
161  DdNode * f,
162  DdNode * g,
163  DdNode * h)
164 {
165  DdNode *one,*zero;
166  DdNode *Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*r,*t,*e;
167  unsigned int topf,topg,toph,v;
168 
169  statLine(dd);
170  /* Trivial cases. */
171  if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */
172  return(g);
173  }
174  if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */
175  return(h);
176  }
177 
178  /* From now on, f is known not to be a constant. */
179  addVarToConst(f,&g,&h,one,zero);
180 
181  /* Check remaining one variable cases. */
182  if (g == h) { /* ITE(F,G,G) = G */
183  return(g);
184  }
185  if (cuddIsConstant(g) && cuddIsConstant(h)) {
186  return(DD_NON_CONSTANT);
187  }
188 
189  topf = cuddI(dd,f->index);
190  topg = cuddI(dd,g->index);
191  toph = cuddI(dd,h->index);
192  v = ddMin(topg,toph);
193 
194  /* ITE(F,G,H) = (x,G,H) (non constant) if F = (x,1,0), x < top(G,H). */
195  if (topf < v && cuddIsConstant(cuddT(f)) && cuddIsConstant(cuddE(f))) {
196  return(DD_NON_CONSTANT);
197  }
198 
199  /* Check cache. */
201  if (r != NULL) {
202  return(r);
203  }
204 
205  /* Compute cofactors. */
206  if (topf <= v) {
207  v = ddMin(topf,v); /* v = top_var(F,G,H) */
208  Fv = cuddT(f); Fnv = cuddE(f);
209  } else {
210  Fv = Fnv = f;
211  }
212  if (topg == v) {
213  Gv = cuddT(g); Gnv = cuddE(g);
214  } else {
215  Gv = Gnv = g;
216  }
217  if (toph == v) {
218  Hv = cuddT(h); Hnv = cuddE(h);
219  } else {
220  Hv = Hnv = h;
221  }
222 
223  /* Recursive step. */
224  t = Cudd_addIteConstant(dd,Fv,Gv,Hv);
225  if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) {
227  return(DD_NON_CONSTANT);
228  }
229  e = Cudd_addIteConstant(dd,Fnv,Gnv,Hnv);
230  if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) {
232  return(DD_NON_CONSTANT);
233  }
234  cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, t);
235  return(t);
236 
237 } /* end of Cudd_addIteConstant */
238 
239 
255 DdNode *
257  DdManager * dd,
258  DdNode * f,
259  DdNode * g)
260 {
261  DdNode *zero;
262  DdNode *Fv,*Fnv,*Gv,*Gnv,*r,*t,*e;
263  unsigned int topf,topg;
264 
265 #ifdef DD_DEBUG
267 #endif
268 
269  statLine(dd);
270  /* Terminal cases. */
271  if (f == DD_ONE(dd) || cuddIsConstant(g)) {
272  return(g);
273  }
274  if (f == (zero = DD_ZERO(dd))) {
275  return(dd->background);
276  }
277 
278 #ifdef DD_DEBUG
279  assert(!cuddIsConstant(f));
280 #endif
281  /* From now on, f and g are known not to be constants. */
282 
283  topf = cuddI(dd,f->index);
284  topg = cuddI(dd,g->index);
285 
286  /* Check cache. */
288  if (r != NULL) {
289  return(r);
290  }
291 
292  /* Compute cofactors. */
293  if (topf <= topg) {
294  Fv = cuddT(f); Fnv = cuddE(f);
295  } else {
296  Fv = Fnv = f;
297  }
298  if (topg <= topf) {
299  Gv = cuddT(g); Gnv = cuddE(g);
300  } else {
301  Gv = Gnv = g;
302  }
303 
304  /* Recursive step. */
305  if (Fv != zero) {
306  t = Cudd_addEvalConst(dd,Fv,Gv);
307  if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) {
309  return(DD_NON_CONSTANT);
310  }
311  if (Fnv != zero) {
312  e = Cudd_addEvalConst(dd,Fnv,Gnv);
313  if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) {
315  return(DD_NON_CONSTANT);
316  }
317  }
319  return(t);
320  } else { /* Fnv must be != zero */
321  e = Cudd_addEvalConst(dd,Fnv,Gnv);
322  cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, e);
323  return(e);
324  }
325 
326 } /* end of Cudd_addEvalConst */
327 
328 
342 DdNode *
344  DdManager * dd,
345  DdNode * f)
346 {
347  DdNode *res;
348 
349  do {
350  dd->reordered = 0;
351  res = cuddAddCmplRecur(dd,f);
352  } while (dd->reordered == 1);
353  return(res);
354 
355 } /* end of Cudd_addCmpl */
356 
357 
371 int
373  DdManager * dd,
374  DdNode * f,
375  DdNode * g)
376 {
377  DdNode *tmp, *fv, *fvn, *gv, *gvn;
378  unsigned int topf, topg, res;
379 
380  /* Terminal cases. */
381  if (f == g) return(1);
382 
383  statLine(dd);
384  if (cuddIsConstant(f)) {
385  if (cuddIsConstant(g)) return(cuddV(f) <= cuddV(g));
386  if (f == DD_MINUS_INFINITY(dd)) return(1);
387  if (f == DD_PLUS_INFINITY(dd)) return(0); /* since f != g */
388  }
389  if (g == DD_PLUS_INFINITY(dd)) return(1);
390  if (g == DD_MINUS_INFINITY(dd)) return(0); /* since f != g */
391 
392  /* Check cache. */
393  tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_addLeq,f,g);
394  if (tmp != NULL) {
395  return(tmp == DD_ONE(dd));
396  }
397 
398  /* Compute cofactors. One of f and g is not constant. */
399  topf = cuddI(dd,f->index);
400  topg = cuddI(dd,g->index);
401  if (topf <= topg) {
402  fv = cuddT(f); fvn = cuddE(f);
403  } else {
404  fv = fvn = f;
405  }
406  if (topg <= topf) {
407  gv = cuddT(g); gvn = cuddE(g);
408  } else {
409  gv = gvn = g;
410  }
411 
412  res = Cudd_addLeq(dd,fvn,gvn) && Cudd_addLeq(dd,fv,gv);
413 
414  /* Store result in cache and return. */
415  cuddCacheInsert2(dd,(DD_CTFP) Cudd_addLeq,f,g,
416  Cudd_NotCond(DD_ONE(dd),res==0));
417  return(res);
418 
419 } /* end of Cudd_addLeq */
420 
421 
422 /*---------------------------------------------------------------------------*/
423 /* Definition of internal functions */
424 /*---------------------------------------------------------------------------*/
425 
426 
440 DdNode *
442  DdManager * dd,
443  DdNode * f,
444  DdNode * g,
445  DdNode * h)
446 {
447  DdNode *one,*zero;
448  DdNode *r,*Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*t,*e;
449  unsigned int topf,topg,toph,v;
450  int index;
451 
452  statLine(dd);
453  /* Trivial cases. */
454 
455  /* One variable cases. */
456  if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */
457  return(g);
458  }
459  if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */
460  return(h);
461  }
462 
463  /* From now on, f is known to not be a constant. */
464  addVarToConst(f,&g,&h,one,zero);
465 
466  /* Check remaining one variable cases. */
467  if (g == h) { /* ITE(F,G,G) = G */
468  return(g);
469  }
470 
471  if (g == one) { /* ITE(F,1,0) = F */
472  if (h == zero) return(f);
473  }
474 
475  topf = cuddI(dd,f->index);
476  topg = cuddI(dd,g->index);
477  toph = cuddI(dd,h->index);
478  v = ddMin(topg,toph);
479 
480  /* A shortcut: ITE(F,G,H) = (x,G,H) if F=(x,1,0), x < top(G,H). */
481  if (topf < v && cuddT(f) == one && cuddE(f) == zero) {
482  r = cuddUniqueInter(dd,(int)f->index,g,h);
483  return(r);
484  }
485  if (topf < v && cuddT(f) == zero && cuddE(f) == one) {
486  r = cuddUniqueInter(dd,(int)f->index,h,g);
487  return(r);
488  }
489 
490  /* Check cache. */
491  r = cuddCacheLookup(dd,DD_ADD_ITE_TAG,f,g,h);
492  if (r != NULL) {
493  return(r);
494  }
495 
496  /* Compute cofactors. */
497  if (topf <= v) {
498  v = ddMin(topf,v); /* v = top_var(F,G,H) */
499  index = f->index;
500  Fv = cuddT(f); Fnv = cuddE(f);
501  } else {
502  Fv = Fnv = f;
503  }
504  if (topg == v) {
505  index = g->index;
506  Gv = cuddT(g); Gnv = cuddE(g);
507  } else {
508  Gv = Gnv = g;
509  }
510  if (toph == v) {
511  index = h->index;
512  Hv = cuddT(h); Hnv = cuddE(h);
513  } else {
514  Hv = Hnv = h;
515  }
516 
517  /* Recursive step. */
518  t = cuddAddIteRecur(dd,Fv,Gv,Hv);
519  if (t == NULL) return(NULL);
520  cuddRef(t);
521 
522  e = cuddAddIteRecur(dd,Fnv,Gnv,Hnv);
523  if (e == NULL) {
524  Cudd_RecursiveDeref(dd,t);
525  return(NULL);
526  }
527  cuddRef(e);
528 
529  r = (t == e) ? t : cuddUniqueInter(dd,index,t,e);
530  if (r == NULL) {
531  Cudd_RecursiveDeref(dd,t);
532  Cudd_RecursiveDeref(dd,e);
533  return(NULL);
534  }
535  cuddDeref(t);
536  cuddDeref(e);
537 
538  cuddCacheInsert(dd,DD_ADD_ITE_TAG,f,g,h,r);
539 
540  return(r);
541 
542 } /* end of cuddAddIteRecur */
543 
544 
557 DdNode *
559  DdManager * dd,
560  DdNode * f)
561 {
562  DdNode *one,*zero;
563  DdNode *r,*Fv,*Fnv,*t,*e;
564 
565  statLine(dd);
566  one = DD_ONE(dd);
567  zero = DD_ZERO(dd);
568 
569  if (cuddIsConstant(f)) {
570  if (f == zero) {
571  return(one);
572  } else {
573  return(zero);
574  }
575  }
576  r = cuddCacheLookup1(dd,Cudd_addCmpl,f);
577  if (r != NULL) {
578  return(r);
579  }
580  Fv = cuddT(f);
581  Fnv = cuddE(f);
582  t = cuddAddCmplRecur(dd,Fv);
583  if (t == NULL) return(NULL);
584  cuddRef(t);
585  e = cuddAddCmplRecur(dd,Fnv);
586  if (e == NULL) {
587  Cudd_RecursiveDeref(dd,t);
588  return(NULL);
589  }
590  cuddRef(e);
591  r = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e);
592  if (r == NULL) {
593  Cudd_RecursiveDeref(dd, t);
594  Cudd_RecursiveDeref(dd, e);
595  return(NULL);
596  }
597  cuddDeref(t);
598  cuddDeref(e);
600  return(r);
601 
602 } /* end of cuddAddCmplRecur */
603 
604 
605 /*---------------------------------------------------------------------------*/
606 /* Definition of static functions */
607 /*---------------------------------------------------------------------------*/
608 
609 
620 static void
622  DdNode * f,
623  DdNode ** gp,
624  DdNode ** hp,
625  DdNode * one,
626  DdNode * zero)
627 {
628  DdNode *g = *gp;
629  DdNode *h = *hp;
630 
631  if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
632  *gp = one;
633  }
634 
635  if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
636  *hp = zero;
637  }
638 
639 } /* end of addVarToConst */
#define cuddRef(n)
Definition: cuddInt.h:557
DdNode * Cudd_addIteConstant(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddAddIte.c:159
DdNode * Cudd_addIte(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddAddIte.c:125
#define cuddDeref(n)
Definition: cuddInt.h:577
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
Definition: cudd.h:270
#define assert(ex)
Definition: util.h:141
DdNode * cuddCacheLookup1(DdManager *table, DdNode *(*)(DdManager *, DdNode *), DdNode *f)
static void addVarToConst(DdNode *f, DdNode **gp, DdNode **hp, DdNode *one, DdNode *zero)
Definition: cuddAddIte.c:621
DdNode * cuddCacheLookup2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
#define DD_ADD_ITE_CONSTANT_TAG
Definition: cuddInt.h:185
DdNode * Cudd_addCmpl(DdManager *dd, DdNode *f)
Definition: cuddAddIte.c:343
void cuddCacheInsert1(DdManager *table, DdNode *(*)(DdManager *, DdNode *), DdNode *f, DdNode *data)
#define DD_ADD_ITE_TAG
Definition: cuddInt.h:173
DdNode * Cudd_addEvalConst(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddAddIte.c:256
#define statLine(dd)
Definition: cuddInt.h:990
#define DD_MINUS_INFINITY(dd)
Definition: cuddInt.h:908
#define cuddV(node)
Definition: cuddInt.h:641
int reordered
Definition: cuddInt.h:392
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:308
int Cudd_addLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddAddIte.c:372
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define DD_ADD_EVAL_CONST_TAG
Definition: cuddInt.h:186
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
#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
static DdNode * zero
Definition: cuddSat.c:105
DdNode * cuddConstantLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:690
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:370
#define DD_PLUS_INFINITY(dd)
Definition: cuddInt.h:894
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:217
DdNode * cuddAddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddAddIte.c:441
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137
DdNode * cuddAddCmplRecur(DdManager *dd, DdNode *f)
Definition: cuddAddIte.c:558
DdNode * background
Definition: cuddInt.h:333
static char rcsid [] DD_UNUSED
Definition: cuddAddIte.c:86
#define DD_NON_CONSTANT
Definition: cuddInt.h:124
#define DD_ZERO(dd)
Definition: cuddInt.h:880