00001
00059 #include "util.h"
00060 #include "cuddInt.h"
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 #ifndef lint
00082 static char rcsid[] DD_UNUSED = "$Id: cuddCof.c,v 1.9 2004/08/13 18:04:47 fabio Exp $";
00083 #endif
00084
00085
00086
00087
00088
00089
00092
00093
00094
00095
00096
00100
00101
00102
00103
00104
00118 DdNode *
00119 Cudd_Cofactor(
00120 DdManager * dd,
00121 DdNode * f,
00122 DdNode * g)
00123 {
00124 DdNode *res,*zero;
00125
00126 zero = Cudd_Not(DD_ONE(dd));
00127 if (g == zero || g == DD_ZERO(dd)) {
00128 (void) fprintf(dd->err,"Cudd_Cofactor: Invalid restriction 1\n");
00129 dd->errorCode = CUDD_INVALID_ARG;
00130 return(NULL);
00131 }
00132 do {
00133 dd->reordered = 0;
00134 res = cuddCofactorRecur(dd,f,g);
00135 } while (dd->reordered == 1);
00136 return(res);
00137
00138 }
00139
00140
00141
00142
00143
00144
00145
00157 void
00158 cuddGetBranches(
00159 DdNode * g,
00160 DdNode ** g1,
00161 DdNode ** g0)
00162 {
00163 DdNode *G = Cudd_Regular(g);
00164
00165 *g1 = cuddT(G);
00166 *g0 = cuddE(G);
00167 if (Cudd_IsComplement(g)) {
00168 *g1 = Cudd_Not(*g1);
00169 *g0 = Cudd_Not(*g0);
00170 }
00171
00172 }
00173
00174
00188 int
00189 cuddCheckCube(
00190 DdManager * dd,
00191 DdNode * g)
00192 {
00193 DdNode *g1,*g0,*one,*zero;
00194
00195 one = DD_ONE(dd);
00196 if (g == one) return(1);
00197 if (Cudd_IsConstant(g)) return(0);
00198
00199 zero = Cudd_Not(one);
00200 cuddGetBranches(g,&g1,&g0);
00201
00202 if (g0 == zero) {
00203 return(cuddCheckCube(dd, g1));
00204 }
00205 if (g1 == zero) {
00206 return(cuddCheckCube(dd, g0));
00207 }
00208 return(0);
00209
00210 }
00211
00212
00225 DdNode *
00226 cuddCofactorRecur(
00227 DdManager * dd,
00228 DdNode * f,
00229 DdNode * g)
00230 {
00231 DdNode *one,*zero,*F,*G,*g1,*g0,*f1,*f0,*t,*e,*r;
00232 unsigned int topf,topg;
00233 int comple;
00234
00235 statLine(dd);
00236 F = Cudd_Regular(f);
00237 if (cuddIsConstant(F)) return(f);
00238
00239 one = DD_ONE(dd);
00240
00241
00242
00243
00244
00245 if (g == one) return(f);
00246
00247
00248 comple = f != F;
00249 r = cuddCacheLookup2(dd,Cudd_Cofactor,F,g);
00250 if (r != NULL) {
00251 return(Cudd_NotCond(r,comple));
00252 }
00253
00254 topf = dd->perm[F->index];
00255 G = Cudd_Regular(g);
00256 topg = dd->perm[G->index];
00257
00258
00259
00260
00261
00262
00263 if (topf <= topg) {
00264 f1 = cuddT(F); f0 = cuddE(F);
00265 } else {
00266 f1 = f0 = F;
00267 }
00268 if (topg <= topf) {
00269 g1 = cuddT(G); g0 = cuddE(G);
00270 if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); }
00271 } else {
00272 g1 = g0 = g;
00273 }
00274
00275 zero = Cudd_Not(one);
00276 if (topf >= topg) {
00277 if (g0 == zero || g0 == DD_ZERO(dd)) {
00278 r = cuddCofactorRecur(dd, f1, g1);
00279 } else if (g1 == zero || g1 == DD_ZERO(dd)) {
00280 r = cuddCofactorRecur(dd, f0, g0);
00281 } else {
00282 (void) fprintf(dd->out,
00283 "Cudd_Cofactor: Invalid restriction 2\n");
00284 dd->errorCode = CUDD_INVALID_ARG;
00285 return(NULL);
00286 }
00287 if (r == NULL) return(NULL);
00288 } else {
00289 t = cuddCofactorRecur(dd, f1, g);
00290 if (t == NULL) return(NULL);
00291 cuddRef(t);
00292 e = cuddCofactorRecur(dd, f0, g);
00293 if (e == NULL) {
00294 Cudd_RecursiveDeref(dd, t);
00295 return(NULL);
00296 }
00297 cuddRef(e);
00298
00299 if (t == e) {
00300 r = t;
00301 } else if (Cudd_IsComplement(t)) {
00302 r = cuddUniqueInter(dd,(int)F->index,Cudd_Not(t),Cudd_Not(e));
00303 if (r != NULL)
00304 r = Cudd_Not(r);
00305 } else {
00306 r = cuddUniqueInter(dd,(int)F->index,t,e);
00307 }
00308 if (r == NULL) {
00309 Cudd_RecursiveDeref(dd ,e);
00310 Cudd_RecursiveDeref(dd ,t);
00311 return(NULL);
00312 }
00313 cuddDeref(t);
00314 cuddDeref(e);
00315 }
00316
00317 cuddCacheInsert2(dd,Cudd_Cofactor,F,g,r);
00318
00319 return(Cudd_NotCond(r,comple));
00320
00321 }
00322
00323
00324
00325
00326
00327