00001 
00032 #include    "util_hack.h"
00033 #include    "cuddInt.h"
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 #ifndef lint
00055 static char rcsid[] DD_UNUSED = "$Id: cuddCof.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
00056 #endif
00057 
00058 
00059 
00060 
00061 
00062 
00065 
00066 
00067 
00068 
00069 
00073 
00074 
00075 
00076 
00077 
00091 DdNode *
00092 Cudd_Cofactor(
00093   DdManager * dd,
00094   DdNode * f,
00095   DdNode * g)
00096 {
00097     DdNode *res,*zero;
00098 
00099     zero = Cudd_Not(DD_ONE(dd));
00100     if (g == zero || g == DD_ZERO(dd)) {
00101         (void) fprintf(dd->err,"Cudd_Cofactor: Invalid restriction 1\n");
00102         dd->errorCode = CUDD_INVALID_ARG;
00103         return(NULL);
00104     }
00105     do {
00106         dd->reordered = 0;
00107         res = cuddCofactorRecur(dd,f,g);
00108     } while (dd->reordered == 1);
00109     return(res);
00110 
00111 } 
00112 
00113 
00114 
00115 
00116 
00117 
00118 
00130 void
00131 cuddGetBranches(
00132   DdNode * g,
00133   DdNode ** g1,
00134   DdNode ** g0)
00135 {
00136     DdNode      *G = Cudd_Regular(g);
00137 
00138     *g1 = cuddT(G);
00139     *g0 = cuddE(G);
00140     if (Cudd_IsComplement(g)) {
00141         *g1 = Cudd_Not(*g1);
00142         *g0 = Cudd_Not(*g0);
00143     }
00144 
00145 } 
00146 
00147 
00161 int
00162 cuddCheckCube(
00163   DdManager * dd,
00164   DdNode * g)
00165 {
00166     DdNode *g1,*g0,*one,*zero;
00167     
00168     one = DD_ONE(dd);
00169     if (g == one) return(1);
00170     if (Cudd_IsConstant(g)) return(0);
00171 
00172     zero = Cudd_Not(one);
00173     cuddGetBranches(g,&g1,&g0);
00174 
00175     if (g0 == zero) {
00176         return(cuddCheckCube(dd, g1));
00177     }
00178     if (g1 == zero) {
00179         return(cuddCheckCube(dd, g0));
00180     }
00181     return(0);
00182 
00183 } 
00184 
00185 
00198 DdNode *
00199 cuddCofactorRecur(
00200   DdManager * dd,
00201   DdNode * f,
00202   DdNode * g)
00203 {
00204     DdNode *one,*zero,*F,*G,*g1,*g0,*f1,*f0,*t,*e,*r;
00205     unsigned int topf,topg;
00206     int comple;
00207 
00208     statLine(dd);
00209     F = Cudd_Regular(f);
00210     if (cuddIsConstant(F)) return(f);
00211 
00212     one = DD_ONE(dd);
00213 
00214     
00215 
00216 
00217 
00218     if (g == one) return(f);
00219     
00220 
00221     comple = f != F;
00222     r = cuddCacheLookup2(dd,Cudd_Cofactor,F,g);
00223     if (r != NULL) {
00224         return(Cudd_NotCond(r,comple));
00225     }
00226 
00227     topf = dd->perm[F->index];
00228     G = Cudd_Regular(g);
00229     topg = dd->perm[G->index];
00230 
00231     
00232 
00233 
00234 
00235 
00236     if (topf <= topg) {
00237         f1 = cuddT(F); f0 = cuddE(F);
00238     } else {
00239         f1 = f0 = F;
00240     }
00241     if (topg <= topf) {
00242         g1 = cuddT(G); g0 = cuddE(G);
00243         if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); }
00244     } else {
00245         g1 = g0 = g;
00246     }
00247 
00248     zero = Cudd_Not(one);
00249     if (topf >= topg) {
00250         if (g0 == zero || g0 == DD_ZERO(dd)) {
00251             r = cuddCofactorRecur(dd, f1, g1);
00252         } else if (g1 == zero || g1 == DD_ZERO(dd)) {
00253             r = cuddCofactorRecur(dd, f0, g0);
00254         } else {
00255             (void) fprintf(dd->out,
00256                            "Cudd_Cofactor: Invalid restriction 2\n");
00257             dd->errorCode = CUDD_INVALID_ARG;
00258             return(NULL);
00259         }
00260         if (r == NULL) return(NULL);
00261     } else  {
00262         t = cuddCofactorRecur(dd, f1, g);
00263         if (t == NULL) return(NULL);
00264         cuddRef(t);
00265         e = cuddCofactorRecur(dd, f0, g);
00266         if (e == NULL) {
00267             Cudd_RecursiveDeref(dd, t);
00268             return(NULL);
00269         }
00270         cuddRef(e);
00271 
00272         if (t == e) {
00273             r = t;
00274         } else if (Cudd_IsComplement(t)) {
00275             r = cuddUniqueInter(dd,(int)F->index,Cudd_Not(t),Cudd_Not(e));
00276             if (r != NULL)
00277                 r = Cudd_Not(r);
00278         } else {
00279             r = cuddUniqueInter(dd,(int)F->index,t,e);
00280         }
00281         if (r == NULL) {
00282             Cudd_RecursiveDeref(dd ,e);
00283             Cudd_RecursiveDeref(dd ,t);
00284             return(NULL);
00285         }
00286         cuddDeref(t);
00287         cuddDeref(e);
00288     }
00289 
00290     cuddCacheInsert2(dd,Cudd_Cofactor,F,g,r);
00291 
00292     return(Cudd_NotCond(r,comple));
00293 
00294 } 
00295 
00296 
00297 
00298 
00299 
00300