VIS
|
00001 00018 #include "absInt.h" 00019 00020 static char rcsid[] UNUSED = "$Id: absRefine.c,v 1.24 2002/09/19 05:25:01 fabio Exp $"; 00021 00022 00023 /*---------------------------------------------------------------------------*/ 00024 /* Macro declarations */ 00025 /*---------------------------------------------------------------------------*/ 00026 00027 /*---------------------------------------------------------------------------*/ 00028 /* Variable declarations */ 00029 /*---------------------------------------------------------------------------*/ 00030 00033 /*---------------------------------------------------------------------------*/ 00034 /* Static function prototypes */ 00035 /*---------------------------------------------------------------------------*/ 00036 00037 static mdd_t * RefineVariable(Abs_VerificationInfo_t *absInfo, AbsVertexInfo_t *vertexPtr, mdd_t *goalSet); 00038 static mdd_t * RefineIdentifier(Abs_VerificationInfo_t *absInfo, AbsVertexInfo_t *vertexPtr, mdd_t *goalSet); 00039 static mdd_t * RefineNot(Abs_VerificationInfo_t *absInfo, AbsVertexInfo_t *vertexPtr, mdd_t *goalSet); 00040 static mdd_t * RefineAnd(Abs_VerificationInfo_t *absInfo, AbsVertexInfo_t *vertexPtr, mdd_t *goalSet); 00041 static mdd_t * RefineFixedPoint(Abs_VerificationInfo_t *absInfo, AbsVertexInfo_t *vertexPtr, mdd_t *goalSet); 00042 static mdd_t * RefineFixedPointIterate(Abs_VerificationInfo_t *absInfo, AbsVertexInfo_t *vertexPtr, mdd_t *goalSet, int iterateNumber); 00043 static mdd_t * RefinePreImage(Abs_VerificationInfo_t *absInfo, AbsVertexInfo_t *vertexPtr, mdd_t *goalSet); 00044 static boolean RestoreContainment(Abs_VerificationInfo_t *absInfo, AbsVertexInfo_t *vertexPtr); 00045 static int PruneIterateVector(Abs_VerificationInfo_t *absInfo, AbsVertexInfo_t *vertexPtr); 00046 static mdd_t * SuccessTest(mdd_t *sat, mdd_t *goalSet, boolean polarity); 00047 00051 /*---------------------------------------------------------------------------*/ 00052 /* Definition of exported functions */ 00053 /*---------------------------------------------------------------------------*/ 00054 00055 00056 /*---------------------------------------------------------------------------*/ 00057 /* Definition of internal functions */ 00058 /*---------------------------------------------------------------------------*/ 00059 00073 mdd_t * 00074 AbsSubFormulaRefine( 00075 Abs_VerificationInfo_t *absInfo, 00076 AbsVertexInfo_t *vertexPtr, 00077 mdd_t *goalSet) 00078 { 00079 AbsStats_t *stats; 00080 mdd_manager *mddManager; 00081 mdd_t *oldTmpCareSet = NIL(mdd_t); 00082 mdd_t *realGoalSet; 00083 mdd_t *result; 00084 long verbosity; 00085 00086 verbosity = AbsOptionsReadVerbosity(AbsVerificationInfoReadOptions(absInfo)); 00087 stats = AbsVerificationInfoReadStats(absInfo); 00088 mddManager = AbsVerificationInfoReadMddManager(absInfo); 00089 00090 if (verbosity & ABS_VB_REFINE) { 00091 (void) fprintf(vis_stdout, "ABS: Beginning Refinement of Vertex(%3d)\n", 00092 AbsVertexReadId(vertexPtr)); 00093 } 00094 00095 /* If the goal set is empty, do not refine */ 00096 if (mdd_is_tautology(goalSet, 0)) { 00097 00098 if (verbosity & ABS_VB_GOALSZ) { 00099 (void) fprintf(vis_stdout, 00100 "ABS: Empty Goal in Refinement of Vertex(%3d)\n", 00101 AbsVertexReadId(vertexPtr)); 00102 } 00103 00104 /* Set the refine flag */ 00105 AbsVertexSetTrueRefine(vertexPtr, TRUE); 00106 00107 return mdd_dup(goalSet); 00108 } 00109 00110 realGoalSet = SuccessTest(AbsVertexReadSat(vertexPtr), goalSet, 00111 AbsVertexReadPolarity(vertexPtr)); 00112 00113 /* If the vertex is refined already do not try to refine it */ 00114 if (mdd_is_tautology(realGoalSet, 0) || 00115 !AbsVertexReadGlobalApprox(vertexPtr)) { 00116 00117 if (verbosity & ABS_VB_GOALSZ) { 00118 (void) fprintf(vis_stdout, 00119 "ABS: Quick (%d,%d) Refinement of Vertex(%3d)\n", 00120 mdd_is_tautology(realGoalSet, 0)? 1: 0, 00121 AbsVertexReadGlobalApprox(vertexPtr)? 0: 1, 00122 AbsVertexReadId(vertexPtr)); 00123 } 00124 00125 AbsVertexSetTrueRefine(vertexPtr, TRUE); 00126 return realGoalSet; 00127 } 00128 00129 if (verbosity & ABS_VB_GOALSZ) { 00130 (void) fprintf(vis_stdout, "ABS: Received Goal Set-> "); 00131 (void) fprintf(vis_stdout, "%d Nodes\n", 00132 mdd_size(realGoalSet)); 00133 if (verbosity & ABS_VB_GLCUBE) { 00134 AbsBddPrintMinterms(realGoalSet); 00135 } 00136 } 00137 00138 mdd_free(realGoalSet); 00139 00140 /* If the current vertex has more than one parent, the temporary care set 00141 * must be reset (because it depends on the path that led to this vertex) */ 00142 if (lsLength(vertexPtr->parent) > 1) { 00143 oldTmpCareSet = AbsVerificationInfoReadTmpCareSet(absInfo); 00144 AbsVerificationInfoSetTmpCareSet(absInfo, mdd_one(mddManager)); 00145 } 00146 00147 switch (AbsVertexReadType(vertexPtr)) { 00148 case fixedPoint_c: 00149 result = RefineFixedPoint(absInfo, vertexPtr, goalSet); 00150 AbsStatsReadRefineFixedPoint(stats)++; 00151 break; 00152 case and_c: 00153 result = RefineAnd(absInfo, vertexPtr, goalSet); 00154 AbsStatsReadRefineAnd(stats)++; 00155 break; 00156 case not_c: 00157 result = RefineNot(absInfo, vertexPtr, goalSet); 00158 AbsStatsReadRefineNot(stats)++; 00159 break; 00160 case preImage_c: 00161 result = RefinePreImage(absInfo, vertexPtr, goalSet); 00162 AbsStatsReadRefinePreImage(stats)++; 00163 break; 00164 case identifier_c: 00165 result = RefineIdentifier(absInfo, vertexPtr, goalSet); 00166 AbsStatsReadRefineIdentifier(stats)++; 00167 break; 00168 case variable_c: 00169 result = RefineVariable(absInfo, vertexPtr, goalSet); 00170 AbsStatsReadRefineVariable(stats)++; 00171 break; 00172 default: fail("Encountered unknown type of vertex\n"); 00173 } 00174 00175 if (verbosity & ABS_VB_REFINE) { 00176 (void) fprintf(vis_stdout, 00177 "ABS: Done Refining Vertex(%3d).\n", 00178 AbsVertexReadId(vertexPtr)); 00179 } 00180 00181 if (verbosity & ABS_VB_GOALSZ) { 00182 (void) fprintf(vis_stdout, "ABS: Returned Goal Set-> "); 00183 (void) fprintf(vis_stdout, "%d Nodes\n", 00184 mdd_size(result)); 00185 if (verbosity & ABS_VB_GLCUBE) { 00186 AbsBddPrintMinterms(result); 00187 } 00188 } 00189 00190 if (verbosity & ABS_VB_REFVTX) { 00191 AbsVertexPrint(vertexPtr, NIL(st_table), FALSE, verbosity); 00192 } 00193 00194 if (lsLength(vertexPtr->parent) > 1) { 00195 /* Restore the old temporary careset */ 00196 mdd_free(AbsVerificationInfoReadTmpCareSet(absInfo)); 00197 AbsVerificationInfoSetTmpCareSet(absInfo, oldTmpCareSet); 00198 } 00199 00200 return result; 00201 } /* End of AbsSubFormulaRefine */ 00202 00203 /*---------------------------------------------------------------------------*/ 00204 /* Definition of static functions */ 00205 /*---------------------------------------------------------------------------*/ 00206 00225 static mdd_t * 00226 RefineVariable( 00227 Abs_VerificationInfo_t *absInfo, 00228 AbsVertexInfo_t *vertexPtr, 00229 mdd_t *goalSet) 00230 { 00231 /* Set the current goalSet. If the pointer is non-empty, that means that the 00232 variable belongs to a different pointer from the one being considered, 00233 therefore, only the first goal set is of interest to us.*/ 00234 if (AbsVertexReadGoalSet(vertexPtr) == NIL(mdd_t)) { 00235 AbsVertexSetGoalSet(vertexPtr, mdd_dup(goalSet)); 00236 } 00237 00238 /* Set the validity of the refinement */ 00239 AbsVertexSetTrueRefine(vertexPtr, !AbsVertexReadGlobalApprox(vertexPtr)); 00240 00241 return mdd_dup(goalSet); 00242 } /* End of RefineVariable */ 00243 00253 static mdd_t * 00254 RefineIdentifier( 00255 Abs_VerificationInfo_t *absInfo, 00256 AbsVertexInfo_t *vertexPtr, 00257 mdd_t *goalSet) 00258 { 00259 /* Set the refinement flags */ 00260 AbsVertexSetTrueRefine(vertexPtr, TRUE); 00261 00262 /* 00263 * If the polarity of this vertex is negative, we need to add states to 00264 * the satisfying set. Since we already have the exact set, the states not 00265 * in it are the returned goal. If the polarity is positive, we need to 00266 * remove states. The states of the incoming goal that are in the 00267 * satisfying set are the returned goal. 00268 */ 00269 if (AbsVertexReadPolarity(vertexPtr)) { 00270 return mdd_and(goalSet, AbsVertexReadSat(vertexPtr), 1, 1); 00271 } else { 00272 return mdd_and(goalSet, AbsVertexReadSat(vertexPtr), 1, 0); 00273 } 00274 } /* End of RefineIdentifier */ 00275 00285 static mdd_t * 00286 RefineNot( 00287 Abs_VerificationInfo_t *absInfo, 00288 AbsVertexInfo_t *vertexPtr, 00289 mdd_t *goalSet) 00290 { 00291 AbsVertexInfo_t *subFormula; 00292 mdd_t *result; 00293 00294 /* The not vertex has a trivial propagation equation */ 00295 subFormula = AbsVertexReadLeftKid(vertexPtr); 00296 00297 /* Go ahead and re-evaluate */ 00298 mdd_free(AbsVertexReadSat(vertexPtr)); 00299 00300 /* Refine recursively */ 00301 result = AbsSubFormulaRefine(absInfo, subFormula, goalSet); 00302 00303 /* Set the set sat */ 00304 AbsVertexSetSat(vertexPtr, mdd_not(AbsVertexReadSat(subFormula))); 00305 00306 /* Set the approximation flags */ 00307 AbsVertexSetLocalApprox(vertexPtr, FALSE); 00308 AbsVertexSetGlobalApprox(vertexPtr, AbsVertexReadGlobalApprox(subFormula)); 00309 00310 /* Set the trueRefine flag */ 00311 AbsVertexSetTrueRefine(vertexPtr, AbsVertexReadTrueRefine(subFormula)); 00312 00313 assert(mdd_lequal(result, goalSet, 1, 1)); 00314 00315 return result; 00316 } /* End of RefineNot */ 00317 00327 static mdd_t * 00328 RefineAnd( 00329 Abs_VerificationInfo_t *absInfo, 00330 AbsVertexInfo_t *vertexPtr, 00331 mdd_t *goalSet) 00332 { 00333 AbsVertexInfo_t *firstFormula; 00334 AbsVertexInfo_t *secondFormula; 00335 mdd_t *kidFirstResult; 00336 mdd_t *conjunction; 00337 mdd_t *result; 00338 mdd_t *oldTmpCareSet; 00339 00340 /* Delete the old sat */ 00341 mdd_free(AbsVertexReadSat(vertexPtr)); 00342 00343 /* Obtain the Sub-formulas */ 00344 firstFormula = AbsVertexReadLeftKid(vertexPtr); 00345 secondFormula = AbsVertexReadRightKid(vertexPtr); 00346 00347 kidFirstResult = AbsSubFormulaRefine(absInfo, firstFormula, goalSet); 00348 00349 /* Store the temporary careset and set the new one */ 00350 oldTmpCareSet = AbsVerificationInfoReadTmpCareSet(absInfo); 00351 AbsVerificationInfoSetTmpCareSet(absInfo, 00352 mdd_and(oldTmpCareSet, 00353 AbsVertexReadSat(firstFormula), 00354 1,1)); 00355 00356 if (AbsVertexReadPolarity(vertexPtr)) { 00357 /* 00358 * Positive polarity: The goal set is given to one sub-formula first for 00359 * refinement, and the left-overs are given to the second sub-formula. 00360 */ 00361 result = AbsSubFormulaRefine(absInfo, secondFormula, kidFirstResult); 00362 mdd_free(kidFirstResult); 00363 } 00364 else { /* Vertex with negative polarity */ 00365 mdd_t *kidSecondResult; 00366 mdd_t *reducedGoalSet; 00367 00368 reducedGoalSet = mdd_and(goalSet, AbsVertexReadSat(firstFormula), 1, 1); 00369 kidSecondResult = AbsSubFormulaRefine(absInfo, secondFormula, 00370 reducedGoalSet); 00371 result = mdd_or(kidFirstResult, kidSecondResult, 1, 1); 00372 00373 mdd_free(reducedGoalSet); 00374 mdd_free(kidFirstResult); 00375 mdd_free(kidSecondResult); 00376 } 00377 00378 /* Restore the temporary careset */ 00379 mdd_free(AbsVerificationInfoReadTmpCareSet(absInfo)); 00380 AbsVerificationInfoSetTmpCareSet(absInfo, oldTmpCareSet); 00381 00382 /* Re-evaluate the vertex just in case there has been some refinement */ 00383 conjunction = mdd_and(AbsVertexReadSat(firstFormula), 00384 AbsVertexReadSat(secondFormula), 1, 1); 00385 00386 /* Store the new Sat value */ 00387 AbsVertexSetSat(vertexPtr, conjunction); 00388 00389 /* Set the approximation flags */ 00390 AbsVertexSetLocalApprox(vertexPtr, FALSE); 00391 AbsVertexSetGlobalApprox(vertexPtr, 00392 AbsVertexReadGlobalApprox(firstFormula) || 00393 AbsVertexReadGlobalApprox(secondFormula)); 00394 00395 /* Set the refinement flags */ 00396 AbsVertexSetTrueRefine(vertexPtr, AbsVertexReadTrueRefine(firstFormula) && 00397 AbsVertexReadTrueRefine(secondFormula)); 00398 00399 assert(mdd_lequal(result, goalSet, 1, 1)); 00400 00401 return result; 00402 } /* End of RefineAnd */ 00403 00417 static mdd_t * 00418 RefineFixedPoint( 00419 Abs_VerificationInfo_t *absInfo, 00420 AbsVertexInfo_t *vertexPtr, 00421 mdd_t *goalSet) 00422 { 00423 boolean newIterates; 00424 mdd_t *currentGoalSet; 00425 mdd_t *result; 00426 mdd_t *oldTmpCareSet; 00427 mdd_t *newTmpCareSet; 00428 mdd_t *oneMdd; 00429 int numIterates; 00430 00431 /* Variable initialization */ 00432 numIterates = array_n(AbsVertexReadRings(vertexPtr)) - 1; 00433 newIterates = TRUE; 00434 00435 /* Delete the previous result */ 00436 if (AbsVertexReadSat(vertexPtr) != NIL(mdd_t)) { 00437 mdd_free(AbsVertexReadSat(vertexPtr)); 00438 } 00439 00440 /* Set the new care set */ 00441 oldTmpCareSet = AbsVerificationInfoReadTmpCareSet(absInfo); 00442 newTmpCareSet = mdd_one(AbsVerificationInfoReadMddManager(absInfo)); 00443 AbsVerificationInfoSetTmpCareSet(absInfo, newTmpCareSet); 00444 00445 oneMdd = mdd_one(AbsVerificationInfoReadMddManager(absInfo)); 00446 currentGoalSet = mdd_dup(oneMdd); 00447 /* While the fixed point has not been approximated exactly */ 00448 while (newIterates && AbsVertexReadGlobalApprox(vertexPtr) 00449 && !mdd_is_tautology(currentGoalSet, 0)) { 00450 mdd_t *newGoalSet; 00451 boolean pruneIterates; 00452 00453 newGoalSet = RefineFixedPointIterate(absInfo, vertexPtr, currentGoalSet, 00454 numIterates); 00455 00456 /* Release unnecessary functions */ 00457 mdd_free(newGoalSet); 00458 mdd_free(currentGoalSet); 00459 00460 /* Restore the inclusion property in the fixed point iterates */ 00461 pruneIterates = RestoreContainment(absInfo, vertexPtr); 00462 00463 /* Remove redundant iterates */ 00464 if (pruneIterates) { 00465 numIterates = PruneIterateVector(absInfo, vertexPtr); 00466 } 00467 00468 /* Sanity check of the refinement process */ 00469 assert(AbsIteratesSanityCheck(absInfo, vertexPtr)); 00470 00471 /* Check if further iteration is required */ 00472 newIterates = AbsFixedPointIterate(absInfo, vertexPtr, numIterates); 00473 numIterates = array_n(AbsVertexReadRings(vertexPtr)) - 1; 00474 00475 currentGoalSet = SuccessTest(AbsVertexFetchRing(vertexPtr, numIterates), 00476 oneMdd, AbsVertexReadPolarity(vertexPtr)); 00477 } /* End of while loop */ 00478 00479 mdd_free(oneMdd); 00480 00481 /* Restore the old temporary careset */ 00482 mdd_free(newTmpCareSet); 00483 AbsVerificationInfoSetTmpCareSet(absInfo, oldTmpCareSet); 00484 00485 AbsVertexSetSat(vertexPtr, 00486 mdd_dup(AbsVertexFetchRing(vertexPtr, numIterates))); 00487 00488 AbsVertexSetLocalApprox(vertexPtr, FALSE); 00489 AbsVertexSetGlobalApprox(vertexPtr, 00490 AbsVertexFetchSubApprox(vertexPtr, numIterates)); 00491 00492 result = mdd_and(currentGoalSet, goalSet, 1, 1); 00493 mdd_free(currentGoalSet); 00494 return result; 00495 } /* End of RefineFixedPoint */ 00496 00507 static mdd_t * 00508 RefineFixedPointIterate( 00509 Abs_VerificationInfo_t *absInfo, 00510 AbsVertexInfo_t *vertexPtr, 00511 mdd_t *goalSet, 00512 int iterateNumber) 00513 { 00514 AbsVertexInfo_t *varFormula; 00515 AbsVertexInfo_t *subFormula; 00516 boolean trueRefine; 00517 mdd_t *careSet; 00518 mdd_t *variableValue; 00519 mdd_t *result; 00520 mdd_t *previousGoal; 00521 mdd_t *refinedGoal; 00522 mdd_t *newIterate; 00523 mdd_t *oldIterate; 00524 mdd_t *subFormulaSat; 00525 int saveExact; 00526 00527 assert(iterateNumber != 0); 00528 00529 /* Variable initialization */ 00530 varFormula = AbsVertexReadFpVar(vertexPtr); 00531 subFormula = AbsVertexReadLeftKid(vertexPtr); 00532 careSet = AbsVerificationInfoReadCareSet(absInfo); 00533 oldIterate = AbsVertexFetchRing(vertexPtr, iterateNumber); 00534 00535 /* Propagate the goalSet for refinement */ 00536 variableValue = AbsVertexFetchRing(vertexPtr, iterateNumber - 1); 00537 00538 AbsVertexSetSat(varFormula, variableValue); 00539 00540 AbsVertexSetGlobalApprox(varFormula, 00541 AbsVertexFetchSubApprox(vertexPtr, 00542 iterateNumber - 1)); 00543 00544 /* Schedule the formula for Re-evaluation */ 00545 AbsFormulaScheduleEvaluation(varFormula, vertexPtr); 00546 00547 /* Evaluate the sub-formula again */ 00548 AbsSubFormulaVerify(absInfo, subFormula); 00549 00550 /* Set the goal to empty to detect if the refinement reaches it */ 00551 if (AbsVertexReadGoalSet(varFormula) != NIL(mdd_t)) { 00552 mdd_free(AbsVertexReadGoalSet(varFormula)); 00553 AbsVertexSetGoalSet(varFormula, NIL(mdd_t)); 00554 } 00555 00556 /* Refine the sub-formula for this iterate */ 00557 result = AbsSubFormulaRefine(absInfo, subFormula, goalSet); 00558 00559 /* Read the trueRefine from the subFormula */ 00560 trueRefine = AbsVertexReadTrueRefine(subFormula); 00561 00562 /* If The refinement does not need a recursive step, return. The return may 00563 * be for three different reasons: 00564 * a) The local refinement that was just done, succeeded completely. 00565 * b) The goalset in varFormula is NIL, which means, the refinement 00566 process failed somewhere earlier in the process, and therefore, the 00567 false result was computed without the refinement of the variable. 00568 c) trueRefine is TRUE. Which means, that even though the approximate 00569 flag in the vertex is TRUE, meaning that there has been an 00570 approximation, the refinement is still solid 00571 */ 00572 if (mdd_is_tautology(result, 0) || trueRefine || 00573 AbsVertexReadGoalSet(varFormula) == NIL(mdd_t)) { 00574 00575 subFormulaSat = AbsVertexReadSat(subFormula); 00576 if (AbsVertexReadPolarity(vertexPtr)) { 00577 if (AbsMddLEqualModCareSet(subFormulaSat, oldIterate, careSet)) { 00578 newIterate = mdd_dup(subFormulaSat); 00579 } 00580 else { 00581 newIterate = mdd_and(subFormulaSat, oldIterate, 1, 1); 00582 } 00583 } 00584 else { 00585 if (AbsMddLEqualModCareSet(oldIterate, subFormulaSat, careSet)) { 00586 newIterate = mdd_dup(subFormulaSat); 00587 } 00588 else { 00589 newIterate = mdd_or(subFormulaSat, oldIterate, 1, 1); 00590 } 00591 } 00592 00593 mdd_free(oldIterate); 00594 array_insert(mdd_t *, AbsVertexReadRings(vertexPtr), iterateNumber, 00595 newIterate); 00596 00597 /* Set the new approx flag */ 00598 array_insert(boolean, AbsVertexReadSubApprox(vertexPtr), iterateNumber, 00599 AbsVertexReadGlobalApprox(subFormula)); 00600 00601 AbsVertexSetTrueRefine(vertexPtr, trueRefine); 00602 00603 return result; 00604 } 00605 00606 /* Recursive call to refine the previous iterate */ 00607 previousGoal = mdd_dup(AbsVertexReadGoalSet(varFormula)); 00608 refinedGoal = RefineFixedPointIterate(absInfo, vertexPtr, previousGoal, 00609 iterateNumber - 1); 00610 00611 trueRefine = AbsVertexReadTrueRefine(vertexPtr); 00612 00613 /* 00614 * Due to the refinement of the previous iterate, convergence might have 00615 * been reached 00616 */ 00617 if (iterateNumber > 1) { 00618 mdd_t *ring1 = AbsVertexFetchRing(vertexPtr, iterateNumber - 1); 00619 mdd_t *ring2 = AbsVertexFetchRing(vertexPtr, iterateNumber - 2); 00620 if (AbsMddLEqualModCareSet(ring1, ring2, careSet)) { 00621 mdd_free(previousGoal); 00622 mdd_free(refinedGoal); 00623 mdd_free(oldIterate); 00624 mdd_free(result); 00625 00626 array_insert(mdd_t *, AbsVertexReadRings(vertexPtr), iterateNumber, 00627 mdd_dup(AbsVertexFetchRing(vertexPtr, iterateNumber - 1))); 00628 00629 AbsVertexSetTrueRefine(vertexPtr, trueRefine); 00630 00631 /* Set the new approx flag */ 00632 array_insert(boolean, AbsVertexReadSubApprox(vertexPtr), iterateNumber, 00633 AbsVertexReadGlobalApprox(subFormula)); 00634 00635 return SuccessTest(AbsVertexFetchRing(vertexPtr, iterateNumber), 00636 goalSet, AbsVertexReadPolarity(vertexPtr)); 00637 } 00638 } 00639 00640 mdd_free(previousGoal); 00641 mdd_free(refinedGoal); 00642 00643 /* Evaluate the sub-formula exactly */ 00644 variableValue = AbsVertexFetchRing(vertexPtr, iterateNumber - 1); 00645 00646 AbsVertexSetSat(varFormula, variableValue); 00647 mdd_free(result); 00648 00649 AbsVertexSetGlobalApprox(varFormula, 00650 AbsVertexFetchSubApprox(vertexPtr, 00651 iterateNumber - 1)); 00652 00653 /* Schedule the formula for Re-evaluation */ 00654 AbsFormulaScheduleEvaluation(varFormula, vertexPtr); 00655 00656 /* Evaluate the sub-formula this time exactly */ 00657 saveExact = AbsOptionsReadExact(AbsVerificationInfoReadOptions(absInfo)); 00658 AbsOptionsSetExact(AbsVerificationInfoReadOptions(absInfo), TRUE); 00659 AbsSubFormulaVerify(absInfo, subFormula); 00660 AbsOptionsSetExact(AbsVerificationInfoReadOptions(absInfo), saveExact); 00661 00662 /* Enforce monotonicity of the approximants */ 00663 subFormulaSat = AbsVertexReadSat(subFormula); 00664 if (AbsVertexReadPolarity(vertexPtr)) { 00665 if (AbsMddLEqualModCareSet(subFormulaSat, oldIterate, careSet)) { 00666 newIterate = mdd_dup(subFormulaSat); 00667 } 00668 else { 00669 newIterate = mdd_and(subFormulaSat, oldIterate, 1, 1); 00670 } 00671 } 00672 else { 00673 if (AbsMddLEqualModCareSet(oldIterate, subFormulaSat, careSet)) { 00674 newIterate = mdd_dup(subFormulaSat); 00675 } 00676 else { 00677 newIterate = mdd_or(subFormulaSat, oldIterate, 1, 1); 00678 } 00679 } 00680 00681 /* Set the new approx flag */ 00682 array_insert(boolean, AbsVertexReadSubApprox(vertexPtr), iterateNumber, 00683 AbsVertexReadGlobalApprox(subFormula)); 00684 00685 /* Recompute the goal set and the iterate */ 00686 result = SuccessTest(newIterate, goalSet, 00687 AbsVertexReadPolarity(vertexPtr)); 00688 00689 /* Some basic sanity check */ 00690 assert(AbsVertexReadPolarity(vertexPtr)? 00691 AbsMddLEqualModCareSet(newIterate, oldIterate, careSet): 00692 AbsMddLEqualModCareSet(oldIterate, newIterate, careSet)); 00693 00694 /* Store the new iterate */ 00695 mdd_free(oldIterate); 00696 array_insert(mdd_t *, AbsVertexReadRings(vertexPtr), iterateNumber, 00697 newIterate); 00698 00699 /* Set the new approx flag */ 00700 array_insert(boolean, AbsVertexReadSubApprox(vertexPtr), iterateNumber, 00701 AbsVertexReadGlobalApprox(subFormula)); 00702 00703 AbsVertexSetTrueRefine(vertexPtr, trueRefine); 00704 00705 return result; 00706 } /* End of RefineFixedPointIterate */ 00707 00717 static mdd_t * 00718 RefinePreImage( 00719 Abs_VerificationInfo_t *absInfo, 00720 AbsVertexInfo_t *vertexPtr, 00721 mdd_t *goalSet) 00722 { 00723 AbsStats_t *stats; 00724 AbsVertexInfo_t *subFormula; 00725 Img_ImageInfo_t *imageInfo; 00726 Fsm_Fsm_t *system; 00727 mdd_t *careSet; 00728 mdd_t *result; 00729 mdd_t *subResult; 00730 mdd_t *newGoalSet; 00731 mdd_t *oldTmpCareSet; 00732 mdd_t *preImage; 00733 00734 /* Variable initialization */ 00735 system = AbsVerificationInfoReadFsm(absInfo); 00736 subFormula = AbsVertexReadLeftKid(vertexPtr); 00737 subResult = AbsVertexReadSat(subFormula); 00738 stats = AbsVerificationInfoReadStats(absInfo); 00739 imageInfo = Fsm_FsmReadOrCreateImageInfo(system, 1, 1); 00740 careSet = mdd_and(AbsVerificationInfoReadCareSet(absInfo), 00741 AbsVerificationInfoReadTmpCareSet(absInfo), 1, 1); 00742 00743 /* Propagate the goal set */ 00744 newGoalSet = AbsImageReadOrCompute(absInfo, imageInfo, goalSet, subResult); 00745 00746 /* Store the new care set */ 00747 oldTmpCareSet = AbsVerificationInfoReadTmpCareSet(absInfo); 00748 AbsVerificationInfoSetTmpCareSet(absInfo, 00749 mdd_one(AbsVerificationInfoReadMddManager(absInfo))); 00750 00751 /* Refine recursively */ 00752 result = AbsSubFormulaRefine(absInfo, subFormula, newGoalSet); 00753 00754 /* Restore the old temporary careset */ 00755 mdd_free(AbsVerificationInfoReadTmpCareSet(absInfo)); 00756 AbsVerificationInfoSetTmpCareSet(absInfo, oldTmpCareSet); 00757 00758 if (!mdd_equal(result, newGoalSet) || 00759 !AbsVertexReadGlobalApprox(subFormula)) { 00760 mdd_free(AbsVertexReadSat(vertexPtr)); 00761 00762 if (AbsVertexReadSolutions(vertexPtr) == NIL(st_table)) { 00763 /* Initialize the cache */ 00764 AbsVertexSetSolutions(vertexPtr, st_init_table(st_ptrcmp, st_ptrhash)); 00765 } 00766 00767 preImage = NIL(mdd_t); 00768 if (AbsEvalCacheLookup(AbsVertexReadSolutions(vertexPtr), 00769 AbsVertexReadSat(subFormula), careSet, FALSE, 00770 &preImage, 0)) { 00771 00772 /* Set the sat */ 00773 AbsVertexSetSat(vertexPtr, mdd_dup(preImage)); 00774 } 00775 else { 00776 long cpuTime; 00777 00778 subResult = AbsVertexReadSat(subFormula); 00779 00780 cpuTime = util_cpu_time(); 00781 AbsVertexSetSat(vertexPtr, 00782 Img_ImageInfoComputeBwdWithDomainVars(imageInfo, 00783 subResult, 00784 subResult, 00785 careSet)); 00786 AbsStatsReadPreImageCpuTime(stats)+= util_cpu_time() - cpuTime; 00787 00788 AbsStatsReadExactPreImage(stats)++; 00789 00790 /* Insert the result in the cache */ 00791 AbsEvalCacheInsert(AbsVertexReadSolutions(vertexPtr), 00792 AbsVertexReadSat(subFormula), 00793 AbsVertexReadSat(vertexPtr), careSet, 00794 FALSE, FALSE); 00795 00796 } 00797 /* Set the new approximation flags */ 00798 AbsVertexSetLocalApprox(vertexPtr, FALSE); 00799 AbsVertexSetGlobalApprox(vertexPtr, 00800 AbsVertexReadGlobalApprox(subFormula)); 00801 } /* If !mdd_equal || !GlobalApprox(subFormula) */ 00802 mdd_free(careSet); 00803 mdd_free(newGoalSet); 00804 mdd_free(result); 00805 00806 result = SuccessTest(AbsVertexReadSat(vertexPtr), goalSet, 00807 AbsVertexReadPolarity(vertexPtr)); 00808 00809 AbsVertexSetTrueRefine(vertexPtr, 00810 AbsVertexReadTrueRefine(subFormula)); 00811 00812 return result; 00813 } /* End of RefinePreImage */ 00814 00832 static boolean 00833 RestoreContainment( 00834 Abs_VerificationInfo_t *absInfo, 00835 AbsVertexInfo_t *vertexPtr) 00836 { 00837 mdd_t *iterateMdd; 00838 mdd_t *iterateMddPrevious; 00839 mdd_t *product; 00840 boolean convergence; 00841 int numIterates; 00842 int index; 00843 00844 convergence = FALSE; 00845 numIterates = array_n(AbsVertexReadRings(vertexPtr)) - 1; 00846 00847 if (AbsVertexReadPolarity(vertexPtr)) { 00848 iterateMddPrevious = AbsVertexFetchRing(vertexPtr, numIterates); 00849 00850 for(index = numIterates - 1; index >= 0; index--) { 00851 iterateMdd = iterateMddPrevious; 00852 iterateMddPrevious = AbsVertexFetchRing(vertexPtr, index); 00853 00854 if (!AbsMddLEqualModCareSet(iterateMddPrevious, iterateMdd, 00855 AbsVerificationInfoReadCareSet(absInfo))) { 00856 product = mdd_and(iterateMddPrevious, iterateMdd, 1, 1); 00857 00858 /* Add here don't care minimization */ 00859 00860 mdd_free(iterateMddPrevious); 00861 array_insert(mdd_t *, AbsVertexReadRings(vertexPtr), index, product); 00862 iterateMddPrevious = product; 00863 } 00864 00865 if (index != numIterates - 1 && 00866 AbsMddLEqualModCareSet(iterateMdd, iterateMddPrevious, 00867 AbsVerificationInfoReadCareSet(absInfo))) { 00868 convergence = TRUE; 00869 } 00870 } 00871 } 00872 else { 00873 iterateMdd = AbsVertexFetchRing(vertexPtr, 0); 00874 00875 for(index = 1; index <= numIterates; index++) { 00876 iterateMddPrevious = iterateMdd; 00877 iterateMdd = AbsVertexFetchRing(vertexPtr, index); 00878 00879 if (!AbsMddLEqualModCareSet(iterateMddPrevious, iterateMdd, 00880 AbsVerificationInfoReadCareSet(absInfo))) { 00881 product = mdd_or(iterateMddPrevious, iterateMdd, 1, 1); 00882 00883 /* Add here don't care minimization */ 00884 00885 mdd_free(iterateMdd); 00886 array_insert(mdd_t *, AbsVertexReadRings(vertexPtr), index, product); 00887 iterateMdd = product; 00888 } 00889 00890 if (index != numIterates && 00891 AbsMddLEqualModCareSet(iterateMdd, iterateMddPrevious, 00892 AbsVerificationInfoReadCareSet(absInfo))) { 00893 convergence = TRUE; 00894 } 00895 } 00896 } 00897 00898 return convergence; 00899 } /* End of RestoreContainment */ 00900 00916 static int 00917 PruneIterateVector( 00918 Abs_VerificationInfo_t *absInfo, 00919 AbsVertexInfo_t *vertexPtr) 00920 { 00921 array_t *newRings; 00922 array_t *newRingApprox; 00923 array_t *newSubApprox; 00924 mdd_t *current; 00925 mdd_t *previous; 00926 mdd_t *careSet; 00927 int numIterates; 00928 int index; 00929 00930 /* Read the care Set */ 00931 careSet = AbsVerificationInfoReadCareSet(absInfo); 00932 00933 /* Read the number of iterates initially in the vertex */ 00934 numIterates = array_n(AbsVertexReadRings(vertexPtr)) - 1; 00935 assert(numIterates > 0); 00936 00937 /* If there are only two iterates, no pruning is needed */ 00938 if (numIterates < 2) { 00939 return numIterates; 00940 } 00941 00942 /* Allocate the new arrays to store the new iterates */ 00943 newRings = array_alloc(mdd_t *, 0); 00944 newRingApprox = array_alloc(boolean, 0); 00945 newSubApprox = array_alloc(boolean, 0); 00946 00947 /* Initial values for the loop */ 00948 index = 1; 00949 previous = AbsVertexFetchRing(vertexPtr, index - 1); 00950 current = AbsVertexFetchRing(vertexPtr, index); 00951 array_insert_last(mdd_t *, newRings, mdd_dup(previous)); 00952 array_insert_last(boolean, newRingApprox, 00953 AbsVertexFetchRingApprox(vertexPtr, index - 1)); 00954 array_insert_last(boolean, newSubApprox, 00955 AbsVertexFetchSubApprox(vertexPtr, index - 1)); 00956 00957 /* Traverse the set of iterates */ 00958 while (index < numIterates && 00959 !AbsMddLEqualModCareSet(current, previous, careSet)) { 00960 array_insert_last(mdd_t *, newRings, mdd_dup(current)); 00961 array_insert_last(boolean, newRingApprox, 00962 AbsVertexFetchRingApprox(vertexPtr, index)); 00963 array_insert_last(boolean, newSubApprox, 00964 AbsVertexFetchSubApprox(vertexPtr, index)); 00965 index++; 00966 previous = current; 00967 current = AbsVertexFetchRing(vertexPtr, index); 00968 } 00969 00970 /* Insert the last two elements of the array */ 00971 array_insert_last(mdd_t *, newRings, mdd_dup(current)); 00972 array_insert_last(boolean, newRingApprox, 00973 AbsVertexFetchRingApprox(vertexPtr, index)); 00974 array_insert_last(boolean, newSubApprox, 00975 AbsVertexFetchSubApprox(vertexPtr, index)); 00976 00977 /* Free the arrays stored in the vertex and store the new ones */ 00978 arrayForEachItem(mdd_t *, AbsVertexReadRings(vertexPtr), index, current) { 00979 mdd_free(current); 00980 } 00981 array_free(AbsVertexReadRings(vertexPtr)); 00982 array_free(AbsVertexReadRingApprox(vertexPtr)); 00983 array_free(AbsVertexReadSubApprox(vertexPtr)); 00984 00985 /* Store the new results */ 00986 AbsVertexSetRings(vertexPtr, newRings); 00987 AbsVertexSetRingApprox(vertexPtr, newRingApprox); 00988 AbsVertexSetSubApprox(vertexPtr, newSubApprox); 00989 00990 assert(array_n(newRings) == array_n(newRingApprox)); 00991 assert(array_n(newRings) == array_n(newSubApprox)); 00992 00993 return array_n(newRings) - 1; 00994 } /* End of PruneIterateVector */ 00995 01006 static mdd_t * 01007 SuccessTest( 01008 mdd_t *sat, 01009 mdd_t *goalSet, 01010 boolean polarity) 01011 { 01012 mdd_t *result; 01013 01014 if (polarity) { 01015 result = mdd_and(goalSet, sat, 1, 1); 01016 } 01017 else { 01018 result = mdd_and(goalSet, sat, 1, 0); 01019 } 01020 01021 return result; 01022 } /* End of SuccessTest */