00001
00058 #include "util.h"
00059 #include "cuddInt.h"
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 #ifndef lint
00081 static char rcsid[] DD_UNUSED = "$Id: cuddSolve.c,v 1.12 2004/08/13 18:04:51 fabio Exp $";
00082 #endif
00083
00084
00085
00086
00087
00088
00091
00092
00093
00094
00095
00099
00100
00101
00102
00103
00121 DdNode *
00122 Cudd_SolveEqn(
00123 DdManager * bdd,
00124 DdNode * F ,
00125 DdNode * Y ,
00126 DdNode ** G ,
00127 int ** yIndex ,
00128 int n )
00129 {
00130 DdNode *res;
00131 int *temp;
00132
00133 *yIndex = temp = ALLOC(int, n);
00134 if (temp == NULL) {
00135 bdd->errorCode = CUDD_MEMORY_OUT;
00136 (void) fprintf(bdd->out,
00137 "Cudd_SolveEqn: Out of memory for yIndex\n");
00138 return(NULL);
00139 }
00140
00141 do {
00142 bdd->reordered = 0;
00143 res = cuddSolveEqnRecur(bdd, F, Y, G, n, temp, 0);
00144 } while (bdd->reordered == 1);
00145
00146 return(res);
00147
00148 }
00149
00150
00164 DdNode *
00165 Cudd_VerifySol(
00166 DdManager * bdd,
00167 DdNode * F ,
00168 DdNode ** G ,
00169 int * yIndex ,
00170 int n )
00171 {
00172 DdNode *res;
00173
00174 do {
00175 bdd->reordered = 0;
00176 res = cuddVerifySol(bdd, F, G, yIndex, n);
00177 } while (bdd->reordered == 1);
00178
00179 FREE(yIndex);
00180
00181 return(res);
00182
00183 }
00184
00185
00186
00187
00188
00189
00190
00205 DdNode *
00206 cuddSolveEqnRecur(
00207 DdManager * bdd,
00208 DdNode * F ,
00209 DdNode * Y ,
00210 DdNode ** G ,
00211 int n ,
00212 int * yIndex ,
00213 int i )
00214 {
00215 DdNode *Fn, *Fm1, *Fv, *Fvbar, *T, *w, *nextY, *one;
00216 DdNodePtr *variables;
00217
00218 int j;
00219
00220 statLine(bdd);
00221 variables = bdd->vars;
00222 one = DD_ONE(bdd);
00223
00224
00225 if (Y == one) {
00226 return F;
00227 }
00228
00229
00230 yIndex[i] = Y->index;
00231 nextY = Cudd_T(Y);
00232
00233
00234 Fm1 = cuddBddExistAbstractRecur(bdd, Cudd_Not(F), variables[yIndex[i]]);
00235 if (Fm1) {
00236 Fm1 = Cudd_Not(Fm1);
00237 cuddRef(Fm1);
00238 } else {
00239 return(NULL);
00240 }
00241
00242 Fn = cuddSolveEqnRecur(bdd, Fm1, nextY, G, n, yIndex, i+1);
00243 if (Fn) {
00244 cuddRef(Fn);
00245 } else {
00246 Cudd_RecursiveDeref(bdd, Fm1);
00247 return(NULL);
00248 }
00249
00250 Fv = cuddCofactorRecur(bdd, F, variables[yIndex[i]]);
00251 if (Fv) {
00252 cuddRef(Fv);
00253 } else {
00254 Cudd_RecursiveDeref(bdd, Fm1);
00255 Cudd_RecursiveDeref(bdd, Fn);
00256 return(NULL);
00257 }
00258
00259 Fvbar = cuddCofactorRecur(bdd, F, Cudd_Not(variables[yIndex[i]]));
00260 if (Fvbar) {
00261 cuddRef(Fvbar);
00262 } else {
00263 Cudd_RecursiveDeref(bdd, Fm1);
00264 Cudd_RecursiveDeref(bdd, Fn);
00265 Cudd_RecursiveDeref(bdd, Fv);
00266 return(NULL);
00267 }
00268
00269
00270 w = cuddBddIteRecur(bdd, variables[yIndex[i]], Cudd_Not(Fv), Fvbar);
00271 if (w) {
00272 cuddRef(w);
00273 } else {
00274 Cudd_RecursiveDeref(bdd, Fm1);
00275 Cudd_RecursiveDeref(bdd, Fn);
00276 Cudd_RecursiveDeref(bdd, Fv);
00277 Cudd_RecursiveDeref(bdd, Fvbar);
00278 return(NULL);
00279 }
00280
00281 T = cuddBddRestrictRecur(bdd, w, Cudd_Not(Fm1));
00282 if(T) {
00283 cuddRef(T);
00284 } else {
00285 Cudd_RecursiveDeref(bdd, Fm1);
00286 Cudd_RecursiveDeref(bdd, Fn);
00287 Cudd_RecursiveDeref(bdd, Fv);
00288 Cudd_RecursiveDeref(bdd, Fvbar);
00289 Cudd_RecursiveDeref(bdd, w);
00290 return(NULL);
00291 }
00292
00293 Cudd_RecursiveDeref(bdd,Fm1);
00294 Cudd_RecursiveDeref(bdd,w);
00295 Cudd_RecursiveDeref(bdd,Fv);
00296 Cudd_RecursiveDeref(bdd,Fvbar);
00297
00298
00299 for (j = n-1; j > i; j--) {
00300 w = cuddBddComposeRecur(bdd,T, G[j], variables[yIndex[j]]);
00301 if(w) {
00302 cuddRef(w);
00303 } else {
00304 Cudd_RecursiveDeref(bdd, Fn);
00305 Cudd_RecursiveDeref(bdd, T);
00306 return(NULL);
00307 }
00308 Cudd_RecursiveDeref(bdd,T);
00309 T = w;
00310 }
00311 G[i] = T;
00312
00313 Cudd_Deref(Fn);
00314
00315 return(Fn);
00316
00317 }
00318
00319
00331 DdNode *
00332 cuddVerifySol(
00333 DdManager * bdd,
00334 DdNode * F ,
00335 DdNode ** G ,
00336 int * yIndex ,
00337 int n )
00338 {
00339 DdNode *w, *R;
00340
00341 int j;
00342
00343 R = F;
00344 cuddRef(R);
00345 for(j = n - 1; j >= 0; j--) {
00346 w = Cudd_bddCompose(bdd, R, G[j], yIndex[j]);
00347 if (w) {
00348 cuddRef(w);
00349 } else {
00350 return(NULL);
00351 }
00352 Cudd_RecursiveDeref(bdd,R);
00353 R = w;
00354 }
00355
00356 cuddDeref(R);
00357
00358 return(R);
00359
00360 }
00361
00362
00363
00364
00365
00366