VIS
|
00001 00018 #include "absInt.h" 00019 00020 static char rcsid[] UNUSED = "$Id: absEvaluate.c,v 1.19 2002/09/19 05:25:00 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 void EvaluateVariable(Abs_VerificationInfo_t *absInfo, AbsVertexInfo_t *vertexPtr); 00038 static void EvaluateIdentifier(Abs_VerificationInfo_t *absInfo, AbsVertexInfo_t *vertexPtr); 00039 static void EvaluateNot(Abs_VerificationInfo_t *absInfo, AbsVertexInfo_t *vertexPtr); 00040 static void EvaluateAnd(Abs_VerificationInfo_t *absInfo, AbsVertexInfo_t *vertexPtr); 00041 static void EvaluateFixedPoint(Abs_VerificationInfo_t *absInfo, AbsVertexInfo_t *vertexPtr); 00042 static void EvaluatePreImage(Abs_VerificationInfo_t *absInfo, AbsVertexInfo_t *vertexPtr); 00043 static mdd_t * OverApproximatePreImageWithSubFSM(Abs_VerificationInfo_t *absInfo, mdd_t *lowerBound, mdd_t *upperBound, mdd_t *careSet); 00044 static mdd_t * OverApproximatePreImageWithBddSubsetting(Abs_VerificationInfo_t *absInfo, mdd_t *lowerBound, mdd_t *upperBound, mdd_t *careSet); 00045 static mdd_t * UnderApproximatePreImageWithBddSubsetting(Abs_VerificationInfo_t *absInfo, mdd_t *lowerBound, mdd_t *upperBound, mdd_t *careSet); 00046 00050 /*---------------------------------------------------------------------------*/ 00051 /* Definition of exported functions */ 00052 /*---------------------------------------------------------------------------*/ 00053 00054 00055 /*---------------------------------------------------------------------------*/ 00056 /* Definition of internal functions */ 00057 /*---------------------------------------------------------------------------*/ 00058 00070 void 00071 AbsSubFormulaVerify( 00072 Abs_VerificationInfo_t *absInfo, 00073 AbsVertexInfo_t *vertexPtr) 00074 { 00075 AbsStats_t *stats; 00076 mdd_manager *mddManager; 00077 mdd_t *oldTmpCareSet = NIL(mdd_t); 00078 00079 long verbosity; 00080 00081 stats = AbsVerificationInfoReadStats(absInfo); 00082 mddManager = AbsVerificationInfoReadMddManager(absInfo); 00083 00084 /* If the current vertex has more than one parent, the temporary care set 00085 * must be reset (because it depends on the path that led to this vertex */ 00086 if (lsLength(vertexPtr->parent) > 1) { 00087 oldTmpCareSet = AbsVerificationInfoReadTmpCareSet(absInfo); 00088 AbsVerificationInfoSetTmpCareSet(absInfo, mdd_one(mddManager)); 00089 } 00090 00091 switch (AbsVertexReadType(vertexPtr)) { 00092 case fixedPoint_c: 00093 EvaluateFixedPoint(absInfo, vertexPtr); 00094 AbsStatsReadEvalFixedPoint(stats)++; 00095 break; 00096 case and_c: 00097 EvaluateAnd(absInfo, vertexPtr); 00098 AbsStatsReadEvalAnd(stats)++; 00099 break; 00100 case not_c: 00101 EvaluateNot(absInfo, vertexPtr); 00102 AbsStatsReadEvalNot(stats)++; 00103 break; 00104 case preImage_c: 00105 EvaluatePreImage(absInfo, vertexPtr); 00106 AbsStatsReadEvalPreImage(stats)++; 00107 break; 00108 case identifier_c: 00109 EvaluateIdentifier(absInfo, vertexPtr); 00110 AbsStatsReadEvalIdentifier(stats)++; 00111 break; 00112 case variable_c: 00113 EvaluateVariable(absInfo, vertexPtr); 00114 AbsStatsReadEvalVariable(stats)++; 00115 break; 00116 default: fail("Encountered unknown type of vertex\n"); 00117 } 00118 00119 verbosity = AbsOptionsReadVerbosity(AbsVerificationInfoReadOptions(absInfo)); 00120 00121 /* Print the size of the care set */ 00122 if (verbosity & ABS_VB_CARESZ) { 00123 (void) fprintf(vis_stdout, "ABS: Size of Care Set: "); 00124 (void) fprintf(vis_stdout, "%d Nodes.\n", 00125 mdd_size(AbsVerificationInfoReadCareSet(absInfo))); 00126 } 00127 00128 /* Print the care set */ 00129 if (verbosity & ABS_VB_CARE) { 00130 (void) fprintf(vis_stdout, "ABS: Care Set for Evaluation:\n"); 00131 AbsBddPrintMinterms(AbsVerificationInfoReadCareSet(absInfo)); 00132 } 00133 00134 /* Print the contents of the vertex */ 00135 if (verbosity & ABS_VB_VTXCNT) { 00136 AbsVertexPrint(vertexPtr, NIL(st_table), FALSE, verbosity); 00137 } 00138 00139 if (lsLength(vertexPtr->parent) > 1) { 00140 /* Restore the old temporary careset */ 00141 mdd_free(AbsVerificationInfoReadTmpCareSet(absInfo)); 00142 AbsVerificationInfoSetTmpCareSet(absInfo, oldTmpCareSet); 00143 } 00144 00145 } /* End of AbsSubFormulaVerify */ 00146 00160 void 00161 AbsFormulaScheduleEvaluation( 00162 AbsVertexInfo_t *current, 00163 AbsVertexInfo_t *limit) 00164 { 00165 /* We reached the final case */ 00166 if (current == limit) { 00167 return; 00168 } 00169 else { 00170 AbsVertexInfo_t *parentPtr; 00171 lsList parentList; 00172 lsGen gen; 00173 00174 /* Set the re-evaluation flag for the current vertex */ 00175 AbsVertexSetServed(current, 0); 00176 00177 /* Recur over the parents */ 00178 parentList = AbsVertexReadParent(current); 00179 lsForEachItem(parentList, gen, parentPtr) { 00180 if (parentPtr != NIL(AbsVertexInfo_t)) { 00181 AbsFormulaScheduleEvaluation(parentPtr, limit); 00182 } 00183 } 00184 } 00185 00186 return; 00187 } /* End of AbsFormulaScheduleEvaluation */ 00188 00206 mdd_t * 00207 AbsComputeOptimalIterate( 00208 Abs_VerificationInfo_t *absInfo, 00209 AbsVertexInfo_t *vertexPtr, 00210 mdd_t *lowerIterate, 00211 mdd_t *upperIterate) 00212 { 00213 mdd_t *tmp; 00214 mdd_t *result; 00215 00216 if (AbsOptionsReadMinimizeIterate(AbsVerificationInfoReadOptions(absInfo)) 00217 && AbsVertexReadUseExtraCareSet(vertexPtr)) { 00218 00219 /* 00220 * For this computation we have three ingredients and a handfull of 00221 * choices. The ingredients are the sets newIterate, iterate and 00222 * careSet. The goal is to compute an interval delimited by two boolean 00223 * functions and then call the function bdd_between to try to obtain 00224 * the best bdd in size inside that interval. To compute the extremes 00225 * of the interval there are several choices. For example, the care set 00226 * can be used in the lower bound of the interval or in both 00227 * bounds. The bigger the interval the more choice the function 00228 * bdd_between has to minimize, however, this does not turn into a 00229 * better result. 00230 * 00231 * Current Choice: [newIterate * iterate', newIterate] 00232 */ 00233 tmp = mdd_and(lowerIterate, upperIterate, 0, 1); 00234 result = bdd_between(tmp, upperIterate); 00235 00236 /* This line for debugging purposes, should be removed 00237 (void) fprintf(vis_stdout, 00238 "newIterate : %d, Diff : %d, result %d\n", 00239 mdd_size(upperIterate), mdd_size(tmp), 00240 mdd_size(result)); */ 00241 00242 mdd_free(tmp); 00243 } 00244 else { 00245 result = mdd_dup(upperIterate); 00246 } 00247 00248 return result; 00249 } /* End of AbsComputeOptimalIterate */ 00250 00260 boolean 00261 AbsFixedPointIterate( 00262 Abs_VerificationInfo_t *absInfo, 00263 AbsVertexInfo_t *vertexPtr, 00264 int iterateIndex) 00265 { 00266 AbsVertexInfo_t *subFormula; 00267 boolean keepIterating; 00268 boolean globalApprox; 00269 int stepCount; 00270 long verbosity; 00271 mdd_t *iterate; 00272 mdd_t *newIterate; 00273 mdd_t *careSet; 00274 00275 /* Do not allow to iterate from the middle of a fixed point computation */ 00276 assert(iterateIndex == array_n(AbsVertexReadRings(vertexPtr)) - 1); 00277 00278 careSet = AbsVerificationInfoReadCareSet(absInfo); 00279 00280 /* Check if the set of iterates has already converged */ 00281 if (array_n(AbsVertexReadRings(vertexPtr)) > 1) { 00282 mdd_t *ring1 = AbsVertexFetchRing(vertexPtr, iterateIndex); 00283 mdd_t *ring2 = AbsVertexFetchRing(vertexPtr, iterateIndex - 1); 00284 if (AbsMddLEqualModCareSet(ring1, ring2, careSet)) { 00285 return FALSE; 00286 } 00287 iterate = AbsVertexFetchRing(vertexPtr, iterateIndex - 1); 00288 } 00289 else { 00290 iterate = AbsVertexFetchRing(vertexPtr, iterateIndex); 00291 } 00292 newIterate = AbsVertexFetchRing(vertexPtr, iterateIndex); 00293 00294 /* Variable initialization */ 00295 keepIterating = TRUE; 00296 stepCount = iterateIndex; 00297 verbosity = AbsOptionsReadVerbosity(AbsVerificationInfoReadOptions(absInfo)); 00298 subFormula = AbsVertexReadLeftKid(vertexPtr); 00299 globalApprox = AbsVertexFetchSubApprox(vertexPtr, iterateIndex); 00300 00301 /* Main loop for the fixed point computation */ 00302 while (keepIterating) { 00303 mdd_t *best; 00304 00305 /* 00306 * Given newIterate, iterate and CareSet, if the use of extra care set is 00307 * enabled, choose the best candidate as the value of the iterate. 00308 */ 00309 best = AbsComputeOptimalIterate(absInfo, vertexPtr, iterate, newIterate); 00310 00311 /* Print the iterates */ 00312 if ((verbosity & ABS_VB_PITER) || (verbosity & ABS_VB_ITSIZ)) { 00313 (void) fprintf(vis_stdout, "ABS: New Iterate: "); 00314 if (verbosity & ABS_VB_ITSIZ) { 00315 (void) fprintf(vis_stdout, "%d -> %d\n", mdd_size(newIterate), 00316 mdd_size(best)); 00317 } 00318 else { 00319 (void) fprintf(vis_stdout, "\n"); 00320 } 00321 if (verbosity & ABS_VB_PITER) { 00322 AbsBddPrintMinterms(newIterate); 00323 } 00324 } 00325 00326 /* Store the value of the variable */ 00327 AbsVertexSetSat(AbsVertexReadFpVar(vertexPtr), best); 00328 00329 /* Mark the proper sub-formulas for re-evaluation */ 00330 AbsFormulaScheduleEvaluation(AbsVertexReadFpVar(vertexPtr), vertexPtr); 00331 00332 /* Evaluate the sub-formula */ 00333 AbsSubFormulaVerify(absInfo, subFormula); 00334 mdd_free(best); 00335 iterate = newIterate; 00336 00337 /* 00338 * Compute the new iterate. Due to the fact that don't cares are being 00339 * used, it might be possible that the new iterate does not contain the 00340 * previous one, in that case the or is taken 00341 */ 00342 newIterate = mdd_or(iterate, AbsVertexReadSat(subFormula), 1, 1); 00343 00344 assert(AbsMddLEqualModCareSet(iterate, newIterate, careSet)); 00345 00346 /* Set the rings and the approximation flags */ 00347 AbsVertexInsertRing(vertexPtr, newIterate); 00348 AbsVertexInsertRingApprox(vertexPtr, FALSE); 00349 globalApprox = globalApprox || AbsVertexReadGlobalApprox(subFormula); 00350 AbsVertexInsertSubApprox(vertexPtr, globalApprox); 00351 00352 keepIterating = !AbsMddEqualModCareSet(newIterate, iterate, careSet); 00353 00354 stepCount++; 00355 } /* End of main while loop */ 00356 00357 return TRUE; 00358 } /* End of AbsFixedPointIterate */ 00359 00360 /*---------------------------------------------------------------------------*/ 00361 /* Definition of static functions */ 00362 /*---------------------------------------------------------------------------*/ 00363 00374 static void 00375 EvaluateVariable( 00376 Abs_VerificationInfo_t *absInfo, 00377 AbsVertexInfo_t *vertexPtr) 00378 { 00379 /* Increase the number of times the result has been used */ 00380 AbsVertexReadServed(vertexPtr)++; 00381 00382 return; 00383 } /* End of EvaluateVariable */ 00384 00399 static void 00400 EvaluateIdentifier( 00401 Abs_VerificationInfo_t *absInfo, 00402 AbsVertexInfo_t *vertexPtr) 00403 { 00404 if (AbsVertexReadServed(vertexPtr) == 0) { 00405 Ntk_Node_t *node; 00406 Var_Variable_t *nodeVar; 00407 graph_t *partition; 00408 vertex_t *partitionVertex; 00409 Mvf_Function_t *nodeFunction; 00410 mdd_t *result; 00411 char *nodeNameString; 00412 char *nodeValueString; 00413 int nodeValue; 00414 00415 /* Clean up of previous result */ 00416 if (AbsVertexReadSat(vertexPtr) != NIL(mdd_t)) { 00417 mdd_free(AbsVertexReadSat(vertexPtr)); 00418 AbsVertexSetSat(vertexPtr, NIL(mdd_t)); 00419 } 00420 00421 /* Read the partition */ 00422 partition = AbsVerificationInfoReadPartition(absInfo); 00423 00424 assert(partition != NIL(graph_t)); 00425 00426 /* Obtain the name and the value being used */ 00427 nodeNameString = AbsVertexReadName(vertexPtr); 00428 nodeValueString = AbsVertexReadValue(vertexPtr); 00429 00430 /* Obtain the the node in the network and the variable attached to it */ 00431 node = Ntk_NetworkFindNodeByName(AbsVerificationInfoReadNetwork(absInfo), 00432 nodeNameString); 00433 nodeVar = Ntk_NodeReadVariable(node); 00434 00435 /* Obtain the real value of the multi-valued vairable */ 00436 if (Var_VariableTestIsSymbolic(nodeVar)) { 00437 nodeValue = Var_VariableReadIndexFromSymbolicValue(nodeVar, 00438 nodeValueString); 00439 } 00440 else { 00441 nodeValue = atoi(nodeValueString); 00442 } 00443 00444 /* Read the partition, find the vertex in the partition and its function */ 00445 partitionVertex = Part_PartitionFindVertexByName(partition, 00446 nodeNameString); 00447 00448 /* If the vertex is not represented in the partition must be built */ 00449 if (partitionVertex == NIL(vertex_t)) { 00450 Ntk_Node_t *tmpNode; 00451 lsGen tmpGen; 00452 array_t *mvfArray; 00453 array_t *tmpRoots; 00454 st_table *tmpLeaves; 00455 00456 /* Initialize the variables */ 00457 tmpRoots = array_alloc(Ntk_Node_t *, 0); 00458 tmpLeaves = st_init_table(st_ptrcmp, st_ptrhash); 00459 00460 /* Insert the parameters in the array and table */ 00461 array_insert_last(Ntk_Node_t *, tmpRoots, node); 00462 Ntk_NetworkForEachCombInput(AbsVerificationInfoReadNetwork(absInfo), 00463 tmpGen, tmpNode) { 00464 st_insert(tmpLeaves, (char *) tmpNode, (char *) NTM_UNUSED); 00465 } 00466 00467 /* Effectively build the mdd for the given vertex */ 00468 mvfArray = Ntm_NetworkBuildMvfs(AbsVerificationInfoReadNetwork(absInfo), 00469 tmpRoots, tmpLeaves, NIL(mdd_t)); 00470 nodeFunction = array_fetch(Mvf_Function_t *, mvfArray, 0); 00471 array_free(tmpRoots); 00472 st_free_table(tmpLeaves); 00473 array_free(mvfArray); 00474 00475 /* Store the result in the vertex */ 00476 result = Mvf_FunctionReadComponent(nodeFunction, nodeValue); 00477 AbsVertexSetSat(vertexPtr, mdd_dup(result)); 00478 Mvf_FunctionFree(nodeFunction); 00479 } 00480 else { 00481 /* Store the result in the vertex */ 00482 nodeFunction = Part_VertexReadFunction(partitionVertex); 00483 result = Mvf_FunctionReadComponent(nodeFunction, nodeValue); 00484 AbsVertexSetSat(vertexPtr, mdd_dup(result)); 00485 } 00486 00487 /* Set the approximation flags */ 00488 AbsVertexSetLocalApprox(vertexPtr, FALSE); 00489 AbsVertexSetGlobalApprox(vertexPtr, FALSE); 00490 } 00491 00492 /* Increase the number of times the result has been used */ 00493 AbsVertexReadServed(vertexPtr)++; 00494 00495 return; 00496 } /* End of EvaluateIdentifier */ 00497 00507 static void 00508 EvaluateNot( 00509 Abs_VerificationInfo_t *absInfo, 00510 AbsVertexInfo_t *vertexPtr) 00511 { 00512 if (AbsVertexReadServed(vertexPtr) == 0) { 00513 AbsVertexInfo_t *subFormula; 00514 00515 /* Clean up of previous result */ 00516 if (AbsVertexReadSat(vertexPtr) != NIL(mdd_t)) { 00517 mdd_free(AbsVertexReadSat(vertexPtr)); 00518 AbsVertexSetSat(vertexPtr, NIL(mdd_t)); 00519 } 00520 00521 /* Recursively evaluate the sub-formula */ 00522 subFormula = AbsVertexReadLeftKid(vertexPtr); 00523 AbsSubFormulaVerify(absInfo, subFormula); 00524 00525 /* Negate the result of the sub-formula */ 00526 AbsVertexSetSat(vertexPtr, mdd_not(AbsVertexReadSat(subFormula))); 00527 00528 /* Set the approximation flags */ 00529 AbsVertexSetLocalApprox(vertexPtr, FALSE); 00530 AbsVertexSetGlobalApprox(vertexPtr, AbsVertexReadGlobalApprox(subFormula)); 00531 } 00532 00533 /* Increase the number of times the result has been used */ 00534 AbsVertexReadServed(vertexPtr)++; 00535 00536 return; 00537 } /* End of EvaluateNot */ 00538 00548 static void 00549 EvaluateAnd( 00550 Abs_VerificationInfo_t *absInfo, 00551 AbsVertexInfo_t *vertexPtr) 00552 { 00553 if (AbsVertexReadServed(vertexPtr) == 0) { 00554 AbsVertexInfo_t *firstFormula; 00555 AbsVertexInfo_t *secondFormula; 00556 mdd_t *oldTmpCareSet; 00557 00558 /* Clean up of previous result */ 00559 if (AbsVertexReadSat(vertexPtr) != NIL(mdd_t)) { 00560 mdd_free(AbsVertexReadSat(vertexPtr)); 00561 AbsVertexSetSat(vertexPtr, NIL(mdd_t)); 00562 } 00563 00564 /* Obtain the subformulas to evaluate */ 00565 firstFormula = AbsVertexReadLeftKid(vertexPtr); 00566 secondFormula = AbsVertexReadRightKid(vertexPtr); 00567 00568 /* Recursively evaluate the first sub-formula */ 00569 AbsSubFormulaVerify(absInfo, firstFormula); 00570 00571 /* Store the temporary careset and set the new one */ 00572 oldTmpCareSet = AbsVerificationInfoReadTmpCareSet(absInfo); 00573 AbsVerificationInfoSetTmpCareSet(absInfo, 00574 mdd_and(oldTmpCareSet, 00575 AbsVertexReadSat(firstFormula), 00576 1,1)); 00577 00578 /* Recursively evaluate the second sub-formula */ 00579 AbsSubFormulaVerify(absInfo, secondFormula); 00580 00581 /* Restore the temporary careset */ 00582 mdd_free(AbsVerificationInfoReadTmpCareSet(absInfo)); 00583 AbsVerificationInfoSetTmpCareSet(absInfo, oldTmpCareSet); 00584 00585 /* Compute result, so far no approximation is required */ 00586 AbsVertexSetSat(vertexPtr, mdd_and(AbsVertexReadSat(firstFormula), 00587 AbsVertexReadSat(secondFormula), 00588 1, 1)); 00589 00590 /* Set the approximation flags */ 00591 AbsVertexSetLocalApprox(vertexPtr, FALSE); 00592 AbsVertexSetGlobalApprox(vertexPtr, 00593 AbsVertexReadGlobalApprox(firstFormula) || 00594 AbsVertexReadGlobalApprox(secondFormula)); 00595 } 00596 00597 /* Increase the number of times the result has been used */ 00598 AbsVertexReadServed(vertexPtr)++; 00599 00600 return; 00601 } /* End of EvaluateAnd */ 00602 00612 static void 00613 EvaluateFixedPoint( 00614 Abs_VerificationInfo_t *absInfo, 00615 AbsVertexInfo_t *vertexPtr) 00616 { 00617 if (AbsVertexReadServed(vertexPtr) == 0) { 00618 mdd_manager *mddManager; 00619 mdd_t *oldTmpCareSet; 00620 mdd_t *newTmpCareSet; 00621 00622 if (AbsVertexReadRings(vertexPtr) != NIL(array_t)) { 00623 mdd_t *ringUnit; 00624 int i; 00625 00626 arrayForEachItem(mdd_t *, AbsVertexReadRings(vertexPtr), i, ringUnit) { 00627 mdd_free(ringUnit); 00628 } 00629 array_free(AbsVertexReadRings(vertexPtr)); 00630 array_free(AbsVertexReadRingApprox(vertexPtr)); 00631 array_free(AbsVertexReadSubApprox(vertexPtr)); 00632 mdd_free(AbsVertexReadSat(vertexPtr)); 00633 } 00634 00635 /* Re-allocation of the temporary structures */ 00636 AbsVertexSetRings(vertexPtr, array_alloc(mdd_t *, 0)); 00637 AbsVertexSetRingApprox(vertexPtr, array_alloc(boolean, 0)); 00638 AbsVertexSetSubApprox(vertexPtr, array_alloc(boolean, 0)); 00639 00640 /* Initial values of the fixed point */ 00641 mddManager = AbsVerificationInfoReadMddManager(absInfo); 00642 AbsVertexInsertRing(vertexPtr, mdd_zero(mddManager)); 00643 AbsVertexInsertRingApprox(vertexPtr, FALSE); 00644 AbsVertexInsertSubApprox(vertexPtr, FALSE); 00645 00646 /* Reset the temporary careset to the mdd one */ 00647 oldTmpCareSet = AbsVerificationInfoReadTmpCareSet(absInfo); 00648 newTmpCareSet = mdd_one(mddManager); 00649 AbsVerificationInfoSetTmpCareSet(absInfo, newTmpCareSet); 00650 00651 /* Effectively iterate the body */ 00652 AbsFixedPointIterate(absInfo, vertexPtr, 0); 00653 00654 /* Restore the old temporary careset */ 00655 mdd_free(newTmpCareSet); 00656 AbsVerificationInfoSetTmpCareSet(absInfo, oldTmpCareSet); 00657 00658 /* Set the last result as the set sat*/ 00659 AbsVertexSetSat(vertexPtr, 00660 mdd_dup(AbsVertexFetchRing(vertexPtr, 00661 array_n(AbsVertexReadRings(vertexPtr)) 00662 - 1))); 00663 00664 /* Set the approximation flags */ 00665 AbsVertexSetLocalApprox(vertexPtr, FALSE); 00666 AbsVertexSetGlobalApprox(vertexPtr, 00667 AbsVertexFetchSubApprox(vertexPtr, 00668 array_n(AbsVertexReadSubApprox(vertexPtr)) - 1)); 00669 } 00670 00671 /* Increase the number of times the result has been used */ 00672 AbsVertexReadServed(vertexPtr)++; 00673 00674 return; 00675 } 00676 00677 /* End of EvaluateFixedPoint */ 00678 00688 static void 00689 EvaluatePreImage( 00690 Abs_VerificationInfo_t *absInfo, 00691 AbsVertexInfo_t *vertexPtr) 00692 { 00693 AbsOptions_t *options; 00694 AbsStats_t *stats; 00695 long verbosity; 00696 00697 /* Variable initialization */ 00698 options = AbsVerificationInfoReadOptions(absInfo); 00699 verbosity = AbsOptionsReadVerbosity(options); 00700 stats = AbsVerificationInfoReadStats(absInfo); 00701 00702 if (AbsVertexReadServed(vertexPtr) == 0) { 00703 AbsVertexInfo_t *subFormula; 00704 mdd_manager *mddManager; 00705 mdd_t *result; 00706 mdd_t *careSet; 00707 mdd_t *oldTmpCareSet; 00708 mdd_t *minimizedSet; 00709 00710 /* Variable initialization */ 00711 mddManager = AbsVerificationInfoReadMddManager(absInfo); 00712 subFormula = AbsVertexReadLeftKid(vertexPtr); 00713 00714 /* 00715 * Compute the care set as the conjunction of the given one and the 00716 * temporary one 00717 */ 00718 careSet = mdd_and(AbsVerificationInfoReadCareSet(absInfo), 00719 AbsVerificationInfoReadTmpCareSet(absInfo), 1, 1); 00720 00721 /* Clean up */ 00722 if (AbsVertexReadSat(vertexPtr) != NIL(mdd_t)) { 00723 mdd_free(AbsVertexReadSat(vertexPtr)); 00724 AbsVertexSetSat(vertexPtr, NIL(mdd_t)); 00725 } 00726 00727 /* Reset the temporary careset to the mdd one */ 00728 oldTmpCareSet = AbsVerificationInfoReadTmpCareSet(absInfo); 00729 AbsVerificationInfoSetTmpCareSet(absInfo, mdd_one(mddManager)); 00730 00731 /* Evaluate the sub-formula */ 00732 AbsSubFormulaVerify(absInfo, subFormula); 00733 00734 /* Restore the old temporary careset */ 00735 mdd_free(AbsVerificationInfoReadTmpCareSet(absInfo)); 00736 AbsVerificationInfoSetTmpCareSet(absInfo, oldTmpCareSet); 00737 00738 /* Check for trivial cases */ 00739 if (mdd_is_tautology(AbsVertexReadSat(subFormula), 0) || 00740 mdd_is_tautology(AbsVertexReadSat(subFormula), 1)) { 00741 AbsVertexSetSat(vertexPtr, mdd_dup(AbsVertexReadSat(subFormula))); 00742 AbsVertexSetLocalApprox(vertexPtr, FALSE); 00743 AbsVertexSetGlobalApprox(vertexPtr, 00744 AbsVertexReadGlobalApprox(subFormula)); 00745 mdd_free(careSet); 00746 return; 00747 } 00748 00749 /* if (AbsOptionsReadMinimizeIterate(options)){ */ 00750 if (FALSE){ 00751 minimizedSet = bdd_minimize(AbsVertexReadSat(subFormula), 00752 AbsVerificationInfoReadCareSet(absInfo)); 00753 } 00754 else { 00755 minimizedSet = mdd_dup(AbsVertexReadSat(subFormula)); 00756 } 00757 00758 /* Look up in the cache if the result has been previously computed */ 00759 if (AbsVertexReadSolutions(vertexPtr) != NIL(st_table)) { 00760 mdd_t *unit; 00761 boolean localFlag; 00762 boolean exactness; 00763 00764 exactness = AbsOptionsReadExact(options); 00765 if (AbsEvalCacheLookup(AbsVertexReadSolutions(vertexPtr), 00766 minimizedSet, careSet, !exactness, 00767 &unit, &localFlag)) { 00768 00769 /* Set the sat */ 00770 AbsVertexSetSat(vertexPtr, mdd_dup(unit)); 00771 00772 /* Set the approximation flags */ 00773 AbsVertexSetLocalApprox(vertexPtr, localFlag & !exactness); 00774 AbsVertexSetGlobalApprox(vertexPtr, 00775 AbsVertexReadGlobalApprox(subFormula) || 00776 AbsVertexReadLocalApprox(vertexPtr)); 00777 /* Increase the number of times the result has been used */ 00778 AbsVertexReadServed(vertexPtr)++; 00779 00780 mdd_free(careSet); 00781 mdd_free(minimizedSet); 00782 return; 00783 } 00784 } 00785 else { 00786 /* Initialize the cache */ 00787 AbsVertexSetSolutions(vertexPtr, st_init_table(st_ptrcmp, st_ptrhash)); 00788 } 00789 00790 /* Effectively compute preImage */ 00791 if (!AbsOptionsReadExact(options)) { 00792 if (AbsVertexReadPolarity(vertexPtr)) { 00793 if (AbsOptionsReadPartApprox(options)) { 00794 result = OverApproximatePreImageWithSubFSM(absInfo, minimizedSet, 00795 minimizedSet, careSet); 00796 } 00797 else { 00798 result = OverApproximatePreImageWithBddSubsetting(absInfo, 00799 minimizedSet, 00800 minimizedSet, 00801 careSet); 00802 } 00803 AbsVertexSetLocalApprox(vertexPtr, TRUE); 00804 } 00805 else { 00806 result = UnderApproximatePreImageWithBddSubsetting(absInfo, 00807 minimizedSet, 00808 minimizedSet, 00809 careSet); 00810 AbsVertexSetLocalApprox(vertexPtr, TRUE); 00811 } 00812 AbsStatsReadApproxPreImage(AbsVerificationInfoReadStats(absInfo))++; 00813 } 00814 else { 00815 Fsm_Fsm_t *system; 00816 Img_ImageInfo_t *imageInfo; 00817 long cpuTime; 00818 00819 system = AbsVerificationInfoReadFsm(absInfo); 00820 imageInfo = Fsm_FsmReadOrCreateImageInfo(system, 1, 0); 00821 cpuTime = util_cpu_time(); 00822 result = Img_ImageInfoComputeBwdWithDomainVars(imageInfo, minimizedSet, 00823 minimizedSet,careSet); 00824 AbsStatsReadPreImageCpuTime(stats)+= util_cpu_time() - cpuTime; 00825 00826 AbsStatsReadExactPreImage(stats)++; 00827 AbsVertexSetLocalApprox(vertexPtr, FALSE); 00828 } 00829 AbsVertexSetSat(vertexPtr, result); 00830 00831 /* Set the value in the cache */ 00832 AbsEvalCacheInsert(AbsVertexReadSolutions(vertexPtr), 00833 minimizedSet, AbsVertexReadSat(vertexPtr), careSet, 00834 AbsVertexReadLocalApprox(vertexPtr), FALSE); 00835 AbsStatsReadPreImageCacheEntries(stats)++; 00836 mdd_free(minimizedSet); 00837 00838 /* Set the approximation flags */ 00839 AbsVertexSetGlobalApprox(vertexPtr, 00840 AbsVertexReadGlobalApprox(subFormula) || 00841 AbsVertexReadLocalApprox(vertexPtr)); 00842 00843 /* Print the number of states in the on set of Sat */ 00844 if (verbosity & ABS_VB_TSAT) { 00845 Fsm_Fsm_t *globalSystem; 00846 array_t *domainVars; 00847 mdd_t *intersection; 00848 00849 intersection = mdd_and(AbsVertexReadSat(vertexPtr), careSet, 1, 1); 00850 00851 globalSystem = AbsVerificationInfoReadFsm(absInfo); 00852 domainVars = Fsm_FsmReadPresentStateVars(globalSystem); 00853 (void) fprintf(vis_stdout, "ABS: %.0f States satisfy the EX formula.\n", 00854 mdd_count_onset(AbsVerificationInfoReadMddManager(absInfo), 00855 intersection, domainVars)); 00856 mdd_free(intersection); 00857 } 00858 mdd_free(careSet); 00859 } 00860 00861 00862 /* Increase the number of times the result has been used */ 00863 AbsVertexReadServed(vertexPtr)++; 00864 00865 return; 00866 } /* End of EvaluatePreImage */ 00867 00878 static mdd_t * 00879 OverApproximatePreImageWithSubFSM( 00880 Abs_VerificationInfo_t *absInfo, 00881 mdd_t *lowerBound, 00882 mdd_t *upperBound, 00883 mdd_t *careSet) 00884 { 00885 Fsm_Fsm_t *system; 00886 Img_ImageInfo_t *imageInfo; 00887 mdd_t *result; 00888 long cpuTime; 00889 00890 /* Initialize some variables */ 00891 system = AbsVerificationInfoReadApproxFsm(absInfo); 00892 00893 if (system == NIL(Fsm_Fsm_t)) { 00894 system = AbsVerificationInfoReadFsm(absInfo); 00895 } 00896 00897 /* Obtain the image info */ 00898 imageInfo = Fsm_FsmReadOrCreateImageInfo(system, 1, 0); 00899 00900 cpuTime = util_cpu_time(); 00901 result = Img_ImageInfoComputeBwdWithDomainVars(imageInfo, lowerBound, 00902 upperBound, careSet); 00903 AbsStatsReadAppPreCpuTime(AbsVerificationInfoReadStats(absInfo))+= 00904 util_cpu_time() - cpuTime; 00905 00906 return result; 00907 } /* End of OverApproximatePreImageWithSubFSM */ 00908 00909 00920 static mdd_t * 00921 OverApproximatePreImageWithBddSubsetting( 00922 Abs_VerificationInfo_t *absInfo, 00923 mdd_t *lowerBound, 00924 mdd_t *upperBound, 00925 mdd_t *careSet) 00926 { 00927 Fsm_Fsm_t *system; 00928 Img_ImageInfo_t *imageInfo; 00929 mdd_t *superSet; 00930 mdd_t *result; 00931 long cpuTime; 00932 00933 /* Initialize some variables */ 00934 system = AbsVerificationInfoReadFsm(absInfo); 00935 00936 /* Compute the subset of the restriction set */ 00937 superSet = bdd_approx_remap_ua(lowerBound,BDD_OVER_APPROX, 00938 AbsVerificationInfoReadNumStateVars(absInfo), 00939 0,1); 00940 00941 /* Obtain the image info */ 00942 imageInfo = Fsm_FsmReadOrCreateImageInfo(system, 1, 0); 00943 00944 cpuTime = util_cpu_time(); 00945 result = Img_ImageInfoComputeBwdWithDomainVars(imageInfo, superSet, 00946 superSet, careSet); 00947 AbsStatsReadAppPreCpuTime(AbsVerificationInfoReadStats(absInfo))+= 00948 util_cpu_time() - cpuTime; 00949 00950 mdd_free(superSet); 00951 00952 return result; 00953 } /* End of OverApproximatePreImageWithBddSubsetting */ 00954 00964 static mdd_t * 00965 UnderApproximatePreImageWithBddSubsetting( 00966 Abs_VerificationInfo_t *absInfo, 00967 mdd_t *lowerBound, 00968 mdd_t *upperBound, 00969 mdd_t *careSet) 00970 { 00971 Fsm_Fsm_t *system; 00972 Img_ImageInfo_t *imageInfo; 00973 mdd_t *subSet; 00974 mdd_t *result; 00975 long cpuTime; 00976 00977 /* Initialize some variables */ 00978 system = AbsVerificationInfoReadFsm(absInfo); 00979 00980 /* Compute the subset of the restriction set */ 00981 subSet = bdd_approx_remap_ua(lowerBound, BDD_UNDER_APPROX, 00982 AbsVerificationInfoReadNumStateVars(absInfo), 00983 0,1); 00984 00985 /* Obtain the image info */ 00986 imageInfo = Fsm_FsmReadOrCreateImageInfo(system, 1, 0); 00987 00988 cpuTime = util_cpu_time(); 00989 result = Img_ImageInfoComputeBwdWithDomainVars(imageInfo, subSet, subSet, 00990 careSet); 00991 AbsStatsReadAppPreCpuTime(AbsVerificationInfoReadStats(absInfo))+= 00992 util_cpu_time() - cpuTime; 00993 00994 mdd_free(subSet); 00995 00996 return result; 00997 } /* End of UnderApproximatePreImageWithBddSubsetting */