VIS
|
00001 00036 #include "imgInt.h" 00037 00038 static char rcsid[] UNUSED = "$Id: imgTfmBwd.c,v 1.29 2002/08/18 04:47:07 fabio Exp $"; 00039 00040 /*---------------------------------------------------------------------------*/ 00041 /* Constant declarations */ 00042 /*---------------------------------------------------------------------------*/ 00043 00044 /*---------------------------------------------------------------------------*/ 00045 /* Type declarations */ 00046 /*---------------------------------------------------------------------------*/ 00047 00048 /*---------------------------------------------------------------------------*/ 00049 /* Structure declarations */ 00050 /*---------------------------------------------------------------------------*/ 00051 00052 /*---------------------------------------------------------------------------*/ 00053 /* Variable declarations */ 00054 /*---------------------------------------------------------------------------*/ 00055 00056 /*---------------------------------------------------------------------------*/ 00057 /* Macro declarations */ 00058 /*---------------------------------------------------------------------------*/ 00059 00062 /*---------------------------------------------------------------------------*/ 00063 /* Static function prototypes */ 00064 /*---------------------------------------------------------------------------*/ 00065 00066 static bdd_t * PreImageByDomainCofactoring(ImgTfmInfo_t *info, array_t *delta, bdd_t *image, array_t *relationArray, mdd_t *cofactorCube, mdd_t *abstractCube, int splitMethod, int turnDepth, int depth); 00067 static mdd_t * PreImageByStaticDomainCofactoring(ImgTfmInfo_t *info, array_t *vector, mdd_t *from, array_t *relationArray, int turnDepth, int depth); 00068 static bdd_t * PreImageByConstraintCofactoring(ImgTfmInfo_t *info, array_t *delta, bdd_t *image, int splitMethod, int turnDepth, int depth); 00069 static mdd_t * PreImageBySubstitution(ImgTfmInfo_t *info, array_t *vector, mdd_t *from); 00070 static bdd_t * PreImageMakeVectorCanonical(ImgTfmInfo_t *info, array_t *vector, bdd_t *image, array_t *relationArray, array_t **newVector, array_t **newRelationArray, mdd_t **cofactorCube, mdd_t **abstractCube); 00071 static bdd_t * PreImageMakeRelationCanonical(ImgTfmInfo_t *info, array_t *vector, bdd_t *image, array_t *relationArray, array_t **newVector, array_t **newRelationArray); 00072 static bdd_t * PreImageDeleteOneComponent(ImgTfmInfo_t *info, array_t *delta, int index, array_t **newDelta); 00073 static int PreImageChooseSplitVar(ImgTfmInfo_t *info, array_t *delta, bdd_t *img, int splitMethod, int split); 00074 static mdd_t * DomainCofactoring(ImgTfmInfo_t *info, array_t *vector, mdd_t *from, array_t *relationArray, mdd_t *c, array_t **newVector, array_t **newRelationArray, mdd_t **cofactorCube, mdd_t **abstractCube); 00075 static int CheckPreImageVector(ImgTfmInfo_t *info, array_t *vector, mdd_t *image); 00076 00080 /*---------------------------------------------------------------------------*/ 00081 /* Definition of exported functions */ 00082 /*---------------------------------------------------------------------------*/ 00083 00084 00085 /*---------------------------------------------------------------------------*/ 00086 /* Definition of internal functions */ 00087 /*---------------------------------------------------------------------------*/ 00088 00089 00099 bdd_t * 00100 ImgTfmPreImage(ImgTfmInfo_t *info, bdd_t *image) 00101 { 00102 bdd_t *preImg, *pre; 00103 int turnDepth; 00104 bdd_t *refResult, *one; 00105 array_t *relationArray; 00106 int partial; 00107 bdd_t *from; 00108 array_t *vector; 00109 00110 if (bdd_is_tautology(image, 1)) { 00111 preImg = mdd_one(info->manager); 00112 return(preImg); 00113 } else if (bdd_is_tautology(image, 0)) { 00114 preImg = mdd_zero(info->manager); 00115 return(preImg); 00116 } 00117 00118 info->maxIntermediateSize = 0; 00119 if (info->buildTR) { 00120 if (info->option->preSplitMethod == 4 && 00121 info->option->preSplitMaxDepth < 0 && 00122 info->option->buildPartialTR == FALSE && 00123 info->preKeepPiInTr == FALSE && 00124 info->option->preCanonical == FALSE) { 00125 mdd_t *range; 00126 range = ImgSubstitute(image, info->functionData, Img_D2R_c); 00127 preImg = ImgBddLinearAndSmooth(info->manager, range, 00128 info->bwdClusteredRelationArray, 00129 info->bwdArraySmoothVarBddArray, 00130 info->bwdSmoothVarCubeArray, 00131 info->option->verbosity); 00132 mdd_free(range); 00133 return(preImg); 00134 } 00135 relationArray = mdd_array_duplicate(info->bwdClusteredRelationArray); 00136 } else 00137 relationArray = NIL(array_t); 00138 00139 one = mdd_one(info->manager); 00140 00141 vector = info->vector; 00142 from = image; 00143 00144 partial = 0; 00145 if (info->option->preSplitMethod == 0) { 00146 preImg = PreImageByDomainCofactoring(info, vector, from, 00147 NIL(array_t), NIL(mdd_t), NIL(mdd_t), 00148 info->option->preSplitMethod, 0, 0); 00149 } else if (info->option->preSplitMethod == 1) { 00150 preImg = PreImageByConstraintCofactoring(info, vector, from, 00151 info->option->preSplitMethod, 00152 0, 0); 00153 } else if (info->option->preSplitMethod == 3) { 00154 preImg = PreImageBySubstitution(info, vector, from); 00155 } else { 00156 turnDepth = info->option->turnDepth; 00157 if (turnDepth == 0) { 00158 if (info->option->preSplitMethod == 2) { 00159 preImg = PreImageByConstraintCofactoring(info, vector, from, 00160 info->option->preSplitMethod, 00161 turnDepth, 0); 00162 } else 00163 preImg = ImgPreImageByHybrid(info, vector, from); 00164 } else if (info->option->preSplitMethod == 2) { 00165 preImg = PreImageByDomainCofactoring(info, vector, from, 00166 relationArray, 00167 NIL(mdd_t), NIL(mdd_t), 00168 info->option->preSplitMethod, 00169 turnDepth, 0); 00170 } else { 00171 if (info->buildTR) { 00172 if (info->buildTR == 2) { 00173 if (info->buildPartialTR) { 00174 preImg = PreImageByStaticDomainCofactoring(info, vector, 00175 from, relationArray, 00176 turnDepth, 0); 00177 partial = 1; 00178 } else { 00179 preImg = PreImageByStaticDomainCofactoring(info, NIL(array_t), 00180 from, relationArray, 00181 turnDepth, 0); 00182 } 00183 } else if (info->option->delayedSplit) { 00184 preImg = PreImageByDomainCofactoring(info, vector, from, 00185 relationArray, one, one, 00186 info->option->preSplitMethod, 00187 turnDepth, 0); 00188 } else { 00189 preImg = PreImageByDomainCofactoring(info, vector, from, 00190 relationArray, 00191 NIL(mdd_t), NIL(mdd_t), 00192 info->option->preSplitMethod, 00193 turnDepth, 0); 00194 } 00195 } else { 00196 preImg = PreImageByDomainCofactoring(info, vector, from, 00197 relationArray, 00198 NIL(mdd_t), NIL(mdd_t), 00199 info->option->preSplitMethod, 00200 turnDepth, 0); 00201 } 00202 } 00203 } 00204 mdd_free(one); 00205 00206 if (info->option->debug) { 00207 if (info->buildTR == 2) { 00208 refResult = ImgPreImageByHybridWithStaticSplit(info, NIL(array_t), 00209 image, relationArray, 00210 NIL(mdd_t), NIL(mdd_t)); 00211 } else { 00212 if (partial) { 00213 refResult = ImgPreImageByHybridWithStaticSplit(info, info->vector, 00214 image, relationArray, 00215 NIL(mdd_t), NIL(mdd_t)); 00216 } else 00217 refResult = ImgPreImageByHybrid(info, info->vector, image); 00218 } 00219 assert(mdd_equal_mod_care_set_array(refResult, preImg, 00220 info->toCareSetArray)); 00221 mdd_free(refResult); 00222 } 00223 00224 if (relationArray) 00225 mdd_array_free(relationArray); 00226 00227 if (info->preCache && info->option->autoFlushCache == 1) 00228 ImgFlushCache(info->preCache); 00229 if (info->preKeepPiInTr == TRUE) { 00230 if (info->functionData->quantifyCube) 00231 pre = bdd_smooth_with_cube(preImg, info->functionData->quantifyCube); 00232 else 00233 pre = bdd_smooth(preImg, info->functionData->quantifyBddVars); 00234 mdd_free(preImg); 00235 } else 00236 pre = preImg; 00237 if (info->option->verbosity) { 00238 fprintf(vis_stdout, 00239 "** tfm info: max BDD size for intermediate product = %d\n", 00240 info->maxIntermediateSize); 00241 } 00242 return(pre); 00243 } 00244 00245 00246 /*---------------------------------------------------------------------------*/ 00247 /* Definition of static functions */ 00248 /*---------------------------------------------------------------------------*/ 00249 00250 00260 static bdd_t * 00261 PreImageByDomainCofactoring(ImgTfmInfo_t *info, array_t *delta, bdd_t *image, 00262 array_t *relationArray, 00263 mdd_t *cofactorCube, mdd_t *abstractCube, 00264 int splitMethod, int turnDepth, int depth) 00265 { 00266 array_t *newDelta, *tmpDelta, *vectorT, *vectorE; 00267 bdd_t *preImg, *preImgT, *preImgE, *imgT, *imgE, *newImg, *tmpImg; 00268 int split; 00269 bdd_t *var, *varNot, *refResult; 00270 int nRecur; 00271 array_t *relationArrayT, *relationArrayE; 00272 array_t *newRelationArray, *tmpRelationArray; 00273 mdd_t *cofactorCubeT, *cofactorCubeE; 00274 mdd_t *abstractCubeT, *abstractCubeE; 00275 mdd_t *newCofactorCube, *newAbstractCube; 00276 mdd_t *cofactor, *abstract; 00277 mdd_t *essentialCube, *tmp; 00278 int findEssential; 00279 int foundEssentialDepth, foundEssentialDepthT, foundEssentialDepthE; 00280 int turnFlag, size; 00281 mdd_t *saveCareSet = NIL(mdd_t); 00282 00283 newRelationArray = NIL(array_t); 00284 00285 if (info->option->checkEquivalence && relationArray) { 00286 assert(ImgCheckEquivalence(info, delta, relationArray, 00287 cofactorCube, abstractCube, 1)); 00288 } 00289 00290 info->nRecursionB++; 00291 if (info->option->debug) { 00292 if (relationArray) { 00293 refResult = ImgPreImageByHybrid(info, delta, image); 00294 preImg = ImgPreImageByHybridWithStaticSplit(info, NIL(array_t), image, 00295 relationArray, 00296 cofactorCube, abstractCube); 00297 tmp = refResult; 00298 refResult = mdd_and(tmp, info->debugCareSet, 1, 1); 00299 mdd_free(tmp); 00300 tmp = preImg; 00301 preImg = mdd_and(tmp, info->debugCareSet, 1, 1); 00302 mdd_free(tmp); 00303 assert(mdd_equal_mod_care_set_array(refResult, preImg, 00304 info->toCareSetArray)); 00305 mdd_free(refResult); 00306 mdd_free(preImg); 00307 } 00308 } 00309 00310 if (info->nIntermediateVars) 00311 size = ImgVectorFunctionSize(delta); 00312 else 00313 size = array_n(delta); 00314 if (size == 1) { 00315 preImg = PreImageBySubstitution(info, delta, image); 00316 info->averageDepthB = (info->averageDepthB * (float)info->nLeavesB + 00317 (float)depth) / (float)(info->nLeavesB + 1); 00318 if (depth > info->maxDepthB) 00319 info->maxDepthB = depth; 00320 info->nLeavesB++; 00321 info->foundEssentialDepth = info->option->maxEssentialDepth; 00322 return(preImg); 00323 } 00324 00325 if (info->option->findEssential) { 00326 if (info->option->findEssential == 1) 00327 findEssential = 1; 00328 else { 00329 if (depth >= info->lastFoundEssentialDepth) 00330 findEssential = 1; 00331 else 00332 findEssential = 0; 00333 } 00334 } else 00335 findEssential = 0; 00336 if (findEssential) { 00337 essentialCube = bdd_find_essential_cube(image); 00338 00339 if (!bdd_is_tautology(essentialCube, 1)) { 00340 info->averageFoundEssential = (info->averageFoundEssential * 00341 (float)info->nFoundEssentials + (float)(bdd_size(essentialCube) - 1)) / 00342 (float)(info->nFoundEssentials + 1); 00343 info->averageFoundEssentialDepth = (info->averageFoundEssentialDepth * 00344 (float)info->nFoundEssentials + (float)depth) / 00345 (float)(info->nFoundEssentials + 1); 00346 if (info->nFoundEssentials == 0 || depth < info->topFoundEssentialDepth) 00347 info->topFoundEssentialDepth = depth; 00348 if (info->option->printEssential && depth < IMG_TF_MAX_PRINT_DEPTH) 00349 info->foundEssentials[depth]++; 00350 info->nFoundEssentials++; 00351 if (info->option->delayedSplit && relationArray) { 00352 tmpRelationArray = relationArray; 00353 tmpImg = ImgVectorMinimize(info, delta, essentialCube, image, 00354 tmpRelationArray, &tmpDelta, NIL(mdd_t *), 00355 NIL(array_t *), &cofactor, &abstract); 00356 if (bdd_is_tautology(cofactor, 1)) 00357 newCofactorCube = cofactorCube; 00358 else 00359 newCofactorCube = mdd_and(cofactorCube, cofactor, 1, 1); 00360 mdd_free(cofactor); 00361 if (bdd_is_tautology(abstract, 1)) 00362 newAbstractCube = abstractCube; 00363 else 00364 newAbstractCube = mdd_and(abstractCube, abstract, 1, 1); 00365 mdd_free(abstract); 00366 } else { 00367 if (relationArray) 00368 tmpRelationArray = mdd_array_duplicate(relationArray); 00369 else 00370 tmpRelationArray = relationArray; 00371 tmpImg = ImgVectorMinimize(info, delta, essentialCube, image, 00372 tmpRelationArray, &tmpDelta, NIL(mdd_t *), 00373 NIL(array_t *), NIL(mdd_t *), NIL(mdd_t *)); 00374 newCofactorCube = cofactorCube; 00375 newAbstractCube = abstractCube; 00376 } 00377 foundEssentialDepth = depth; 00378 } else { 00379 tmpDelta = delta; 00380 tmpRelationArray = relationArray; 00381 tmpImg = image; 00382 newCofactorCube = cofactorCube; 00383 newAbstractCube = abstractCube; 00384 foundEssentialDepth = info->option->maxEssentialDepth; 00385 } 00386 mdd_free(essentialCube); 00387 foundEssentialDepthT = info->option->maxEssentialDepth; 00388 foundEssentialDepthE = info->option->maxEssentialDepth; 00389 } else { 00390 tmpDelta = delta; 00391 tmpRelationArray = relationArray; 00392 tmpImg = image; 00393 newCofactorCube = cofactorCube; 00394 newAbstractCube = abstractCube; 00395 /* To remove compiler warnings */ 00396 foundEssentialDepth = -1; 00397 foundEssentialDepthT = -1; 00398 foundEssentialDepthE = -1; 00399 } 00400 00401 if (!info->option->preCanonical) { 00402 newImg = tmpImg; 00403 newDelta = tmpDelta; 00404 newRelationArray = tmpRelationArray; 00405 } else if (info->option->delayedSplit && relationArray) { 00406 newImg = PreImageMakeVectorCanonical(info, tmpDelta, tmpImg, 00407 tmpRelationArray, &newDelta, 00408 &newRelationArray, 00409 &cofactor, &abstract); 00410 if (!bdd_is_tautology(cofactor, 1)) { 00411 if (newCofactorCube == cofactorCube) 00412 newCofactorCube = mdd_and(cofactorCube, cofactor, 1, 1); 00413 else { 00414 tmp = newCofactorCube; 00415 newCofactorCube = mdd_and(tmp, cofactor, 1, 1); 00416 mdd_free(tmp); 00417 } 00418 } 00419 mdd_free(cofactor); 00420 if (!bdd_is_tautology(abstract, 1)) { 00421 if (newAbstractCube == abstractCube) 00422 newAbstractCube = mdd_and(abstractCube, abstract, 1, 1); 00423 else { 00424 tmp = newAbstractCube; 00425 newAbstractCube = mdd_and(tmp, abstract, 1, 1); 00426 mdd_free(tmp); 00427 } 00428 } 00429 mdd_free(abstract); 00430 } else { 00431 newImg = PreImageMakeVectorCanonical(info, tmpDelta, tmpImg, 00432 tmpRelationArray, &newDelta, 00433 &newRelationArray, 00434 NIL(mdd_t *), NIL(mdd_t *)); 00435 } 00436 if (tmpDelta != delta) 00437 ImgVectorFree(tmpDelta); 00438 if (tmpImg != image) 00439 mdd_free(tmpImg); 00440 if (tmpRelationArray && tmpRelationArray != relationArray && 00441 tmpRelationArray != newRelationArray) { 00442 mdd_array_free(tmpRelationArray); 00443 } 00444 00445 if (info->option->debug) { 00446 if (relationArray) { 00447 refResult = ImgPreImageByHybrid(info, newDelta, newImg); 00448 preImg = ImgPreImageByHybridWithStaticSplit(info, NIL(array_t), newImg, 00449 newRelationArray, 00450 newCofactorCube, 00451 newAbstractCube); 00452 tmp = refResult; 00453 refResult = mdd_and(tmp, info->debugCareSet, 1, 1); 00454 mdd_free(tmp); 00455 tmp = preImg; 00456 preImg = mdd_and(tmp, info->debugCareSet, 1, 1); 00457 mdd_free(tmp); 00458 assert(mdd_equal_mod_care_set_array(refResult, preImg, 00459 info->toCareSetArray)); 00460 mdd_free(refResult); 00461 mdd_free(preImg); 00462 } 00463 } 00464 00465 if (bdd_is_tautology(newImg, 1) || bdd_is_tautology(newImg, 0)) { 00466 info->averageDepthB = (info->averageDepthB * (float)info->nLeavesB + 00467 (float)depth) / (float)(info->nLeavesB + 1); 00468 if (depth > info->maxDepthB) 00469 info->maxDepthB = depth; 00470 info->nLeavesB++; 00471 if (info->option->debug) { 00472 refResult = ImgPreImageByHybrid(info, newDelta, newImg); 00473 tmp = refResult; 00474 refResult = mdd_and(tmp, info->debugCareSet, 1, 1); 00475 mdd_free(tmp); 00476 tmp = mdd_and(newImg, info->debugCareSet, 1, 1); 00477 assert(mdd_equal_mod_care_set_array(refResult, tmp, 00478 info->toCareSetArray)); 00479 mdd_free(refResult); 00480 mdd_free(tmp); 00481 } 00482 if (newDelta != delta) 00483 ImgVectorFree(newDelta); 00484 if (relationArray && newRelationArray != relationArray) 00485 mdd_array_free(newRelationArray); 00486 if (newCofactorCube && newCofactorCube != cofactorCube) 00487 mdd_free(newCofactorCube); 00488 if (newAbstractCube && newAbstractCube != abstractCube) 00489 mdd_free(newAbstractCube); 00490 if (findEssential) 00491 info->foundEssentialDepth = foundEssentialDepth; 00492 return(newImg); 00493 } 00494 if (array_n(newDelta) <= 1) { 00495 if (array_n(newDelta) == 0) 00496 preImg = newImg; 00497 else { 00498 assert(array_n(newDelta) == 1); 00499 preImg = PreImageBySubstitution(info, newDelta, newImg); 00500 mdd_free(newImg); 00501 } 00502 info->averageDepthB = (info->averageDepthB * (float)info->nLeavesB + 00503 (float)depth) / (float)(info->nLeavesB + 1); 00504 if (depth > info->maxDepthB) 00505 info->maxDepthB = depth; 00506 info->nLeavesB++; 00507 if (info->option->debug) { 00508 refResult = ImgPreImageByHybrid(info, delta, image); 00509 tmp = refResult; 00510 refResult = mdd_and(tmp, info->debugCareSet, 1, 1); 00511 mdd_free(tmp); 00512 tmp = mdd_and(preImg, info->debugCareSet, 1, 1); 00513 assert(mdd_equal_mod_care_set_array(refResult, tmp, 00514 info->toCareSetArray)); 00515 mdd_free(refResult); 00516 mdd_free(tmp); 00517 } 00518 if (newDelta != delta) 00519 ImgVectorFree(newDelta); 00520 if (relationArray && newRelationArray != relationArray) 00521 mdd_array_free(newRelationArray); 00522 if (newCofactorCube && newCofactorCube != cofactorCube) 00523 mdd_free(newCofactorCube); 00524 if (newAbstractCube && newAbstractCube != abstractCube) 00525 mdd_free(newAbstractCube); 00526 if (findEssential) 00527 info->foundEssentialDepth = foundEssentialDepth; 00528 return(preImg); 00529 } 00530 00531 if (info->preCache) { 00532 preImg = ImgCacheLookupTable(info, info->preCache, newDelta, newImg); 00533 if (preImg) { 00534 info->averageDepthB = (info->averageDepthB * (float)info->nLeavesB + 00535 (float)depth) / (float)(info->nLeavesB + 1); 00536 if (depth > info->maxDepthB) 00537 info->maxDepthB = depth; 00538 info->nLeavesB++; 00539 if (info->option->debug) { 00540 refResult = ImgPreImageByHybrid(info, newDelta, newImg); 00541 tmp = refResult; 00542 refResult = mdd_and(tmp, info->debugCareSet, 1, 1); 00543 mdd_free(tmp); 00544 tmp = mdd_and(preImg, info->debugCareSet, 1, 1); 00545 assert(mdd_equal_mod_care_set_array(refResult, tmp, 00546 info->toCareSetArray)); 00547 mdd_free(refResult); 00548 mdd_free(tmp); 00549 } 00550 if (newDelta != delta) 00551 ImgVectorFree(newDelta); 00552 if (newImg != image) 00553 mdd_free(newImg); 00554 if (relationArray && newRelationArray != relationArray) 00555 mdd_array_free(newRelationArray); 00556 if (newCofactorCube && newCofactorCube != cofactorCube) 00557 mdd_free(newCofactorCube); 00558 if (newAbstractCube && newAbstractCube != abstractCube) 00559 mdd_free(newAbstractCube); 00560 if (findEssential) 00561 info->foundEssentialDepth = foundEssentialDepth; 00562 return(preImg); 00563 } 00564 } 00565 00566 turnFlag = 0; 00567 if (splitMethod == 4 && turnDepth == -1) { 00568 if (depth < info->option->preSplitMinDepth) { 00569 info->nSplitsB++; 00570 turnFlag = 0; 00571 } else if (depth > info->option->preSplitMaxDepth) { 00572 info->nConjoinsB++; 00573 turnFlag = 1; 00574 } else { 00575 turnFlag = ImgDecideSplitOrConjoin(info, newDelta, newImg, 1, 00576 newRelationArray, newCofactorCube, 00577 newAbstractCube, 0, depth); 00578 } 00579 } else { 00580 if (depth == turnDepth) 00581 turnFlag = 1; 00582 else 00583 turnFlag = 0; 00584 } 00585 if (turnFlag) { 00586 if (splitMethod == 2) { 00587 preImg = PreImageByConstraintCofactoring(info, newDelta, newImg, 00588 info->option->preSplitMethod, 00589 0, depth + 1); 00590 } else { 00591 if (relationArray) { 00592 preImg = ImgPreImageByHybridWithStaticSplit(info, NIL(array_t), newImg, 00593 newRelationArray, 00594 newCofactorCube, 00595 newAbstractCube); 00596 } else 00597 preImg = ImgPreImageByHybrid(info, newDelta, newImg); 00598 } 00599 if (info->option->debug) { 00600 refResult = ImgPreImageByHybrid(info, newDelta, newImg); 00601 tmp = refResult; 00602 refResult = mdd_and(tmp, info->debugCareSet, 1, 1); 00603 mdd_free(tmp); 00604 tmp = mdd_and(preImg, info->debugCareSet, 1, 1); 00605 assert(mdd_equal_mod_care_set_array(refResult, tmp, 00606 info->toCareSetArray)); 00607 mdd_free(refResult); 00608 mdd_free(tmp); 00609 } 00610 if (splitMethod == 4) { 00611 if (info->preCache) 00612 ImgCacheInsertTable(info->preCache, newDelta, newImg, mdd_dup(preImg)); 00613 else { 00614 if (newDelta != delta) 00615 ImgVectorFree(newDelta); 00616 if (newImg != image) 00617 mdd_free(newImg); 00618 } 00619 info->averageDepthB = (info->averageDepthB * (float)info->nLeavesB + 00620 (float)depth) / (float)(info->nLeavesB + 1); 00621 if (depth > info->maxDepthB) 00622 info->maxDepthB = depth; 00623 info->nLeavesB++; 00624 } else { 00625 if (newDelta != delta) 00626 ImgVectorFree(newDelta); 00627 if (newImg != image) 00628 mdd_free(newImg); 00629 } 00630 if (relationArray && newRelationArray != relationArray) 00631 mdd_array_free(newRelationArray); 00632 if (newCofactorCube && newCofactorCube != cofactorCube) 00633 mdd_free(newCofactorCube); 00634 if (newAbstractCube && newAbstractCube != abstractCube) 00635 mdd_free(newAbstractCube); 00636 info->nTurnsB++; 00637 if (findEssential) 00638 info->foundEssentialDepth = foundEssentialDepth; 00639 return(preImg); 00640 } 00641 00642 split = PreImageChooseSplitVar(info, newDelta, newImg, 00643 0, info->option->preInputSplit); 00644 00645 /* No more present state variable to split */ 00646 if (split == -1) { 00647 if (info->option->preDcLeafMethod == 0 || 00648 info->option->preDcLeafMethod == 2) { 00649 if (info->option->preDcLeafMethod == 0) 00650 preImg = PreImageBySubstitution(info, newDelta, newImg); 00651 else if (relationArray) { 00652 preImg = ImgPreImageByHybridWithStaticSplit(info, NIL(array_t), newImg, 00653 newRelationArray, 00654 newCofactorCube, 00655 newAbstractCube); 00656 } else 00657 preImg = ImgPreImageByHybrid(info, newDelta, newImg); 00658 if (info->preCache) 00659 ImgCacheInsertTable(info->preCache, newDelta, newImg, mdd_dup(preImg)); 00660 info->averageDepthB = (info->averageDepthB * (float)info->nLeavesB + 00661 (float)depth) / (float)(info->nLeavesB + 1); 00662 if (depth > info->maxDepthB) 00663 info->maxDepthB = depth; 00664 info->nLeavesB++; 00665 } else { 00666 preImg = PreImageByConstraintCofactoring(info, newDelta, newImg, 00667 splitMethod, turnDepth, 00668 depth + 1); 00669 info->nRecursionB--; 00670 } 00671 if (splitMethod == 0) 00672 info->nTurnsB++; 00673 if (info->option->debug) { 00674 refResult = ImgPreImageByHybrid(info, newDelta, newImg); 00675 tmp = refResult; 00676 refResult = mdd_and(tmp, info->debugCareSet, 1, 1); 00677 mdd_free(tmp); 00678 tmp = mdd_and(preImg, info->debugCareSet, 1, 1); 00679 assert(mdd_equal_mod_care_set_array(refResult, tmp, 00680 info->toCareSetArray)); 00681 mdd_free(refResult); 00682 mdd_free(tmp); 00683 } 00684 if (info->option->preDcLeafMethod != 0 || !info->preCache) { 00685 if (newDelta != delta) 00686 ImgVectorFree(newDelta); 00687 if (newImg != image) 00688 mdd_free(newImg); 00689 } 00690 if (relationArray && newRelationArray != relationArray) 00691 mdd_array_free(newRelationArray); 00692 if (newCofactorCube && newCofactorCube != cofactorCube) 00693 mdd_free(newCofactorCube); 00694 if (newAbstractCube && newAbstractCube != abstractCube) 00695 mdd_free(newAbstractCube); 00696 if (findEssential) 00697 info->foundEssentialDepth = foundEssentialDepth; 00698 return(preImg); 00699 } 00700 00701 var = bdd_var_with_index(info->manager, split); 00702 varNot = mdd_not(var); 00703 if (info->option->delayedSplit && relationArray) { 00704 imgT = DomainCofactoring(info, newDelta, newImg, newRelationArray, var, 00705 &vectorT, &relationArrayT, &cofactor, &abstract); 00706 if (bdd_is_tautology(cofactor, 1)) 00707 cofactorCubeT = newCofactorCube; 00708 else 00709 cofactorCubeT = mdd_and(newCofactorCube, cofactor, 1, 1); 00710 mdd_free(cofactor); 00711 if (bdd_is_tautology(abstract, 1)) 00712 abstractCubeT = newAbstractCube; 00713 else 00714 abstractCubeT = mdd_and(newAbstractCube, abstract, 1, 1); 00715 mdd_free(abstract); 00716 00717 imgE = DomainCofactoring(info, newDelta, newImg, newRelationArray, varNot, 00718 &vectorE, &relationArrayE, &cofactor, &abstract); 00719 if (bdd_is_tautology(cofactor, 1)) 00720 cofactorCubeE = newCofactorCube; 00721 else 00722 cofactorCubeE = mdd_and(newCofactorCube, cofactor, 1, 1); 00723 mdd_free(cofactor); 00724 if (bdd_is_tautology(abstract, 1)) 00725 abstractCubeE = newAbstractCube; 00726 else 00727 abstractCubeE = mdd_and(newAbstractCube, abstract, 1, 1); 00728 mdd_free(abstract); 00729 } else { 00730 imgT = DomainCofactoring(info, newDelta, newImg, newRelationArray, var, 00731 &vectorT, &relationArrayT, 00732 NIL(mdd_t *), NIL(mdd_t *)); 00733 cofactorCubeT = NIL(mdd_t); 00734 abstractCubeT = NIL(mdd_t); 00735 00736 imgE = DomainCofactoring(info, newDelta, newImg, newRelationArray, varNot, 00737 &vectorE, &relationArrayE, 00738 NIL(mdd_t *), NIL(mdd_t *)); 00739 cofactorCubeE = NIL(mdd_t); 00740 abstractCubeE = NIL(mdd_t); 00741 } 00742 if (relationArray && newRelationArray != relationArray) 00743 mdd_array_free(newRelationArray); 00744 mdd_free(varNot); 00745 00746 if (!info->preCache && !info->option->debug) { 00747 if (newDelta != delta) 00748 ImgVectorFree(newDelta); 00749 if (newImg != image) 00750 mdd_free(newImg); 00751 } 00752 00753 nRecur = 0; 00754 if (bdd_is_tautology(imgT, 1)) 00755 preImgT = mdd_one(info->manager); 00756 else if (bdd_is_tautology(imgT, 0)) 00757 preImgT = mdd_zero(info->manager); 00758 else { 00759 if (info->option->debug) { 00760 saveCareSet = info->debugCareSet; 00761 info->debugCareSet = mdd_and(saveCareSet, var, 1, 1); 00762 } 00763 preImgT = PreImageByDomainCofactoring(info, vectorT, imgT, relationArrayT, 00764 cofactorCubeT, abstractCubeT, 00765 splitMethod, turnDepth, 00766 depth + 1); 00767 if (info->option->debug) { 00768 mdd_free(info->debugCareSet); 00769 info->debugCareSet = saveCareSet; 00770 } 00771 if (findEssential) 00772 foundEssentialDepthT = info->foundEssentialDepth; 00773 nRecur++; 00774 } 00775 ImgVectorFree(vectorT); 00776 mdd_free(imgT); 00777 if (relationArrayT && relationArrayT != newRelationArray) 00778 mdd_array_free(relationArrayT); 00779 if (cofactorCubeT && cofactorCubeT != newCofactorCube) 00780 mdd_free(cofactorCubeT); 00781 if (abstractCubeT && abstractCubeT != newAbstractCube) 00782 mdd_free(abstractCubeT); 00783 00784 if (bdd_is_tautology(imgE, 1)) 00785 preImgE = mdd_one(info->manager); 00786 else if (bdd_is_tautology(imgE, 0)) 00787 preImgE = mdd_zero(info->manager); 00788 else { 00789 if (info->option->debug) { 00790 saveCareSet = info->debugCareSet; 00791 info->debugCareSet = mdd_and(saveCareSet, var, 1, 0); 00792 } 00793 preImgE = PreImageByDomainCofactoring(info, vectorE, imgE, relationArrayE, 00794 cofactorCubeE, abstractCubeE, 00795 splitMethod, turnDepth, 00796 depth + 1); 00797 if (info->option->debug) { 00798 mdd_free(info->debugCareSet); 00799 info->debugCareSet = saveCareSet; 00800 } 00801 if (findEssential) 00802 foundEssentialDepthE = info->foundEssentialDepth; 00803 nRecur++; 00804 } 00805 ImgVectorFree(vectorE); 00806 mdd_free(imgE); 00807 if (relationArrayE && relationArrayT != newRelationArray) 00808 mdd_array_free(relationArrayE); 00809 if (cofactorCubeE && cofactorCubeE != newCofactorCube) 00810 mdd_free(cofactorCubeE); 00811 if (abstractCubeE && abstractCubeE != newAbstractCube) 00812 mdd_free(abstractCubeE); 00813 if (newCofactorCube && newCofactorCube != cofactorCube) 00814 mdd_free(newCofactorCube); 00815 if (newAbstractCube && newAbstractCube != abstractCube) 00816 mdd_free(newAbstractCube); 00817 00818 preImg = bdd_ite(var, preImgT, preImgE, 1, 1, 1); 00819 if (info->option->verbosity) { 00820 size = bdd_size(preImg); 00821 if (size > info->maxIntermediateSize) 00822 info->maxIntermediateSize = size; 00823 if (info->option->printBddSize) { 00824 fprintf(vis_stdout, "** tfm info: bdd_ite(2,%d,%d) = %d\n", 00825 bdd_size(preImgT), bdd_size(preImgE), bdd_size(preImg)); 00826 } 00827 } 00828 mdd_free(var); 00829 mdd_free(preImgE); 00830 mdd_free(preImgT); 00831 00832 if (info->preCache) 00833 ImgCacheInsertTable(info->preCache, newDelta, newImg, mdd_dup(preImg)); 00834 00835 if (info->option->debug) { 00836 refResult = ImgPreImageByHybrid(info, newDelta, newImg); 00837 tmp = refResult; 00838 refResult = mdd_and(tmp, info->debugCareSet, 1, 1); 00839 mdd_free(tmp); 00840 tmp = mdd_and(preImg, info->debugCareSet, 1, 1); 00841 assert(mdd_equal_mod_care_set_array(refResult, tmp, 00842 info->toCareSetArray)); 00843 mdd_free(refResult); 00844 mdd_free(tmp); 00845 if (!info->preCache) { 00846 if (newDelta != delta) 00847 ImgVectorFree(newDelta); 00848 if (newImg != image) 00849 mdd_free(newImg); 00850 } 00851 } 00852 00853 if (nRecur == 0) { 00854 info->averageDepthB = (info->averageDepthB * (float)info->nLeavesB + 00855 (float)depth) / (float)(info->nLeavesB + 1); 00856 if (depth > info->maxDepthB) 00857 info->maxDepthB = depth; 00858 info->nLeavesB++; 00859 } 00860 00861 if (findEssential) { 00862 if (foundEssentialDepth == info->option->maxEssentialDepth) { 00863 if (foundEssentialDepthT < foundEssentialDepthE) 00864 foundEssentialDepth = foundEssentialDepthT; 00865 else 00866 foundEssentialDepth = foundEssentialDepthE; 00867 } 00868 info->foundEssentialDepth = foundEssentialDepth; 00869 } 00870 return(preImg); 00871 } 00872 00873 00883 static mdd_t * 00884 PreImageByStaticDomainCofactoring(ImgTfmInfo_t *info, array_t *vector, 00885 mdd_t *from, array_t *relationArray, 00886 int turnDepth, int depth) 00887 { 00888 array_t *vectorT, *vectorE, *newVector; 00889 mdd_t *resT, *resE, *res, *cubeT, *cubeE; 00890 mdd_t *fromT, *fromE, *newFrom, *tmpFrom; 00891 mdd_t *var, *varNot; 00892 array_t *relationArrayT, *relationArrayE; 00893 array_t *newRelationArray, *tmpRelationArray; 00894 int nRecur; 00895 mdd_t *essentialCube, *refResult; 00896 int findEssential; 00897 int foundEssentialDepth, foundEssentialDepthT, foundEssentialDepthE; 00898 int turnFlag, size; 00899 mdd_t *saveCareSet = NIL(mdd_t), *tmp; 00900 00901 info->nRecursionB++; 00902 00903 turnFlag = 0; 00904 if (turnDepth == -1) { 00905 if (depth < info->option->preSplitMinDepth) { 00906 info->nSplitsB++; 00907 turnFlag = 0; 00908 } else if (depth > info->option->preSplitMaxDepth) { 00909 info->nConjoinsB++; 00910 turnFlag = 1; 00911 } else { 00912 turnFlag = ImgDecideSplitOrConjoin(info, vector, from, 1, 00913 relationArray, NIL(mdd_t), 00914 NIL(mdd_t), 1, depth); 00915 } 00916 } else { 00917 if (depth == turnDepth) 00918 turnFlag = 1; 00919 else 00920 turnFlag = 0; 00921 } 00922 if (turnFlag) { 00923 res = ImgPreImageByHybridWithStaticSplit(info, vector, from, relationArray, 00924 NIL(mdd_t), NIL(mdd_t)); 00925 info->averageDepthB = (info->averageDepthB * (float)info->nLeavesB + 00926 (float)depth) / (float)(info->nLeavesB + 1); 00927 if (depth > info->maxDepthB) 00928 info->maxDepthB = depth; 00929 info->nLeavesB++; 00930 info->foundEssentialDepth = info->option->maxEssentialDepth; 00931 return(res); 00932 } 00933 00934 if (info->option->findEssential) { 00935 if (info->option->findEssential == 1) 00936 findEssential = 1; 00937 else { 00938 if (depth >= info->lastFoundEssentialDepth) 00939 findEssential = 1; 00940 else 00941 findEssential = 0; 00942 } 00943 } else 00944 findEssential = 0; 00945 if (findEssential) { 00946 essentialCube = bdd_find_essential_cube(from); 00947 00948 if (!bdd_is_tautology(essentialCube, 1)) { 00949 info->averageFoundEssential = (info->averageFoundEssential * 00950 (float)info->nFoundEssentials + (float)(bdd_size(essentialCube) - 1)) / 00951 (float)(info->nFoundEssentials + 1); 00952 info->averageFoundEssentialDepth = (info->averageFoundEssentialDepth * 00953 (float)info->nFoundEssentials + (float)depth) / 00954 (float)(info->nFoundEssentials + 1); 00955 if (info->nFoundEssentials == 0 || depth < info->topFoundEssentialDepth) 00956 info->topFoundEssentialDepth = depth; 00957 if (info->option->printEssential && depth < IMG_TF_MAX_PRINT_DEPTH) 00958 info->foundEssentials[depth]++; 00959 info->nFoundEssentials++; 00960 if (vector) { 00961 array_t *tmpVector; 00962 if (info->option->preCanonical) { 00963 tmpFrom = PreImageMakeRelationCanonical(info, vector, from, 00964 relationArray, &newVector, 00965 &newRelationArray); 00966 } else { 00967 tmpFrom = from; 00968 newVector = vector; 00969 newRelationArray = relationArray; 00970 } 00971 tmpVector = newVector; 00972 newFrom = ImgVectorMinimize(info, tmpVector, essentialCube, tmpFrom, 00973 newRelationArray, &newVector, NIL(mdd_t *), 00974 NIL(array_t *), NIL(mdd_t *), NIL(mdd_t *)); 00975 if (tmpVector != vector) 00976 ImgVectorFree(tmpVector); 00977 if (tmpFrom != from) 00978 mdd_free(tmpFrom); 00979 } else { 00980 tmpRelationArray = ImgGetCofactoredRelationArray(relationArray, 00981 essentialCube); 00982 if (info->option->preCanonical) { 00983 newFrom = PreImageMakeRelationCanonical(info, vector, from, 00984 tmpRelationArray, &newVector, 00985 &newRelationArray); 00986 mdd_array_free(tmpRelationArray); 00987 } else { 00988 newFrom = from; 00989 newVector = vector; 00990 newRelationArray = tmpRelationArray; 00991 } 00992 } 00993 foundEssentialDepth = depth; 00994 } else { 00995 if (info->option->preCanonical) { 00996 newFrom = PreImageMakeRelationCanonical(info, vector, from, 00997 relationArray, 00998 &newVector, &newRelationArray); 00999 } else { 01000 newFrom = from; 01001 newVector = vector; 01002 newRelationArray = relationArray; 01003 } 01004 foundEssentialDepth = info->option->maxEssentialDepth; 01005 } 01006 mdd_free(essentialCube); 01007 foundEssentialDepthT = info->option->maxEssentialDepth; 01008 foundEssentialDepthE = info->option->maxEssentialDepth; 01009 } else { 01010 if (info->option->preCanonical) { 01011 newFrom = PreImageMakeRelationCanonical(info, vector, from, relationArray, 01012 &newVector, &newRelationArray); 01013 } else { 01014 newFrom = from; 01015 newVector = vector; 01016 newRelationArray = relationArray; 01017 } 01018 /* To remove compiler warnings */ 01019 foundEssentialDepth = -1; 01020 foundEssentialDepthT = -1; 01021 foundEssentialDepthE = -1; 01022 } 01023 01024 if (info->option->debug) { 01025 refResult = ImgPreImageByHybridWithStaticSplit(info, vector, from, 01026 relationArray, 01027 NIL(mdd_t), NIL(mdd_t)); 01028 res = ImgPreImageByHybridWithStaticSplit(info, newVector, newFrom, 01029 newRelationArray, 01030 NIL(mdd_t), NIL(mdd_t)); 01031 tmp = refResult; 01032 refResult = mdd_and(tmp, info->debugCareSet, 1, 1); 01033 mdd_free(tmp); 01034 tmp = res; 01035 res = mdd_and(tmp, info->debugCareSet, 1, 1); 01036 mdd_free(tmp); 01037 assert(mdd_equal_mod_care_set_array(refResult, res, info->toCareSetArray)); 01038 mdd_free(refResult); 01039 mdd_free(res); 01040 } 01041 01042 if (bdd_is_tautology(newFrom, 1)) { 01043 if (newVector && newVector != vector) 01044 ImgVectorFree(newVector); 01045 if (newRelationArray != relationArray) 01046 mdd_array_free(newRelationArray); 01047 if (newFrom != from) 01048 mdd_free(newFrom); 01049 info->averageDepthB = (info->averageDepthB * (float)info->nLeavesB + 01050 (float)depth) / (float)(info->nLeavesB + 1); 01051 if (depth > info->maxDepthB) 01052 info->maxDepthB = depth; 01053 info->nLeavesB++; 01054 if (findEssential) 01055 info->foundEssentialDepth = foundEssentialDepth; 01056 return(mdd_one(info->manager)); 01057 } 01058 01059 if (depth == turnDepth || 01060 (info->option->splitCubeFunc && bdd_is_cube(newFrom))) { 01061 res = ImgPreImageByHybridWithStaticSplit(info, newVector, newFrom, 01062 newRelationArray, 01063 NIL(mdd_t), NIL(mdd_t)); 01064 if (newVector && newVector != vector) 01065 ImgVectorFree(newVector); 01066 if (newRelationArray != relationArray) 01067 mdd_array_free(newRelationArray); 01068 if (newFrom != from) 01069 mdd_free(newFrom); 01070 info->averageDepthB = (info->averageDepthB * (float)info->nLeavesB + 01071 (float)depth) / (float)(info->nLeavesB + 1); 01072 if (depth > info->maxDepthB) 01073 info->maxDepthB = depth; 01074 info->nLeavesB++; 01075 if (findEssential) 01076 info->foundEssentialDepth = foundEssentialDepth; 01077 return(res); 01078 } 01079 01080 var = ImgChooseTrSplitVar(info, newVector, newRelationArray, 01081 info->option->trSplitMethod, 0); 01082 if (!var) { 01083 res = ImgPreImageByHybridWithStaticSplit(info, newVector, newFrom, 01084 newRelationArray, 01085 NIL(mdd_t), NIL(mdd_t)); 01086 if (newVector && newVector != vector) 01087 ImgVectorFree(newVector); 01088 if (newRelationArray != relationArray) 01089 mdd_array_free(newRelationArray); 01090 if (newFrom != from) 01091 mdd_free(newFrom); 01092 info->averageDepthB = (info->averageDepthB * (float)info->nLeavesB + 01093 (float)depth) / (float)(info->nLeavesB + 1); 01094 if (depth > info->maxDepthB) 01095 info->maxDepthB = depth; 01096 info->nLeavesB++; 01097 if (findEssential) 01098 info->foundEssentialDepth = foundEssentialDepth; 01099 return(res); 01100 } 01101 01102 varNot = mdd_not(var); 01103 01104 nRecur = 0; 01105 if (newVector) { 01106 ImgVectorConstrain(info, newVector, var, NIL(array_t), 01107 &vectorT, &cubeT, NIL(array_t *), 01108 NIL(mdd_t *), NIL(mdd_t *), TRUE); 01109 fromT = bdd_cofactor(newFrom, cubeT); 01110 mdd_free(cubeT); 01111 } else { 01112 vectorT = NIL(array_t); 01113 fromT = mdd_dup(newFrom); 01114 } 01115 relationArrayT = ImgGetCofactoredRelationArray(newRelationArray, var); 01116 if (bdd_is_tautology(fromT, 1)) { 01117 resT = mdd_one(info->manager); 01118 if (vectorT) 01119 ImgVectorFree(vectorT); 01120 } else if (bdd_is_tautology(fromT, 0)) { 01121 resT = mdd_zero(info->manager); 01122 if (vectorT) 01123 ImgVectorFree(vectorT); 01124 } else { 01125 if (info->option->debug) { 01126 saveCareSet = info->debugCareSet; 01127 info->debugCareSet = mdd_and(saveCareSet, var, 1, 1); 01128 } 01129 resT = PreImageByStaticDomainCofactoring(info, vectorT, fromT, 01130 relationArrayT, turnDepth, depth + 1); 01131 if (info->option->debug) { 01132 mdd_free(info->debugCareSet); 01133 info->debugCareSet = saveCareSet; 01134 } 01135 if (findEssential) 01136 foundEssentialDepthE = info->foundEssentialDepth; 01137 if (vectorT) 01138 ImgVectorFree(vectorT); 01139 nRecur++; 01140 } 01141 mdd_free(fromT); 01142 mdd_array_free(relationArrayT); 01143 01144 if (newVector) { 01145 ImgVectorConstrain(info, newVector, varNot, NIL(array_t), 01146 &vectorE, &cubeE, NIL(array_t *), 01147 NIL(mdd_t *), NIL(mdd_t *), TRUE); 01148 if (newVector != vector) 01149 ImgVectorFree(newVector); 01150 fromE = bdd_cofactor(newFrom, cubeE); 01151 mdd_free(cubeE); 01152 } else { 01153 vectorE = NIL(array_t); 01154 fromE = mdd_dup(newFrom); 01155 } 01156 if (newFrom != from) 01157 mdd_free(newFrom); 01158 relationArrayE = ImgGetCofactoredRelationArray(newRelationArray, varNot); 01159 if (newRelationArray != relationArray) 01160 mdd_array_free(newRelationArray); 01161 if (bdd_is_tautology(fromE, 1)) { 01162 resE = mdd_one(info->manager); 01163 if (vectorE) 01164 ImgVectorFree(vectorE); 01165 } else if (bdd_is_tautology(fromE, 0)) { 01166 resE = mdd_zero(info->manager); 01167 if (vectorE) 01168 ImgVectorFree(vectorE); 01169 } else { 01170 if (info->option->debug) { 01171 saveCareSet = info->debugCareSet; 01172 info->debugCareSet = mdd_and(saveCareSet, var, 1, 0); 01173 } 01174 resE = PreImageByStaticDomainCofactoring(info, vectorE, fromE, 01175 relationArrayE, turnDepth, depth + 1); 01176 if (info->option->debug) { 01177 mdd_free(info->debugCareSet); 01178 info->debugCareSet = saveCareSet; 01179 } 01180 if (findEssential) 01181 foundEssentialDepthE = info->foundEssentialDepth; 01182 if (vectorE) 01183 ImgVectorFree(vectorE); 01184 nRecur++; 01185 } 01186 mdd_free(fromE); 01187 mdd_array_free(relationArrayE); 01188 01189 res = bdd_ite(var, resT, resE, 1, 1, 1); 01190 if (info->option->verbosity) { 01191 size = bdd_size(res); 01192 if (size > info->maxIntermediateSize) 01193 info->maxIntermediateSize = size; 01194 if (info->option->printBddSize) { 01195 fprintf(vis_stdout, "** tfm info: bdd_ite(2,%d,%d) = %d\n", 01196 bdd_size(resT), bdd_size(resE), bdd_size(res)); 01197 } 01198 } 01199 mdd_free(resT); 01200 mdd_free(resE); 01201 mdd_free(var); 01202 mdd_free(varNot); 01203 01204 if (info->option->debug) { 01205 refResult = ImgPreImageByHybridWithStaticSplit(info, vector, from, 01206 relationArray, 01207 NIL(mdd_t), NIL(mdd_t)); 01208 tmp = refResult; 01209 refResult = mdd_and(tmp, info->debugCareSet, 1, 1); 01210 mdd_free(tmp); 01211 tmp = mdd_and(res, info->debugCareSet, 1, 1); 01212 assert(mdd_equal_mod_care_set_array(refResult, tmp, info->toCareSetArray)); 01213 mdd_free(refResult); 01214 mdd_free(tmp); 01215 } 01216 01217 if (nRecur == 0) { 01218 info->averageDepthB = (info->averageDepthB * (float)info->nLeavesB + 01219 (float)depth) / (float)(info->nLeavesB + 1); 01220 if (depth > info->maxDepthB) 01221 info->maxDepthB = depth; 01222 info->nLeavesB++; 01223 } 01224 01225 if (findEssential) { 01226 if (foundEssentialDepth == info->option->maxEssentialDepth) { 01227 if (foundEssentialDepthT < foundEssentialDepthE) 01228 foundEssentialDepth = foundEssentialDepthT; 01229 else 01230 foundEssentialDepth = foundEssentialDepthE; 01231 } 01232 info->foundEssentialDepth = foundEssentialDepth; 01233 } 01234 return(res); 01235 } 01236 01237 01247 static bdd_t * 01248 PreImageByConstraintCofactoring(ImgTfmInfo_t *info, array_t *delta, 01249 bdd_t *image, int splitMethod, 01250 int turnDepth, int depth) 01251 { 01252 array_t *newDelta, *tmpDelta, *vector; 01253 bdd_t *preImg, *preImgT, *preImgE, *imgT, *imgE; 01254 bdd_t *c, *newImg, *tmpImg; 01255 int split; 01256 bdd_t *var, *varNot, *refResult; 01257 ImgComponent_t *comp; 01258 int nRecur, size; 01259 mdd_t *essentialCube; 01260 int findEssential; 01261 int foundEssentialDepth; 01262 int foundEssentialDepthT, foundEssentialDepthE; 01263 mdd_t *saveCareSet = NIL(mdd_t), *tmp; 01264 01265 info->nRecursionB++; 01266 01267 if (info->nIntermediateVars) 01268 size = ImgVectorFunctionSize(delta); 01269 else 01270 size = array_n(delta); 01271 if (size == 1) { 01272 preImg = PreImageBySubstitution(info, delta, image); 01273 info->averageDepthB = (info->averageDepthB * (float)info->nLeavesB + 01274 (float)depth) / (float)(info->nLeavesB + 1); 01275 if (depth > info->maxDepthB) 01276 info->maxDepthB = depth; 01277 info->nLeavesB++; 01278 info->foundEssentialDepth = info->option->maxEssentialDepth; 01279 return(preImg); 01280 } 01281 01282 if (info->option->findEssential) { 01283 if (info->option->findEssential == 1) 01284 findEssential = 1; 01285 else { 01286 if (depth >= info->lastFoundEssentialDepth) 01287 findEssential = 1; 01288 else 01289 findEssential = 0; 01290 } 01291 } else 01292 findEssential = 0; 01293 if (findEssential) { 01294 essentialCube = bdd_find_essential_cube(image); 01295 01296 if (!bdd_is_tautology(essentialCube, 1)) { 01297 info->averageFoundEssential = (info->averageFoundEssential * 01298 (float)info->nFoundEssentials + (float)(bdd_size(essentialCube) - 1)) / 01299 (float)(info->nFoundEssentials + 1); 01300 info->averageFoundEssentialDepth = (info->averageFoundEssentialDepth * 01301 (float)info->nFoundEssentials + (float)depth) / 01302 (float)(info->nFoundEssentials + 1); 01303 if (info->nFoundEssentials == 0 || depth < info->topFoundEssentialDepth) 01304 info->topFoundEssentialDepth = depth; 01305 if (info->option->printEssential && depth < IMG_TF_MAX_PRINT_DEPTH) 01306 info->foundEssentials[depth]++; 01307 info->nFoundEssentials++; 01308 tmpImg = ImgVectorMinimize(info, delta, essentialCube, image, 01309 NIL(array_t), &tmpDelta, NIL(mdd_t *), 01310 NIL(array_t *), NIL(mdd_t *), NIL(mdd_t *)); 01311 foundEssentialDepth = depth; 01312 } else { 01313 tmpDelta = delta; 01314 tmpImg = image; 01315 foundEssentialDepth = info->option->maxEssentialDepth; 01316 } 01317 mdd_free(essentialCube); 01318 foundEssentialDepthT = info->option->maxEssentialDepth; 01319 foundEssentialDepthE = info->option->maxEssentialDepth; 01320 } else { 01321 tmpDelta = delta; 01322 tmpImg = image; 01323 /* To remove compiler warnings */ 01324 foundEssentialDepth = -1; 01325 foundEssentialDepthT = -1; 01326 foundEssentialDepthE = -1; 01327 } 01328 01329 if (info->option->preCanonical) { 01330 newImg = PreImageMakeVectorCanonical(info, tmpDelta, tmpImg, NIL(array_t), 01331 &newDelta, NIL(array_t *), NIL(mdd_t *), 01332 NIL(mdd_t *)); 01333 } else { 01334 newImg = tmpImg; 01335 newDelta = tmpDelta; 01336 } 01337 if (tmpDelta != delta) 01338 ImgVectorFree(tmpDelta); 01339 if (tmpImg != image) 01340 mdd_free(tmpImg); 01341 01342 if (bdd_is_tautology(newImg, 1) || bdd_is_tautology(newImg, 0)) { 01343 info->averageDepthB = (info->averageDepthB * (float)info->nLeavesB + 01344 (float)depth) / (float)(info->nLeavesB + 1); 01345 if (depth > info->maxDepthB) 01346 info->maxDepthB = depth; 01347 info->nLeavesB++; 01348 if (info->option->debug) { 01349 refResult = ImgPreImageByHybrid(info, newDelta, newImg); 01350 tmp = refResult; 01351 refResult = mdd_and(tmp, info->debugCareSet, 1, 1); 01352 mdd_free(tmp); 01353 tmp = mdd_and(newImg, info->debugCareSet, 1, 1); 01354 assert(mdd_equal_mod_care_set_array(refResult, tmp, 01355 info->toCareSetArray)); 01356 mdd_free(refResult); 01357 mdd_free(tmp); 01358 } 01359 ImgVectorFree(newDelta); 01360 if (findEssential) 01361 info->foundEssentialDepth = foundEssentialDepth; 01362 return(newImg); 01363 } 01364 01365 if (info->preCache) { 01366 preImg = ImgCacheLookupTable(info, info->preCache, newDelta, newImg); 01367 if (preImg) { 01368 info->averageDepthB = (info->averageDepthB * (float)info->nLeavesB + 01369 (float)depth) / (float)(info->nLeavesB + 1); 01370 if (depth > info->maxDepthB) 01371 info->maxDepthB = depth; 01372 info->nLeavesB++; 01373 if (info->option->debug) { 01374 refResult = ImgPreImageByHybrid(info, newDelta, newImg); 01375 tmp = refResult; 01376 refResult = mdd_and(tmp, info->debugCareSet, 1, 1); 01377 mdd_free(tmp); 01378 tmp = mdd_and(preImg, info->debugCareSet, 1, 1); 01379 assert(mdd_equal_mod_care_set_array(refResult, tmp, 01380 info->toCareSetArray)); 01381 mdd_free(refResult); 01382 mdd_free(tmp); 01383 } 01384 ImgVectorFree(newDelta); 01385 mdd_free(newImg); 01386 if (findEssential) 01387 info->foundEssentialDepth = foundEssentialDepth; 01388 return(preImg); 01389 } 01390 } 01391 01392 if (depth == turnDepth) { 01393 preImg = ImgPreImageByHybrid(info, newDelta, newImg); 01394 if (info->option->debug) { 01395 refResult = ImgPreImageByHybrid(info, newDelta, newImg); 01396 tmp = refResult; 01397 refResult = mdd_and(tmp, info->debugCareSet, 1, 1); 01398 mdd_free(tmp); 01399 tmp = mdd_and(preImg, info->debugCareSet, 1, 1); 01400 assert(mdd_equal_mod_care_set_array(refResult, tmp, 01401 info->toCareSetArray)); 01402 mdd_free(refResult); 01403 mdd_free(tmp); 01404 } 01405 if (info->preCache) 01406 ImgCacheInsertTable(info->preCache, newDelta, newImg, mdd_dup(preImg)); 01407 else { 01408 ImgVectorFree(newDelta); 01409 mdd_free(newImg); 01410 } 01411 info->averageDepthB = (info->averageDepthB * (float)info->nLeavesB + 01412 (float)depth) / (float)(info->nLeavesB + 1); 01413 if (depth > info->maxDepthB) 01414 info->maxDepthB = depth; 01415 info->nLeavesB++; 01416 info->nTurnsB++; 01417 if (findEssential) 01418 info->foundEssentialDepth = foundEssentialDepth; 01419 return(preImg); 01420 } 01421 01422 split = PreImageChooseSplitVar(info, newDelta, newImg, 01423 1, info->option->preOutputSplit); 01424 comp = array_fetch(ImgComponent_t *, newDelta, split); 01425 var = mdd_dup(comp->var); 01426 varNot = mdd_not(var); 01427 imgE = bdd_cofactor(newImg, varNot); 01428 mdd_free(varNot); 01429 imgT = bdd_cofactor(newImg, var); 01430 mdd_free(var); 01431 if (!info->preCache && !info->option->debug) 01432 mdd_free(newImg); 01433 c = PreImageDeleteOneComponent(info, newDelta, split, &vector); 01434 if (!info->preCache && !info->option->debug) 01435 ImgVectorFree(newDelta); 01436 01437 nRecur = 0; 01438 if (bdd_is_tautology(imgT, 1)) 01439 preImgT = mdd_one(info->manager); 01440 else if (bdd_is_tautology(imgT, 0)) 01441 preImgT = mdd_zero(info->manager); 01442 else { 01443 if (info->option->debug) { 01444 saveCareSet = info->debugCareSet; 01445 info->debugCareSet = mdd_and(saveCareSet, c, 1, 1); 01446 } 01447 preImgT = PreImageByConstraintCofactoring(info, vector, imgT, splitMethod, 01448 turnDepth, depth + 1); 01449 if (info->option->debug) { 01450 mdd_free(info->debugCareSet); 01451 info->debugCareSet = saveCareSet; 01452 } 01453 if (findEssential) 01454 foundEssentialDepthT = info->foundEssentialDepth; 01455 nRecur++; 01456 } 01457 mdd_free(imgT); 01458 if (bdd_is_tautology(imgE, 1)) 01459 preImgE = mdd_one(info->manager); 01460 else if (bdd_is_tautology(imgE, 0)) 01461 preImgE = mdd_zero(info->manager); 01462 else { 01463 if (info->option->debug) { 01464 saveCareSet = info->debugCareSet; 01465 info->debugCareSet = mdd_and(saveCareSet, c, 1, 0); 01466 } 01467 preImgE = PreImageByConstraintCofactoring(info, vector, imgE, splitMethod, 01468 turnDepth, depth + 1); 01469 if (info->option->debug) { 01470 mdd_free(info->debugCareSet); 01471 info->debugCareSet = saveCareSet; 01472 } 01473 if (findEssential) 01474 foundEssentialDepthE = info->foundEssentialDepth; 01475 nRecur++; 01476 } 01477 mdd_free(imgE); 01478 ImgVectorFree(vector); 01479 preImg = bdd_ite(c, preImgT, preImgE, 1, 1, 1); 01480 if (info->option->verbosity) { 01481 size = bdd_size(preImg); 01482 if (size > info->maxIntermediateSize) 01483 info->maxIntermediateSize = size; 01484 if (info->option->printBddSize) { 01485 fprintf(vis_stdout, "** tfm info: bdd_ite(%d,%d,%d) = %d\n", 01486 bdd_size(c), bdd_size(preImgT), bdd_size(preImgE), 01487 bdd_size(preImg)); 01488 } 01489 } 01490 mdd_free(c); 01491 mdd_free(preImgT); 01492 mdd_free(preImgE); 01493 01494 if (info->preCache) 01495 ImgCacheInsertTable(info->preCache, newDelta, newImg, mdd_dup(preImg)); 01496 01497 if (info->option->debug) { 01498 refResult = ImgPreImageByHybrid(info, newDelta, newImg); 01499 tmp = refResult; 01500 refResult = mdd_and(tmp, info->debugCareSet, 1, 1); 01501 mdd_free(tmp); 01502 tmp = mdd_and(preImg, info->debugCareSet, 1, 1); 01503 assert(mdd_equal_mod_care_set_array(refResult, tmp, 01504 info->toCareSetArray)); 01505 mdd_free(refResult); 01506 mdd_free(tmp); 01507 if (!info->preCache) { 01508 ImgVectorFree(newDelta); 01509 mdd_free(newImg); 01510 } 01511 } 01512 01513 if (nRecur == 0) { 01514 info->averageDepthB = (info->averageDepthB * (float)info->nLeavesB + 01515 (float)depth) / (float)(info->nLeavesB + 1); 01516 if (depth > info->maxDepthB) 01517 info->maxDepthB = depth; 01518 info->nLeavesB++; 01519 } 01520 01521 if (findEssential) { 01522 if (foundEssentialDepth == info->option->maxEssentialDepth) { 01523 if (foundEssentialDepthT < foundEssentialDepthE) 01524 foundEssentialDepth = foundEssentialDepthT; 01525 else 01526 foundEssentialDepth = foundEssentialDepthE; 01527 } 01528 info->foundEssentialDepth = foundEssentialDepth; 01529 } 01530 return(preImg); 01531 } 01532 01533 01543 static mdd_t * 01544 PreImageBySubstitution(ImgTfmInfo_t *info, array_t *vector, mdd_t *from) 01545 { 01546 int i, index; 01547 ImgComponent_t *comp, *fromComp; 01548 array_t *varArray, *funcArray; 01549 mdd_t *result; 01550 01551 if (bdd_is_tautology(from, 1)) 01552 return(mdd_one(info->manager)); 01553 else if (bdd_is_tautology(from, 0)) 01554 return(mdd_zero(info->manager)); 01555 01556 fromComp = ImgComponentAlloc(info); 01557 fromComp->func = from; 01558 ImgComponentGetSupport(fromComp); 01559 01560 varArray = array_alloc(mdd_t *, 0); 01561 funcArray = array_alloc(mdd_t *, 0); 01562 01563 for (i = 0; i < array_n(vector); i++) { 01564 comp = array_fetch(ImgComponent_t *, vector, i); 01565 index = bdd_top_var_id(comp->var); 01566 if (fromComp->support[index] || comp->intermediate) { 01567 array_insert_last(mdd_t *, varArray, comp->var); 01568 array_insert_last(mdd_t *, funcArray, comp->func); 01569 } 01570 } 01571 01572 fromComp->func = NIL(mdd_t); 01573 ImgComponentFree(fromComp); 01574 01575 result = bdd_vector_compose(from, varArray, funcArray); 01576 array_free(varArray); 01577 array_free(funcArray); 01578 01579 /* quantify all primary inputs */ 01580 if (info->preKeepPiInTr == FALSE) { 01581 array_t *quantifyVarBddArray; 01582 mdd_t *tmp; 01583 01584 if (info->newQuantifyBddVars) 01585 quantifyVarBddArray = info->newQuantifyBddVars; 01586 else 01587 quantifyVarBddArray = info->quantifyVarBddArray; 01588 01589 tmp = result; 01590 result = bdd_smooth(tmp, quantifyVarBddArray); 01591 mdd_free(tmp); 01592 } 01593 01594 return(result); 01595 } 01596 01597 01611 static bdd_t * 01612 PreImageMakeVectorCanonical(ImgTfmInfo_t *info, array_t *vector, bdd_t *image, 01613 array_t *relationArray, array_t **newVector, 01614 array_t **newRelationArray, 01615 mdd_t **cofactorCube, mdd_t **abstractCube) 01616 { 01617 array_t *tmpVector, *cofactoredVector; 01618 bdd_t *simple, *tmp, *newImage; 01619 ImgComponent_t *comp, *comp1, *imgComp; 01620 int i, id, n, pos; 01621 st_table *equivTable; 01622 int *ptr, *regularPtr; 01623 mdd_t *var, *cofactor, *abstract, *nsVar; 01624 array_t *tmpRelationArray; 01625 int changed = 0; 01626 01627 newImage = mdd_dup(image); 01628 01629 imgComp = ImgComponentAlloc(info); 01630 imgComp->func = image; 01631 ImgComponentGetSupport(imgComp); 01632 01633 if (relationArray) { 01634 cofactor = mdd_one(info->manager); 01635 abstract = mdd_one(info->manager); 01636 } else { 01637 cofactor = NIL(mdd_t); 01638 abstract = NIL(mdd_t); 01639 } 01640 01641 if (info->nIntermediateVars) { 01642 mdd_t *tmpCofactor, *tmpAbstract; 01643 mdd_t *constIntermediate; 01644 01645 if (ImgExistConstIntermediateVar(vector)) { 01646 constIntermediate = mdd_one(info->manager); 01647 for (i = 0; i < array_n(vector); i++) { 01648 comp = array_fetch(ImgComponent_t *, vector, i); 01649 if (comp->intermediate) { 01650 if (mdd_is_tautology(comp->func, 1)) { 01651 tmp = constIntermediate; 01652 constIntermediate = mdd_and(tmp, comp->var, 1, 1); 01653 mdd_free(tmp); 01654 } else if (mdd_is_tautology(comp->func, 0)) { 01655 tmp = constIntermediate; 01656 constIntermediate = mdd_and(tmp, comp->var, 1, 0); 01657 mdd_free(tmp); 01658 } 01659 } 01660 } 01661 if (relationArray) { 01662 cofactoredVector = ImgComposeConstIntermediateVars(info, vector, 01663 constIntermediate, 01664 &tmpCofactor, &tmpAbstract, 01665 NIL(mdd_t *), &newImage); 01666 01667 if (!bdd_is_tautology(tmpCofactor, 1)) { 01668 tmp = cofactor; 01669 cofactor = mdd_and(tmp, tmpCofactor, 1, 1); 01670 mdd_free(tmp); 01671 } 01672 mdd_free(tmpCofactor); 01673 if (!bdd_is_tautology(tmpAbstract, 1)) { 01674 tmp = abstract; 01675 abstract = mdd_and(tmp, tmpAbstract, 1, 1); 01676 mdd_free(tmp); 01677 } 01678 mdd_free(tmpAbstract); 01679 } else { 01680 cofactoredVector = ImgComposeConstIntermediateVars(info, vector, 01681 constIntermediate, 01682 NIL(mdd_t *), NIL(mdd_t *), 01683 NIL(mdd_t *), &newImage); 01684 } 01685 mdd_free(constIntermediate); 01686 } else 01687 cofactoredVector = vector; 01688 } else 01689 cofactoredVector = vector; 01690 01691 /* Simplify image -- canonicalize the image first */ 01692 n = 0; 01693 equivTable = st_init_table(st_ptrcmp, st_ptrhash); 01694 tmpVector = array_alloc(ImgComponent_t *, 0); 01695 for (i = 0; i < array_n(cofactoredVector); i++) { 01696 comp = array_fetch(ImgComponent_t *, cofactoredVector, i); 01697 if (comp->intermediate) { 01698 comp1 = ImgComponentCopy(info, comp); 01699 array_insert_last(ImgComponent_t *, tmpVector, comp1); 01700 n++; 01701 continue; 01702 } 01703 id = (int)bdd_top_var_id(comp->var); 01704 if (!imgComp->support[id]) { 01705 if (abstract) { 01706 nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 01707 tmp = abstract; 01708 abstract = mdd_and(tmp, nsVar, 1, 1); 01709 mdd_free(tmp); 01710 mdd_free(nsVar); 01711 } 01712 continue; 01713 } 01714 if (mdd_is_tautology(comp->func, 1)) { 01715 changed = 1; 01716 simple = bdd_cofactor(newImage, comp->var); 01717 mdd_free(newImage); 01718 newImage = simple; 01719 if (abstract) { 01720 nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 01721 tmp = abstract; 01722 abstract = mdd_and(tmp, nsVar, 1, 1); 01723 mdd_free(tmp); 01724 mdd_free(nsVar); 01725 } 01726 } else if (mdd_is_tautology(comp->func, 0)) { 01727 changed = 1; 01728 tmp = mdd_not(comp->var); 01729 simple = bdd_cofactor(newImage, tmp); 01730 mdd_free(tmp); 01731 mdd_free(newImage); 01732 newImage = simple; 01733 if (abstract) { 01734 nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 01735 tmp = abstract; 01736 abstract = mdd_and(tmp, nsVar, 1, 1); 01737 mdd_free(tmp); 01738 mdd_free(nsVar); 01739 } 01740 } else { 01741 ptr = (int *)bdd_pointer(comp->func); 01742 regularPtr = (int *)((unsigned long)ptr & ~01); 01743 if (st_lookup_int(equivTable, (char *)regularPtr, &pos)) { 01744 changed = 1; 01745 comp1 = array_fetch(ImgComponent_t *, tmpVector, pos); 01746 if (mdd_equal(comp->func, comp1->func)) { 01747 tmp = newImage; 01748 newImage = bdd_compose(tmp, comp->var, comp1->var); 01749 mdd_free(tmp); 01750 } else { 01751 tmp = newImage; 01752 var = mdd_not(comp1->var); 01753 newImage = bdd_compose(tmp, comp->var, var); 01754 mdd_free(tmp); 01755 mdd_free(var); 01756 } 01757 if (abstract) { 01758 nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 01759 tmp = abstract; 01760 abstract = mdd_and(tmp, nsVar, 1, 1); 01761 mdd_free(tmp); 01762 mdd_free(nsVar); 01763 } 01764 } else { 01765 comp1 = ImgComponentCopy(info, comp); 01766 array_insert_last(ImgComponent_t *, tmpVector, comp1); 01767 st_insert(equivTable, (char *)regularPtr, (char *)(long)n); 01768 n++; 01769 } 01770 } 01771 } 01772 st_free_table(equivTable); 01773 if (cofactoredVector && cofactoredVector != vector) 01774 ImgVectorFree(cofactoredVector); 01775 01776 if (changed) { 01777 /* Now Simplify delta by deleting the non-affecting components */ 01778 *newVector = array_alloc(ImgComponent_t *, 0); 01779 01780 imgComp->func = NIL(mdd_t); 01781 ImgComponentFree(imgComp); 01782 01783 imgComp = ImgComponentAlloc(info); 01784 imgComp->func = newImage; 01785 ImgSupportClear(info, imgComp->support); 01786 ImgComponentGetSupport(imgComp); 01787 for (i = 0; i < array_n(tmpVector); i++) { 01788 comp = array_fetch(ImgComponent_t *, tmpVector, i); 01789 id = (int)bdd_top_var_id(comp->var); 01790 if (imgComp->support[id] || comp->intermediate) 01791 array_insert_last(ImgComponent_t *, *newVector, comp); 01792 else { 01793 if (abstract) { 01794 nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 01795 tmp = abstract; 01796 abstract = mdd_and(tmp, nsVar, 1, 1); 01797 mdd_free(tmp); 01798 mdd_free(nsVar); 01799 } 01800 ImgComponentFree(comp); 01801 } 01802 } 01803 array_free(tmpVector); 01804 } else 01805 *newVector = tmpVector; 01806 01807 imgComp->func = NIL(mdd_t); 01808 ImgComponentFree(imgComp); 01809 01810 if (newRelationArray) 01811 *newRelationArray = relationArray; 01812 if (cofactor) { 01813 if (cofactorCube) 01814 *cofactorCube = cofactor; 01815 else { 01816 if (!bdd_is_tautology(cofactor, 1)) { 01817 tmpRelationArray = *newRelationArray; 01818 *newRelationArray = ImgGetCofactoredRelationArray(tmpRelationArray, 01819 cofactor); 01820 if (tmpRelationArray != relationArray) 01821 mdd_array_free(tmpRelationArray); 01822 } 01823 mdd_free(cofactor); 01824 } 01825 } 01826 if (abstract) { 01827 if (abstractCube) 01828 *abstractCube = abstract; 01829 else { 01830 if (bdd_is_tautology(abstract, 1)) 01831 mdd_free(abstract); 01832 else { 01833 tmpRelationArray = *newRelationArray; 01834 *newRelationArray = ImgGetAbstractedRelationArray(info->manager, 01835 tmpRelationArray, 01836 abstract); 01837 mdd_free(abstract); 01838 if (tmpRelationArray != relationArray) 01839 mdd_array_free(tmpRelationArray); 01840 } 01841 } 01842 } 01843 assert(CheckPreImageVector(info, *newVector, newImage)); 01844 return(newImage); 01845 } 01846 01847 01862 static bdd_t * 01863 PreImageMakeRelationCanonical(ImgTfmInfo_t *info, array_t *vector, bdd_t *image, 01864 array_t *relationArray, array_t **newVector, 01865 array_t **newRelationArray) 01866 { 01867 array_t *tmpVector, *cofactoredVector; 01868 bdd_t *simple, *tmp, *newImage; 01869 ImgComponent_t *comp, *comp1, *imgComp; 01870 int i, j, id; 01871 mdd_t *cofactor, *abstract, *var, *nsVar; 01872 array_t *tmpRelationArray; 01873 int changed = 0; 01874 mdd_t *yVarsCube, *rangeCube, *relation, *tmp2; 01875 array_t *supportIds; 01876 01877 imgComp = ImgComponentAlloc(info); 01878 imgComp->func = image; 01879 ImgComponentGetSupport(imgComp); 01880 01881 if (vector) { 01882 newImage = mdd_dup(image); 01883 cofactor = mdd_one(info->manager); 01884 abstract = mdd_one(info->manager); 01885 01886 if (info->nIntermediateVars) { 01887 mdd_t *tmpCofactor, *tmpAbstract; 01888 mdd_t *constIntermediate; 01889 01890 if (ImgExistConstIntermediateVar(vector)) { 01891 constIntermediate = mdd_one(info->manager); 01892 01893 for (i = 0; i < array_n(vector); i++) { 01894 comp = array_fetch(ImgComponent_t *, vector, i); 01895 if (comp->intermediate) { 01896 if (mdd_is_tautology(comp->func, 1)) { 01897 tmp = constIntermediate; 01898 constIntermediate = mdd_and(tmp, comp->var, 1, 1); 01899 mdd_free(tmp); 01900 } else if (mdd_is_tautology(comp->func, 0)) { 01901 tmp = constIntermediate; 01902 constIntermediate = mdd_and(tmp, comp->var, 1, 0); 01903 mdd_free(tmp); 01904 } 01905 } 01906 } 01907 01908 cofactoredVector = ImgComposeConstIntermediateVars(info, vector, 01909 constIntermediate, 01910 &tmpCofactor, 01911 &tmpAbstract, 01912 NIL(mdd_t *), 01913 &newImage); 01914 01915 if (!bdd_is_tautology(tmpCofactor, 1)) { 01916 tmp = cofactor; 01917 cofactor = mdd_and(tmp, tmpCofactor, 1, 1); 01918 mdd_free(tmp); 01919 } 01920 mdd_free(tmpCofactor); 01921 if (!bdd_is_tautology(tmpAbstract, 1)) { 01922 tmp = abstract; 01923 abstract = mdd_and(tmp, tmpAbstract, 1, 1); 01924 mdd_free(tmp); 01925 } 01926 mdd_free(tmpAbstract); 01927 mdd_free(constIntermediate); 01928 } else 01929 cofactoredVector = vector; 01930 } else 01931 cofactoredVector = vector; 01932 01933 /* Simplify image -- canonicalize vector */ 01934 tmpVector = array_alloc(ImgComponent_t *, 0); 01935 for (i = 0; i < array_n(cofactoredVector); i++) { 01936 comp = array_fetch(ImgComponent_t *, cofactoredVector, i); 01937 if (comp->intermediate) { 01938 comp1 = ImgComponentCopy(info, comp); 01939 array_insert_last(ImgComponent_t *, tmpVector, comp1); 01940 continue; 01941 } 01942 id = (int)bdd_top_var_id(comp->var); 01943 if (!imgComp->support[id]) { 01944 if (abstract) { 01945 nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 01946 tmp = abstract; 01947 abstract = mdd_and(tmp, nsVar, 1, 1); 01948 mdd_free(tmp); 01949 mdd_free(nsVar); 01950 } 01951 continue; 01952 } 01953 if (mdd_is_tautology(comp->func, 1)) { 01954 changed = 1; 01955 simple = bdd_cofactor(newImage, comp->var); 01956 mdd_free(newImage); 01957 newImage = simple; 01958 if (abstract) { 01959 nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 01960 tmp = abstract; 01961 abstract = mdd_and(tmp, nsVar, 1, 1); 01962 mdd_free(tmp); 01963 mdd_free(nsVar); 01964 } 01965 } else if (mdd_is_tautology(comp->func, 0)) { 01966 changed = 1; 01967 tmp = mdd_not(comp->var); 01968 simple = bdd_cofactor(newImage, tmp); 01969 mdd_free(tmp); 01970 mdd_free(newImage); 01971 newImage = simple; 01972 if (abstract) { 01973 nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 01974 tmp = abstract; 01975 abstract = mdd_and(tmp, nsVar, 1, 1); 01976 mdd_free(tmp); 01977 mdd_free(nsVar); 01978 } 01979 } else { 01980 comp1 = ImgComponentCopy(info, comp); 01981 array_insert_last(ImgComponent_t *, tmpVector, comp1); 01982 } 01983 } 01984 if (cofactoredVector && cofactoredVector != vector) 01985 ImgVectorFree(cofactoredVector); 01986 01987 if (changed) { 01988 /* Now Simplify delta by deleting the non-affecting components */ 01989 *newVector = array_alloc(ImgComponent_t *, 0); 01990 01991 imgComp->func = NIL(mdd_t); 01992 ImgComponentFree(imgComp); 01993 01994 imgComp = ImgComponentAlloc(info); 01995 imgComp->func = newImage; 01996 ImgSupportClear(info, imgComp->support); 01997 ImgComponentGetSupport(imgComp); 01998 for (i = 0; i < array_n(tmpVector); i++) { 01999 comp = array_fetch(ImgComponent_t *, tmpVector, i); 02000 id = (int)bdd_top_var_id(comp->var); 02001 if (imgComp->support[id] || comp->intermediate) 02002 array_insert_last(ImgComponent_t *, *newVector, comp); 02003 else { 02004 if (abstract) { 02005 nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 02006 tmp = abstract; 02007 abstract = mdd_and(tmp, nsVar, 1, 1); 02008 mdd_free(tmp); 02009 mdd_free(nsVar); 02010 } 02011 ImgComponentFree(comp); 02012 } 02013 } 02014 array_free(tmpVector); 02015 } else 02016 *newVector = tmpVector; 02017 } else { 02018 newImage = image; 02019 *newVector = vector; 02020 cofactor = NIL(mdd_t); 02021 abstract = NIL(mdd_t); 02022 } 02023 02024 yVarsCube = mdd_one(info->manager); 02025 for (i = 0; i < info->nVars; i++) { 02026 if (imgComp->support[i]) { 02027 imgComp->support[i] = 0; 02028 if (st_lookup(info->quantifyVarsTable, (char *)(long)i, NIL(char *))) 02029 continue; 02030 if (info->intermediateVarsTable && 02031 st_lookup(info->intermediateVarsTable, (char *)(long)i, 02032 NIL(char *))) { 02033 continue; 02034 } 02035 var = bdd_var_with_index(info->manager, i); 02036 nsVar = ImgSubstitute(var, info->functionData, Img_D2R_c); 02037 mdd_free(var); 02038 id = (int)bdd_top_var_id(nsVar); 02039 imgComp->support[id] = 1; 02040 tmp = yVarsCube; 02041 yVarsCube = mdd_and(tmp, nsVar, 1, 1); 02042 mdd_free(tmp); 02043 mdd_free(nsVar); 02044 } 02045 } 02046 02047 if (vector) { 02048 for (i = 0; i < array_n(*newVector); i++) { 02049 comp = array_fetch(ImgComponent_t *, *newVector, i); 02050 nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 02051 id = (int)bdd_top_var_id(nsVar); 02052 imgComp->support[id] = 2; 02053 mdd_free(nsVar); 02054 } 02055 } 02056 02057 for (i = 0; i < array_n(relationArray); i++) { 02058 relation = array_fetch(mdd_t *, relationArray, i); 02059 supportIds = mdd_get_bdd_support_ids(info->manager, relation); 02060 for (j = 0; j < array_n(supportIds); j++) { 02061 id = array_fetch(int, supportIds, j); 02062 imgComp->support[id] = 2; 02063 } 02064 array_free(supportIds); 02065 } 02066 02067 for (i = 0; i < info->nVars; i++) { 02068 if (imgComp->support[i] == 1) { 02069 nsVar = bdd_var_with_index(info->manager, i); 02070 var = ImgSubstitute(nsVar, info->functionData, Img_R2D_c); 02071 mdd_free(nsVar); 02072 tmp = newImage; 02073 newImage = bdd_smooth_with_cube(tmp, var); 02074 if (tmp != image) 02075 mdd_free(tmp); 02076 mdd_free(var); 02077 } 02078 } 02079 02080 imgComp->func = NIL(mdd_t); 02081 ImgComponentFree(imgComp); 02082 02083 if (bdd_get_package_name() == CUDD) 02084 rangeCube = info->functionData->rangeCube; 02085 else { 02086 rangeCube = mdd_one(info->manager); 02087 for (i = 0; i < array_n(info->functionData->rangeBddVars); i++) { 02088 var = array_fetch(mdd_t *, info->functionData->rangeBddVars, i); 02089 tmp = rangeCube; 02090 rangeCube = mdd_and(tmp, var, 1, 1); 02091 mdd_free(tmp); 02092 } 02093 } 02094 02095 cofactor = NIL(mdd_t); 02096 if (abstract) { 02097 tmp2 = bdd_smooth_with_cube(rangeCube, yVarsCube); 02098 tmp = abstract; 02099 abstract = mdd_and(tmp, tmp2, 1, 1); 02100 mdd_free(tmp); 02101 mdd_free(tmp2); 02102 } else 02103 abstract = bdd_smooth_with_cube(rangeCube, yVarsCube); 02104 mdd_free(yVarsCube); 02105 if (rangeCube != info->functionData->rangeCube) 02106 mdd_free(rangeCube); 02107 02108 *newRelationArray = relationArray; 02109 if (cofactor) { 02110 if (!bdd_is_tautology(cofactor, 1)) { 02111 tmpRelationArray = *newRelationArray; 02112 *newRelationArray = ImgGetCofactoredRelationArray(tmpRelationArray, 02113 cofactor); 02114 if (tmpRelationArray != relationArray) 02115 mdd_array_free(tmpRelationArray); 02116 } 02117 mdd_free(cofactor); 02118 } 02119 if (bdd_is_tautology(abstract, 1)) 02120 mdd_free(abstract); 02121 else { 02122 tmpRelationArray = *newRelationArray; 02123 *newRelationArray = ImgGetAbstractedRelationArray(info->manager, 02124 tmpRelationArray, 02125 abstract); 02126 mdd_free(abstract); 02127 if (tmpRelationArray != relationArray) 02128 mdd_array_free(tmpRelationArray); 02129 } 02130 return(newImage); 02131 } 02132 02133 02144 static bdd_t * 02145 PreImageDeleteOneComponent(ImgTfmInfo_t *info, array_t *delta, int index, 02146 array_t **newDelta) 02147 { 02148 int i; 02149 ImgComponent_t *comp, *tmpComp; 02150 bdd_t *func, *newFunc; 02151 int preMinimize = info->option->preMinimize; 02152 02153 assert(array_n(delta) > 0); 02154 02155 comp = array_fetch(ImgComponent_t *, delta, index); 02156 func = mdd_dup(comp->func); 02157 02158 *newDelta = array_alloc(ImgComponent_t *, 0); 02159 for (i = 0; i < array_n(delta); i++) { 02160 if (i != index) { 02161 comp = array_fetch(ImgComponent_t *, delta, i); 02162 tmpComp = ImgComponentCopy(info, comp); 02163 if (preMinimize) { 02164 newFunc = bdd_minimize(tmpComp->func, func); 02165 if (mdd_equal(newFunc, tmpComp->func)) 02166 mdd_free(newFunc); 02167 else { 02168 mdd_free(tmpComp->func); 02169 tmpComp->func = newFunc; 02170 ImgSupportClear(info, tmpComp->support); 02171 ImgComponentGetSupport(tmpComp); 02172 } 02173 } 02174 array_insert_last(ImgComponent_t *, (*newDelta), tmpComp); 02175 } 02176 } 02177 02178 return(func); 02179 } 02180 02181 02191 static int 02192 PreImageChooseSplitVar(ImgTfmInfo_t *info, array_t *delta, bdd_t *img, 02193 int splitMethod, int split) 02194 { 02195 ImgComponent_t *comp, *imgComp; 02196 int i, j, bestCost, newCost; 02197 int index, bestVar, bestComp; 02198 int nFuncs, nVars, bestOccur = 0; 02199 int *varOccur, *varCost; 02200 mdd_t *var, *varNot, *pcFunc, *ncFunc; 02201 int tieCount = 0; 02202 02203 assert(array_n(delta) > 0); 02204 02205 if (splitMethod == 0) { 02206 bestVar = -1; 02207 bestComp = -1; 02208 nFuncs = array_n(delta); 02209 nVars = info->nVars; 02210 varOccur = ALLOC(int, nVars); 02211 memset(varOccur, 0, sizeof(int) * nVars); 02212 varCost = NIL(int); 02213 for (i = 0; i < nFuncs; i++) { 02214 comp = array_fetch(ImgComponent_t *, delta, i); 02215 for (j = 0; j < nVars; j++) { 02216 if (comp->support[j]) 02217 varOccur[j]++; 02218 } 02219 } 02220 switch (split) { 02221 case 0: /* largest support */ 02222 for (i = 0; i < nVars; i++) { 02223 if (varOccur[i] == 0) 02224 continue; 02225 if (st_lookup(info->quantifyVarsTable, (char *)(long)i, NIL(char *))) 02226 continue; 02227 if (info->intermediateVarsTable && 02228 st_lookup(info->intermediateVarsTable, (char *)(long)i, 02229 NIL(char *))) { 02230 continue; 02231 } 02232 if (bestVar == -1 || varOccur[i] > bestOccur) { 02233 bestVar = i; 02234 bestOccur = varOccur[i]; 02235 tieCount = 1; 02236 } else if (varOccur[i] == bestOccur) { 02237 tieCount++; 02238 if (info->option->tieBreakMode == 0 && 02239 bdd_get_level_from_id(info->manager, i) < 02240 bdd_get_level_from_id(info->manager, bestVar)) { 02241 bestVar = i; 02242 } 02243 } 02244 } 02245 02246 if (info->option->tieBreakMode == 1 && tieCount > 1) { 02247 bestCost = IMG_TF_MAX_INT; 02248 for (i = bestVar; i < nVars; i++) { 02249 if (varOccur[i] != bestOccur) 02250 continue; 02251 if (st_lookup(info->quantifyVarsTable, (char *)(long)i, NIL(char *))) 02252 continue; 02253 if (info->intermediateVarsTable && 02254 st_lookup(info->intermediateVarsTable, (char *)(long)i, 02255 NIL(char *))) { 02256 continue; 02257 } 02258 var = bdd_var_with_index(info->manager, i); 02259 newCost = 0; 02260 for (j = 0; j < array_n(delta); j++) { 02261 comp = array_fetch(ImgComponent_t *, delta, j); 02262 newCost += bdd_estimate_cofactor(comp->func, var, 1); 02263 newCost += bdd_estimate_cofactor(comp->func, var, 0); 02264 } 02265 mdd_free(var); 02266 02267 if (newCost < bestCost) { 02268 bestVar = i; 02269 bestCost = newCost; 02270 } else if (newCost == bestCost) { 02271 if (bdd_get_level_from_id(info->manager, i) < 02272 bdd_get_level_from_id(info->manager, bestVar)) { 02273 bestVar = i; 02274 } 02275 } 02276 } 02277 } 02278 break; 02279 case 1: /* smallest support after splitting */ 02280 /* Find the variable which makes the smallest support after splitting */ 02281 bestCost = IMG_TF_MAX_INT; 02282 varCost = ALLOC(int, nVars); 02283 memset(varCost, 0, sizeof(int) * nVars); 02284 for (i = 0; i < nVars; i++) { 02285 if (varOccur[i] == 0) 02286 continue; 02287 if (st_lookup(info->quantifyVarsTable, (char *)(long)i, NIL(char *))) 02288 continue; 02289 if (info->intermediateVarsTable && 02290 st_lookup(info->intermediateVarsTable, (char *)(long)i, 02291 NIL(char *))) { 02292 continue; 02293 } 02294 var = bdd_var_with_index(info->manager, i); 02295 varNot = mdd_not(var); 02296 for (j = 0; j < array_n(delta); j++) { 02297 comp = array_fetch(ImgComponent_t *, delta, j); 02298 pcFunc = bdd_cofactor(comp->func, var); 02299 varCost[i] += ImgCountBddSupports(pcFunc); 02300 mdd_free(pcFunc); 02301 ncFunc = bdd_cofactor(comp->func, varNot); 02302 varCost[i] += ImgCountBddSupports(ncFunc); 02303 mdd_free(ncFunc); 02304 } 02305 mdd_free(var); 02306 mdd_free(varNot); 02307 02308 if (varCost[i] < bestCost) { 02309 bestCost = varCost[i]; 02310 bestVar = i; 02311 } else if (varCost[i] == bestCost) { 02312 if (varOccur[i] < varOccur[bestVar]) { 02313 bestVar = i; 02314 } else if (varOccur[i] == varOccur[bestVar]) { 02315 if (bdd_get_level_from_id(info->manager, i) < 02316 bdd_get_level_from_id(info->manager, bestVar)) { 02317 bestVar = i; 02318 } 02319 } 02320 } 02321 } 02322 break; 02323 case 2: /* smallest BDD size after splitting */ 02324 /* Find the variable which makes the smallest BDDs of all functions 02325 after splitting */ 02326 bestCost = IMG_TF_MAX_INT; 02327 varCost = ALLOC(int, nVars); 02328 memset(varCost, 0, sizeof(int) * nVars); 02329 for (i = 0; i < nVars; i++) { 02330 if (varOccur[i] == 0) 02331 continue; 02332 if (st_lookup(info->quantifyVarsTable, (char *)(long)i, NIL(char *))) 02333 continue; 02334 if (info->intermediateVarsTable && 02335 st_lookup(info->intermediateVarsTable, (char *)(long)i, 02336 NIL(char *))) { 02337 continue; 02338 } 02339 var = bdd_var_with_index(info->manager, i); 02340 for (j = 0; j < array_n(delta); j++) { 02341 comp = array_fetch(ImgComponent_t *, delta, j); 02342 varCost[i] += bdd_estimate_cofactor(comp->func, var, 1); 02343 varCost[i] += bdd_estimate_cofactor(comp->func, var, 0); 02344 } 02345 mdd_free(var); 02346 02347 if (varCost[i] < bestCost) { 02348 bestCost = varCost[i]; 02349 bestVar = i; 02350 } else if (varCost[i] == bestCost) { 02351 if (varOccur[i] < varOccur[bestVar]) { 02352 bestVar = i; 02353 } else if (varOccur[i] == varOccur[bestVar]) { 02354 if (bdd_get_level_from_id(info->manager, i) < 02355 bdd_get_level_from_id(info->manager, bestVar)) { 02356 bestVar = i; 02357 } 02358 } 02359 } 02360 } 02361 break; 02362 case 3: /* top variable */ 02363 default: 02364 for (i = 0; i < nVars; i++) { 02365 if (varOccur[i] == 0) 02366 continue; 02367 if (st_lookup(info->quantifyVarsTable, (char *)(long)i, NIL(char *))) 02368 continue; 02369 if (info->intermediateVarsTable && 02370 st_lookup(info->intermediateVarsTable, (char *)(long)i, 02371 NIL(char *))) { 02372 continue; 02373 } 02374 if (bestVar == -1) 02375 bestVar = i; 02376 else if (bdd_get_level_from_id(info->manager, i) < 02377 bdd_get_level_from_id(info->manager, bestVar)) { 02378 bestVar = i; 02379 } 02380 } 02381 } 02382 FREE(varOccur); 02383 if (varCost) 02384 FREE(varCost); 02385 } else { 02386 bestComp = -1; 02387 bestVar = -1; 02388 switch (split) { 02389 case 0: /* smallest BDD size */ 02390 bestCost = IMG_TF_MAX_INT; 02391 imgComp = ImgComponentAlloc(info); 02392 imgComp->func = img; 02393 ImgComponentGetSupport(imgComp); 02394 for (i = 0; i < array_n(delta); i++) { 02395 comp = array_fetch(ImgComponent_t *, delta, i); 02396 if (comp->intermediate) 02397 continue; 02398 index = (int)bdd_top_var_id(comp->var); 02399 if (imgComp->support[index]) { 02400 newCost = bdd_size(comp->func); 02401 if (newCost < bestCost) { 02402 bestComp = i; 02403 bestCost = newCost; 02404 } 02405 } 02406 } 02407 imgComp->func = NIL(mdd_t); 02408 ImgComponentFree(imgComp); 02409 break; 02410 case 1: /* largest BDD size */ 02411 bestCost = 0; 02412 imgComp = ImgComponentAlloc(info); 02413 imgComp->func = img; 02414 ImgComponentGetSupport(imgComp); 02415 for (i = 0; i < array_n(delta); i++) { 02416 comp = array_fetch(ImgComponent_t *, delta, i); 02417 if (comp->intermediate) 02418 continue; 02419 index = (int)bdd_top_var_id(comp->var); 02420 if (imgComp->support[index]) { 02421 newCost = bdd_size(comp->func); 02422 if (newCost > bestCost) { 02423 bestComp = i; 02424 bestCost = newCost; 02425 } 02426 } 02427 } 02428 imgComp->func = NIL(mdd_t); 02429 ImgComponentFree(imgComp); 02430 break; 02431 case 2: /* top variable */ 02432 default: 02433 for (i = 0; i < array_n(delta); i++) { 02434 comp = array_fetch(ImgComponent_t *, delta, i); 02435 if (comp->intermediate) 02436 continue; 02437 index = (int)bdd_top_var_id(comp->var); 02438 if (bestComp == -1 || 02439 bdd_get_level_from_id(info->manager, index) < 02440 bdd_get_level_from_id(info->manager, bestVar)) { 02441 bestVar = index; 02442 bestComp = i; 02443 } 02444 } 02445 break; 02446 } 02447 assert(bestComp != -1); 02448 } 02449 02450 if (splitMethod == 0) 02451 return(bestVar); 02452 else 02453 return(bestComp); 02454 } 02455 02456 02468 static mdd_t * 02469 DomainCofactoring(ImgTfmInfo_t *info, array_t *vector, mdd_t *from, 02470 array_t *relationArray, mdd_t *c, array_t **newVector, 02471 array_t **newRelationArray, mdd_t **cofactorCube, 02472 mdd_t **abstractCube) 02473 { 02474 mdd_t *res, *tmp; 02475 ImgComponent_t *comp, *comp1; 02476 array_t *vector1; 02477 int i, index, n, pos; 02478 mdd_t *newFrom, *var, *nsVar; 02479 mdd_t *cofactor, *abstract, *constIntermediate; 02480 array_t *tmpRelationArray; 02481 st_table *equivTable; 02482 int *ptr, *regularPtr; 02483 int size; 02484 02485 newFrom = mdd_dup(from); 02486 vector1 = array_alloc(ImgComponent_t *, 0); 02487 02488 if (relationArray) { 02489 cofactor = mdd_one(info->manager); 02490 abstract = mdd_one(info->manager); 02491 } else { 02492 cofactor = NIL(mdd_t); 02493 abstract = NIL(mdd_t); 02494 } 02495 02496 if (info->nIntermediateVars) { 02497 size = ImgVectorFunctionSize(vector); 02498 if (size == array_n(vector)) 02499 constIntermediate = NIL(mdd_t); 02500 else 02501 constIntermediate = mdd_one(info->manager); 02502 } else 02503 constIntermediate = NIL(mdd_t); 02504 02505 n = 0; 02506 equivTable = st_init_table(st_ptrcmp, st_ptrhash); 02507 index = (int)bdd_top_var_id(c); 02508 for (i = 0; i < array_n(vector); i++) { 02509 comp = array_fetch(ImgComponent_t *, vector, i); 02510 if (comp->support[index]) 02511 res = bdd_cofactor(comp->func, c); 02512 else 02513 res = mdd_dup(comp->func); 02514 if (bdd_is_tautology(res, 1)) { 02515 if (comp->intermediate) { 02516 tmp = constIntermediate; 02517 constIntermediate = mdd_and(tmp, comp->var, 1, 1); 02518 mdd_free(tmp); 02519 mdd_free(res); 02520 continue; 02521 } 02522 tmp = newFrom; 02523 newFrom = bdd_cofactor(tmp, comp->var); 02524 mdd_free(tmp); 02525 mdd_free(res); 02526 if (relationArray) { 02527 nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 02528 tmp = abstract; 02529 abstract = mdd_and(tmp, nsVar, 1, 1); 02530 mdd_free(tmp); 02531 mdd_free(nsVar); 02532 } 02533 } else if (bdd_is_tautology(res, 0)) { 02534 if (comp->intermediate) { 02535 tmp = constIntermediate; 02536 constIntermediate = mdd_and(tmp, comp->var, 1, 0); 02537 mdd_free(tmp); 02538 mdd_free(res); 02539 continue; 02540 } 02541 tmp = newFrom; 02542 var = mdd_not(comp->var); 02543 newFrom = bdd_cofactor(tmp, var); 02544 mdd_free(tmp); 02545 mdd_free(var); 02546 mdd_free(res); 02547 if (relationArray) { 02548 nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 02549 tmp = abstract; 02550 abstract = mdd_and(tmp, nsVar, 1, 1); 02551 mdd_free(tmp); 02552 mdd_free(nsVar); 02553 } 02554 } else { 02555 if (comp->intermediate) { 02556 comp1 = ImgComponentAlloc(info); 02557 comp1->var = mdd_dup(comp->var); 02558 comp1->func = res; 02559 if (mdd_equal(res, comp->func)) 02560 ImgSupportCopy(info, comp1->support, comp->support); 02561 else 02562 ImgComponentGetSupport(comp1); 02563 comp1->intermediate = 1; 02564 array_insert_last(ImgComponent_t *, vector1, comp1); 02565 n++; 02566 continue; 02567 } 02568 ptr = (int *)bdd_pointer(res); 02569 regularPtr = (int *)((unsigned long)ptr & ~01); 02570 if (st_lookup_int(equivTable, (char *)regularPtr, &pos)) { 02571 comp1 = array_fetch(ImgComponent_t *, vector1, pos); 02572 if (mdd_equal(res, comp1->func)) { 02573 tmp = newFrom; 02574 newFrom = bdd_compose(tmp, comp->var, comp1->var); 02575 mdd_free(tmp); 02576 } else { 02577 tmp = newFrom; 02578 var = mdd_not(comp1->var); 02579 newFrom = bdd_compose(tmp, comp->var, var); 02580 mdd_free(tmp); 02581 mdd_free(var); 02582 } 02583 mdd_free(res); 02584 if (abstract) { 02585 nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 02586 tmp = abstract; 02587 abstract = mdd_and(tmp, nsVar, 1, 1); 02588 mdd_free(tmp); 02589 mdd_free(nsVar); 02590 } 02591 } else { 02592 comp1 = ImgComponentAlloc(info); 02593 comp1->var = mdd_dup(comp->var); 02594 comp1->func = res; 02595 if (mdd_equal(res, comp->func)) 02596 ImgSupportCopy(info, comp1->support, comp->support); 02597 else 02598 ImgComponentGetSupport(comp1); 02599 array_insert_last(ImgComponent_t *, vector1, comp1); 02600 st_insert(equivTable, (char *)regularPtr, (char *)(long)n); 02601 n++; 02602 } 02603 } 02604 } 02605 st_free_table(equivTable); 02606 02607 if (constIntermediate) { 02608 if (!bdd_is_tautology(constIntermediate, 1)) { 02609 mdd_t *tmpCofactor, *tmpAbstract; 02610 02611 if (relationArray) { 02612 vector1 = ImgComposeConstIntermediateVars(info, vector1, 02613 constIntermediate, 02614 &tmpCofactor, &tmpAbstract, 02615 NIL(mdd_t *), &newFrom); 02616 if (!bdd_is_tautology(tmpCofactor, 1)) { 02617 tmp = cofactor; 02618 cofactor = mdd_and(tmp, tmpCofactor, 1, 1); 02619 mdd_free(tmp); 02620 } 02621 mdd_free(tmpCofactor); 02622 if (!bdd_is_tautology(tmpAbstract, 1)) { 02623 tmp = abstract; 02624 abstract = mdd_and(tmp, tmpAbstract, 1, 1); 02625 mdd_free(tmp); 02626 } 02627 mdd_free(tmpAbstract); 02628 tmp = cofactor; 02629 cofactor = mdd_and(tmp, constIntermediate, 1, 1); 02630 mdd_free(tmp); 02631 } else { 02632 vector1 = ImgComposeConstIntermediateVars(info, vector1, 02633 constIntermediate, 02634 NIL(mdd_t *), NIL(mdd_t *), 02635 NIL(mdd_t *), &newFrom); 02636 } 02637 } 02638 mdd_free(constIntermediate); 02639 } 02640 02641 *newVector = vector1; 02642 02643 if (relationArray) { 02644 if (newRelationArray) 02645 *newRelationArray = relationArray; 02646 if (cofactorCube && abstractCube) { 02647 if (cofactor) { 02648 if (bdd_is_tautology(cofactor, 1)) { 02649 mdd_free(cofactor); 02650 *cofactorCube = mdd_dup(c); 02651 } else { 02652 *cofactorCube = mdd_and(cofactor, c, 1, 1); 02653 mdd_free(cofactor); 02654 } 02655 } 02656 if (abstract) 02657 *abstractCube = abstract; 02658 } else { 02659 if (bdd_is_tautology(cofactor, 1)) { 02660 *newRelationArray = ImgGetCofactoredRelationArray(relationArray, c); 02661 mdd_free(cofactor); 02662 } else { 02663 tmp = cofactor; 02664 cofactor = mdd_and(tmp, c, 1, 1); 02665 mdd_free(tmp); 02666 *newRelationArray = ImgGetCofactoredRelationArray(relationArray, 02667 cofactor); 02668 mdd_free(cofactor); 02669 } 02670 if (bdd_is_tautology(abstract, 1)) 02671 mdd_free(abstract); 02672 else { 02673 tmpRelationArray = *newRelationArray; 02674 *newRelationArray = ImgGetAbstractedRelationArray(info->manager, 02675 tmpRelationArray, 02676 abstract); 02677 mdd_free(abstract); 02678 if (tmpRelationArray != relationArray) 02679 mdd_array_free(tmpRelationArray); 02680 } 02681 } 02682 } else 02683 *newRelationArray = NIL(array_t); 02684 02685 return(newFrom); 02686 } 02687 02688 02698 static int 02699 CheckPreImageVector(ImgTfmInfo_t *info, array_t *vector, mdd_t *image) 02700 { 02701 ImgComponent_t *comp, *imgComp; 02702 int i, id, size, status; 02703 02704 status = 1; 02705 if (info->nIntermediateVars) 02706 size = ImgVectorFunctionSize(vector); 02707 else 02708 size = array_n(vector); 02709 if (size != mdd_get_number_of_bdd_support(info->manager, image)) { 02710 fprintf(vis_stderr, 02711 "** tfm error: function vector length is different. (%d != %d)\n", 02712 size, mdd_get_number_of_bdd_support(info->manager, image)); 02713 status = 0; 02714 } 02715 02716 imgComp = ImgComponentAlloc(info); 02717 imgComp->func = image; 02718 ImgComponentGetSupport(imgComp); 02719 for (i = 0; i < array_n(vector); i++) { 02720 comp = array_fetch(ImgComponent_t *, vector, i); 02721 id = (int)bdd_top_var_id(comp->var); 02722 if (comp->intermediate) 02723 imgComp->support[id] = 2; 02724 else if (imgComp->support[id] == 0) { 02725 fprintf(vis_stderr, 02726 "** tfm error: variable index[%d] is not in constraint\n", id); 02727 status = 0; 02728 } else 02729 imgComp->support[id] = 2; 02730 } 02731 for (i = 0; i < info->nVars; i++) { 02732 if (imgComp->support[i] == 1) { 02733 fprintf(vis_stderr, 02734 "** tfm error: variable index[%d] is not in function vector\n", i); 02735 status = 0; 02736 } 02737 } 02738 imgComp->func = NIL(mdd_t); 02739 ImgComponentFree(imgComp); 02740 return(status); 02741 }