#include "util_hack.h"
#include "cuddInt.h"
Go to the source code of this file.
Functions | |
DdNode * | Cudd_bddAndAbstract (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube) |
DdNode * | cuddBddAndAbstractRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube) |
Variables | |
static char rcsid[] | DD_UNUSED = "$Id: cuddAndAbs.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $" |
AutomaticStart AutomaticEnd Function********************************************************************
Synopsis [Takes the AND of two BDDs and simultaneously abstracts the variables in cube.]
Description [Takes the AND of two BDDs and simultaneously abstracts the variables in cube. The variables are existentially abstracted. Returns a pointer to the result is successful; NULL otherwise. Cudd_bddAndAbstract implements the semiring matrix multiplication algorithm for the boolean semiring.]
SideEffects [None]
SeeAlso [Cudd_addMatrixMultiply Cudd_addTriangle Cudd_bddAnd]
Definition at line 92 of file cuddAndAbs.c.
00097 { 00098 DdNode *res; 00099 00100 do { 00101 manager->reordered = 0; 00102 res = cuddBddAndAbstractRecur(manager, f, g, cube); 00103 } while (manager->reordered == 1); 00104 return(res); 00105 00106 } /* end of Cudd_bddAndAbstract */
Function********************************************************************
Synopsis [Takes the AND of two BDDs and simultaneously abstracts the variables in cube.]
Description [Takes the AND of two BDDs and simultaneously abstracts the variables in cube. The variables are existentially abstracted. Returns a pointer to the result is successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddAndAbstract]
Definition at line 129 of file cuddAndAbs.c.
00134 { 00135 DdNode *F, *ft, *fe, *G, *gt, *ge; 00136 DdNode *one, *zero, *r, *t, *e; 00137 unsigned int topf, topg, topcube, top, index; 00138 00139 statLine(manager); 00140 one = DD_ONE(manager); 00141 zero = Cudd_Not(one); 00142 00143 /* Terminal cases. */ 00144 if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); 00145 if (f == one && g == one) return(one); 00146 00147 if (cube == one) { 00148 return(cuddBddAndRecur(manager, f, g)); 00149 } 00150 if (f == one || f == g) { 00151 return(cuddBddExistAbstractRecur(manager, g, cube)); 00152 } 00153 if (g == one) { 00154 return(cuddBddExistAbstractRecur(manager, f, cube)); 00155 } 00156 /* At this point f, g, and cube are not constant. */ 00157 00158 if (f > g) { /* Try to increase cache efficiency. */ 00159 DdNode *tmp = f; 00160 f = g; 00161 g = tmp; 00162 } 00163 00164 /* Here we can skip the use of cuddI, because the operands are known 00165 ** to be non-constant. 00166 */ 00167 F = Cudd_Regular(f); 00168 G = Cudd_Regular(g); 00169 topf = manager->perm[F->index]; 00170 topg = manager->perm[G->index]; 00171 top = ddMin(topf, topg); 00172 topcube = manager->perm[cube->index]; 00173 00174 while (topcube < top) { 00175 cube = cuddT(cube); 00176 if (cube == one) { 00177 return(cuddBddAndRecur(manager, f, g)); 00178 } 00179 topcube = manager->perm[cube->index]; 00180 } 00181 /* Now, topcube >= top. */ 00182 00183 /* Check cache. */ 00184 if (F->ref != 1 || G->ref != 1) { 00185 r = cuddCacheLookup(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube); 00186 if (r != NULL) { 00187 return(r); 00188 } 00189 } 00190 00191 if (topf == top) { 00192 index = F->index; 00193 ft = cuddT(F); 00194 fe = cuddE(F); 00195 if (Cudd_IsComplement(f)) { 00196 ft = Cudd_Not(ft); 00197 fe = Cudd_Not(fe); 00198 } 00199 } else { 00200 index = G->index; 00201 ft = fe = f; 00202 } 00203 00204 if (topg == top) { 00205 gt = cuddT(G); 00206 ge = cuddE(G); 00207 if (Cudd_IsComplement(g)) { 00208 gt = Cudd_Not(gt); 00209 ge = Cudd_Not(ge); 00210 } 00211 } else { 00212 gt = ge = g; 00213 } 00214 00215 if (topcube == top) { /* quantify */ 00216 DdNode *Cube = cuddT(cube); 00217 t = cuddBddAndAbstractRecur(manager, ft, gt, Cube); 00218 if (t == NULL) return(NULL); 00219 /* Special case: 1 OR anything = 1. Hence, no need to compute 00220 ** the else branch if t is 1. Likewise t + t * anything == t. 00221 ** Notice that t == fe implies that fe does not depend on the 00222 ** variables in Cube. Likewise for t == ge. 00223 */ 00224 if (t == one || t == fe || t == ge) { 00225 if (F->ref != 1 || G->ref != 1) 00226 cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, 00227 f, g, cube, t); 00228 return(t); 00229 } 00230 cuddRef(t); 00231 /* Special case: t + !t * anything == t + anything. */ 00232 if (t == Cudd_Not(fe)) { 00233 e = cuddBddExistAbstractRecur(manager, ge, Cube); 00234 } else if (t == Cudd_Not(ge)) { 00235 e = cuddBddExistAbstractRecur(manager, fe, Cube); 00236 } else { 00237 e = cuddBddAndAbstractRecur(manager, fe, ge, Cube); 00238 } 00239 if (e == NULL) { 00240 Cudd_IterDerefBdd(manager, t); 00241 return(NULL); 00242 } 00243 if (t == e) { 00244 r = t; 00245 cuddDeref(t); 00246 } else { 00247 cuddRef(e); 00248 r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e)); 00249 if (r == NULL) { 00250 Cudd_IterDerefBdd(manager, t); 00251 Cudd_IterDerefBdd(manager, e); 00252 return(NULL); 00253 } 00254 r = Cudd_Not(r); 00255 cuddRef(r); 00256 Cudd_DelayedDerefBdd(manager, t); 00257 Cudd_DelayedDerefBdd(manager, e); 00258 cuddDeref(r); 00259 } 00260 } else { 00261 t = cuddBddAndAbstractRecur(manager, ft, gt, cube); 00262 if (t == NULL) return(NULL); 00263 cuddRef(t); 00264 e = cuddBddAndAbstractRecur(manager, fe, ge, cube); 00265 if (e == NULL) { 00266 Cudd_IterDerefBdd(manager, t); 00267 return(NULL); 00268 } 00269 if (t == e) { 00270 r = t; 00271 cuddDeref(t); 00272 } else { 00273 cuddRef(e); 00274 if (Cudd_IsComplement(t)) { 00275 r = cuddUniqueInter(manager, (int) index, 00276 Cudd_Not(t), Cudd_Not(e)); 00277 if (r == NULL) { 00278 Cudd_IterDerefBdd(manager, t); 00279 Cudd_IterDerefBdd(manager, e); 00280 return(NULL); 00281 } 00282 r = Cudd_Not(r); 00283 } else { 00284 r = cuddUniqueInter(manager,(int)index,t,e); 00285 if (r == NULL) { 00286 Cudd_IterDerefBdd(manager, t); 00287 Cudd_IterDerefBdd(manager, e); 00288 return(NULL); 00289 } 00290 } 00291 cuddDeref(e); 00292 cuddDeref(t); 00293 } 00294 } 00295 00296 if (F->ref != 1 || G->ref != 1) 00297 cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube, r); 00298 return (r); 00299 00300 } /* end of cuddBddAndAbstractRecur */
char rcsid [] DD_UNUSED = "$Id: cuddAndAbs.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $" [static] |
CFile***********************************************************************
FileName [cuddAndAbs.c]
PackageName [cudd]
Synopsis [Combined AND and existential abstraction for BDDs]
Description [External procedures included in this module:
Internal procedures included in this module:
]
Author [Fabio Somenzi]
Copyright [This file was created at the University of Colorado at Boulder. The University of Colorado at Boulder makes no warranty about the suitability of this software for any purpose. It is presented on an AS IS basis.]
Definition at line 51 of file cuddAndAbs.c.