00001
00031 #include "util_hack.h"
00032 #include "cuddInt.h"
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #ifndef lint
00054 static char rcsid[] DD_UNUSED = "$Id: cuddSolve.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
00055 #endif
00056
00057
00058
00059
00060
00061
00064
00065
00066
00067
00068
00072
00073
00074
00075
00076
00094 DdNode *
00095 Cudd_SolveEqn(
00096 DdManager * bdd,
00097 DdNode * F ,
00098 DdNode * Y ,
00099 DdNode ** G ,
00100 int ** yIndex ,
00101 int n )
00102 {
00103 DdNode *res;
00104 int *temp;
00105
00106 *yIndex = temp = ALLOC(int, n);
00107 if (temp == NULL) {
00108 bdd->errorCode = CUDD_MEMORY_OUT;
00109 (void) fprintf(bdd->out,
00110 "Cudd_SolveEqn: Out of memory for yIndex\n");
00111 return(NULL);
00112 }
00113
00114 do {
00115 bdd->reordered = 0;
00116 res = cuddSolveEqnRecur(bdd, F, Y, G, n, temp, 0);
00117 } while (bdd->reordered == 1);
00118
00119 return(res);
00120
00121 }
00122
00123
00137 DdNode *
00138 Cudd_VerifySol(
00139 DdManager * bdd,
00140 DdNode * F ,
00141 DdNode ** G ,
00142 int * yIndex ,
00143 int n )
00144 {
00145 DdNode *res;
00146
00147 do {
00148 bdd->reordered = 0;
00149 res = cuddVerifySol(bdd, F, G, yIndex, n);
00150 } while (bdd->reordered == 1);
00151
00152 FREE(yIndex);
00153
00154 return(res);
00155
00156 }
00157
00158
00159
00160
00161
00162
00163
00178 DdNode *
00179 cuddSolveEqnRecur(
00180 DdManager * bdd,
00181 DdNode * F ,
00182 DdNode * Y ,
00183 DdNode ** G ,
00184 int n ,
00185 int * yIndex ,
00186 int i )
00187 {
00188 DdNode *Fn, *Fm1, *Fv, *Fvbar, *T, *w, *nextY, *one;
00189 DdNodePtr *variables;
00190
00191 int j;
00192
00193 statLine(bdd);
00194 variables = bdd->vars;
00195 one = DD_ONE(bdd);
00196
00197
00198 if (Y == one) {
00199 return F;
00200 }
00201
00202
00203 yIndex[i] = Y->index;
00204 nextY = Cudd_T(Y);
00205
00206
00207 Fm1 = cuddBddExistAbstractRecur(bdd, Cudd_Not(F), variables[yIndex[i]]);
00208 if (Fm1) {
00209 Fm1 = Cudd_Not(Fm1);
00210 cuddRef(Fm1);
00211 } else {
00212 return(NULL);
00213 }
00214
00215 Fn = cuddSolveEqnRecur(bdd, Fm1, nextY, G, n, yIndex, i+1);
00216 if (Fn) {
00217 cuddRef(Fn);
00218 } else {
00219 Cudd_RecursiveDeref(bdd, Fm1);
00220 return(NULL);
00221 }
00222
00223 Fv = cuddCofactorRecur(bdd, F, variables[yIndex[i]]);
00224 if (Fv) {
00225 cuddRef(Fv);
00226 } else {
00227 Cudd_RecursiveDeref(bdd, Fm1);
00228 Cudd_RecursiveDeref(bdd, Fn);
00229 return(NULL);
00230 }
00231
00232 Fvbar = cuddCofactorRecur(bdd, F, Cudd_Not(variables[yIndex[i]]));
00233 if (Fvbar) {
00234 cuddRef(Fvbar);
00235 } else {
00236 Cudd_RecursiveDeref(bdd, Fm1);
00237 Cudd_RecursiveDeref(bdd, Fn);
00238 Cudd_RecursiveDeref(bdd, Fv);
00239 return(NULL);
00240 }
00241
00242
00243 w = cuddBddIteRecur(bdd, variables[yIndex[i]], Cudd_Not(Fv), Fvbar);
00244 if (w) {
00245 cuddRef(w);
00246 } else {
00247 Cudd_RecursiveDeref(bdd, Fm1);
00248 Cudd_RecursiveDeref(bdd, Fn);
00249 Cudd_RecursiveDeref(bdd, Fv);
00250 Cudd_RecursiveDeref(bdd, Fvbar);
00251 return(NULL);
00252 }
00253
00254 T = cuddBddRestrictRecur(bdd, w, Cudd_Not(Fm1));
00255 if(T) {
00256 cuddRef(T);
00257 } else {
00258 Cudd_RecursiveDeref(bdd, Fm1);
00259 Cudd_RecursiveDeref(bdd, Fn);
00260 Cudd_RecursiveDeref(bdd, Fv);
00261 Cudd_RecursiveDeref(bdd, Fvbar);
00262 Cudd_RecursiveDeref(bdd, w);
00263 return(NULL);
00264 }
00265
00266 Cudd_RecursiveDeref(bdd,Fm1);
00267 Cudd_RecursiveDeref(bdd,w);
00268 Cudd_RecursiveDeref(bdd,Fv);
00269 Cudd_RecursiveDeref(bdd,Fvbar);
00270
00271
00272 for (j = n-1; j > i; j--) {
00273 w = cuddBddComposeRecur(bdd,T, G[j], variables[yIndex[j]]);
00274 if(w) {
00275 cuddRef(w);
00276 } else {
00277 Cudd_RecursiveDeref(bdd, Fn);
00278 Cudd_RecursiveDeref(bdd, T);
00279 return(NULL);
00280 }
00281 Cudd_RecursiveDeref(bdd,T);
00282 T = w;
00283 }
00284 G[i] = T;
00285
00286 Cudd_Deref(Fn);
00287
00288 return(Fn);
00289
00290 }
00291
00292
00304 DdNode *
00305 cuddVerifySol(
00306 DdManager * bdd,
00307 DdNode * F ,
00308 DdNode ** G ,
00309 int * yIndex ,
00310 int n )
00311 {
00312 DdNode *w, *R;
00313
00314 int j;
00315
00316 R = F;
00317 cuddRef(R);
00318 for(j = n - 1; j >= 0; j--) {
00319 w = Cudd_bddCompose(bdd, R, G[j], yIndex[j]);
00320 if (w) {
00321 cuddRef(w);
00322 } else {
00323 return(NULL);
00324 }
00325 Cudd_RecursiveDeref(bdd,R);
00326 R = w;
00327 }
00328
00329 cuddDeref(R);
00330
00331 return(R);
00332
00333 }
00334
00335
00336
00337
00338
00339