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