VIS
|
00001 00017 #include "amcInt.h" 00018 #include "mcInt.h" 00019 00020 static char rcsid[] UNUSED = "$Id: amcBlock.c,v 1.35 2005/04/25 20:24:53 fabio Exp $"; 00021 00022 /*---------------------------------------------------------------------------*/ 00023 /* Constant declarations */ 00024 /*---------------------------------------------------------------------------*/ 00025 00026 /*---------------------------------------------------------------------------*/ 00027 /* Structure declarations */ 00028 /*---------------------------------------------------------------------------*/ 00029 00037 struct BlockInfoStruct { 00038 Amc_SubsystemInfo_t *optimalSystem; /* temporary storage for Block method */ 00039 int bestSystem; /* temporary storage for Block method */ 00040 }; 00041 00042 struct BlockSubsystemInfoStruct { 00043 int scheduledForRefinement; 00044 }; 00045 00046 00047 /*---------------------------------------------------------------------------*/ 00048 /* Type declarations */ 00049 /*---------------------------------------------------------------------------*/ 00050 typedef struct BlockInfoStruct BlockInfo_t; 00051 typedef struct BlockSubsystemInfoStruct BlockSubsystemInfo_t; 00052 00053 /*---------------------------------------------------------------------------*/ 00054 /* Variable declarations */ 00055 /*---------------------------------------------------------------------------*/ 00056 00057 /*---------------------------------------------------------------------------*/ 00058 /* Macro declarations */ 00059 /*---------------------------------------------------------------------------*/ 00060 00063 /*---------------------------------------------------------------------------*/ 00064 /* Static function prototypes */ 00065 /*---------------------------------------------------------------------------*/ 00066 00067 static BlockInfo_t * AmcObtainOptimalSystemUpperBound(Amc_Info_t *amcInfo, Ctlp_Formula_t *formula, BlockInfo_t *BlockInfo, int verbosity); 00068 static BlockInfo_t * AmcObtainOptimalSystemLowerBound(Amc_Info_t *amcInfo, Ctlp_Formula_t *formula, BlockInfo_t *BlockInfo, int verbosity); 00069 static void AmcInitializeDependency(array_t *subSystemArray, int isMBM); 00070 static void AmcInitializeSchedule(Amc_Info_t *amcInfo); 00071 static int AmcIsEverySubsystemRescheduled(Amc_Info_t *amcInfo); 00072 static void AmcPrintScheduleInformation(Amc_Info_t *amcInfo); 00073 #if 0 00074 static void AmcRescheduleForRefinement(st_table *fanOutSystemTable); 00075 static mdd_t * AmcRefineWithSatisfyStatesOfFanInSystem(Amc_SubsystemInfo_t *subSystem, mdd_t *careStates); 00076 #endif 00077 static array_t * AmcInitializeQuantifyVars(Amc_SubsystemInfo_t *subSystem); 00078 #if 0 00079 static void AmcFreeBlockInfo(BlockInfo_t *BlockInfo); 00080 #endif 00081 static int AmcBlockSubsystemReadScheduledForRefinement(BlockSubsystemInfo_t *system); 00082 static void AmcBlockSubsystemSetScheduledForRefinement(BlockSubsystemInfo_t *system, int data); 00083 #if 0 00084 static Amc_SubsystemInfo_t * AmcBlockReadOptimalSubsystem(BlockInfo_t *system); 00085 #endif 00086 static void AmcBlockSetOptimalSystem(BlockInfo_t *system, Amc_SubsystemInfo_t *data); 00087 #if 0 00088 static int AmcBlockReadBestSystem(BlockInfo_t *system); 00089 #endif 00090 static void AmcBlockSetBestSystem(BlockInfo_t *system, int data); 00091 #if 0 00092 static Amc_SubsystemInfo_t * AmcClearInputVarsFromFSM(Amc_SubsystemInfo_t *subSystem); 00093 #endif 00094 00098 /*---------------------------------------------------------------------------*/ 00099 /* Definition of exported functions */ 00100 /*---------------------------------------------------------------------------*/ 00101 00102 00103 /*---------------------------------------------------------------------------*/ 00104 /* Definition of internal functions */ 00105 /*---------------------------------------------------------------------------*/ 00148 int 00149 AmcBlockTearingProc( 00150 Amc_Info_t *amcInfo, 00151 Ctlp_Formula_t *formula, 00152 int verbosity) 00153 { 00154 array_t *subSystemArray = amcInfo->subSystemArray; 00155 Amc_SubsystemInfo_t *subSystem; 00156 BlockInfo_t BlockInfo; 00157 00158 00159 /* 00160 * Update fan-in subsystems and fan-out subsystems when machine by machine 00161 * method is ON. 00162 * Update initial states in BlockInfo. 00163 * Reschedule every subsystem to be evaluated. 00164 */ 00165 00166 if( amcInfo->optimalSystem == NIL(Amc_SubsystemInfo_t) ) { 00167 AmcInitializeDependency(subSystemArray, amcInfo->isMBM); 00168 } 00169 00170 AmcInitializeSchedule(amcInfo); 00171 00172 /* BlockInfo is a temporary storage. optimal system is not freed */ 00173 BlockInfo.optimalSystem = NIL(Amc_SubsystemInfo_t); 00174 00175 00176 /* 00177 * Outer loop until there's no scheduled subsystem. 00178 */ 00179 while(AmcIsEverySubsystemRescheduled(amcInfo)) { 00180 00181 if(verbosity == Amc_VerbosityNone_c) 00182 AmcPrintScheduleInformation(amcInfo); 00183 00184 00185 if( !amcInfo->lowerBound ) { 00186 AmcObtainOptimalSystemUpperBound(amcInfo, formula, &BlockInfo, 00187 verbosity); 00188 /* AmcObtainOptimalSystemUpperBoundWithDI(amcInfo, formula, &BlockInfo, 00189 verbosity); */ 00190 } 00191 else { 00192 AmcObtainOptimalSystemLowerBound(amcInfo, formula, &BlockInfo, 00193 verbosity); 00194 /* AmcObtainOptimalSystemLowerBoundWithMBM(amcInfo, formula, &BlockInfo, 00195 verbosity); */ 00196 } 00197 00198 if(amcInfo->isVerified) { 00199 00200 int best = BlockInfo.bestSystem; 00201 subSystem = array_fetch(Amc_SubsystemInfo_t *, amcInfo->subSystemArray, 00202 best); 00203 subSystem->takenIntoOptimal = 1; 00204 00205 return 1; 00206 } 00207 00208 if(!amcInfo->isMBM) 00209 break; 00210 00211 } /* End of while() */ 00212 00213 if(verbosity == Amc_VerbosityNone_c) 00214 AmcPrintScheduleInformation(amcInfo); 00215 00216 00217 /* Update the subsystem that had been included in optimal system */ 00218 { 00219 int best = BlockInfo.bestSystem; 00220 subSystem = array_fetch(Amc_SubsystemInfo_t *, amcInfo->subSystemArray, 00221 best); 00222 subSystem->takenIntoOptimal = 1; 00223 } 00224 00225 /* Update amcInfo's optimal system */ 00226 if(amcInfo->optimalSystem != NIL(Amc_SubsystemInfo_t)) { 00227 #ifdef AMC_DEBUG 00228 { 00229 Amc_SubsystemInfo_t *previousOpt = amcInfo->optimalSystem; 00230 Amc_SubsystemInfo_t *currentOpt = BlockInfo.optimalSystem; 00231 00232 if(!amcInfo->lowerBound) { 00233 if(mdd_lequal(previousOpt->satisfyStates, currentOpt->satisfyStates, 00234 1, 1)) { 00235 fprintf(vis_stdout, "\n###AMC : We are ok."); 00236 } 00237 else { 00238 fprintf(vis_stdout, "\n** amc error: Somethings wrong."); 00239 } 00240 } 00241 else { 00242 if( mdd_lequal(currentOpt->satisfyStates, previousOpt->satisfyStates, 00243 1, 1)) { 00244 fprintf(vis_stdout, "\n###AMC : We are ok."); 00245 } 00246 else { 00247 fprintf(vis_stdout, "\n** amc error: Somethings wrong."); 00248 } 00249 } 00250 } 00251 #endif 00252 Amc_AmcSubsystemFree(amcInfo->optimalSystem); 00253 } 00254 AmcSetOptimalSystem(amcInfo, BlockInfo.optimalSystem); 00255 00256 return 1; 00257 } 00258 00266 void 00267 AmcFreeBlock( 00268 Amc_Info_t *amcInfo) 00269 { 00270 Amc_SubsystemInfo_t *subSystem; 00271 BlockSubsystemInfo_t *BlockSubsystem; 00272 int i ; 00273 00274 /* what if amc doesn't free partition */ 00275 arrayForEachItem(Amc_SubsystemInfo_t *, amcInfo->subSystemArray, i, 00276 subSystem) { 00277 BlockSubsystem = (BlockSubsystemInfo_t *)AmcSubsystemReadMethodSpecificData(subSystem); 00278 if(BlockSubsystem != NIL(BlockSubsystemInfo_t)) 00279 FREE(BlockSubsystem); 00280 00281 Amc_AmcSubsystemFree(subSystem); 00282 } 00283 array_free(amcInfo->subSystemArray); 00284 00285 if(amcInfo->optimalSystem != NIL(Amc_SubsystemInfo_t)) { 00286 Amc_AmcSubsystemFree(amcInfo->optimalSystem); 00287 amcInfo->optimalSystem = NIL(Amc_SubsystemInfo_t); 00288 } 00289 00290 if( amcInfo->initialStates != NIL(mdd_t)) { 00291 mdd_free(amcInfo->initialStates); 00292 amcInfo->initialStates = NIL(mdd_t); 00293 } 00294 00295 FREE(amcInfo); 00296 00297 } 00298 00299 /*---------------------------------------------------------------------------*/ 00300 /* Definition of static functions */ 00301 /*---------------------------------------------------------------------------*/ 00302 00303 00304 00350 static BlockInfo_t * 00351 AmcObtainOptimalSystemUpperBound( 00352 Amc_Info_t *amcInfo, 00353 Ctlp_Formula_t *formula, 00354 BlockInfo_t *BlockInfo, 00355 int verbosity) 00356 { 00357 array_t *subSystemArray = amcInfo->subSystemArray; 00358 Amc_SubsystemInfo_t *subSystem, *bestCombinedSystem; 00359 mdd_t *initialStates; 00360 mdd_t *smallestStates, *currentErrorStates, *careStates; 00361 int i, best = 0; 00362 graph_t *partition = Part_NetworkReadPartition(amcInfo->network); 00363 mdd_manager *mddManager = Part_PartitionReadMddManager(partition); 00364 mdd_t *mddOne = mdd_one(mddManager); 00365 array_t *quantifyVars; 00366 Mc_DcLevel dcLevel; 00367 char *flagValue; 00368 00369 00370 /* 00371 * Initial states must be set before coming into this routine. 00372 */ 00373 initialStates = amcInfo->initialStates; 00374 if( initialStates == NIL(mdd_t) ) { 00375 (void)fprintf(vis_stderr, "** amc error: \n"); 00376 return(NIL(BlockInfo_t)); 00377 } 00378 00379 /* Read in the usage of don't care level */ 00380 flagValue = Cmd_FlagReadByName("amc_DC_level"); 00381 if(flagValue != NIL(char)){ 00382 dcLevel = (Mc_DcLevel) atoi(flagValue); 00383 if( dcLevel > McDcLevelRchFrontier_c ) dcLevel = McDcLevelRchFrontier_c; 00384 } 00385 else{ 00386 /* default value set to McDcLevelNone_c. Mc's default is McDcLevelRch_c. */ 00387 dcLevel = McDcLevelNone_c; 00388 } 00389 00390 /* 00391 * Update the set of states satisfying the formula for each sub-systems. 00392 * The process of "combining sub-systems" is equivalent of taking a 00393 * "synchronous product" of multiple sub-subsystems. 00394 */ 00395 smallestStates = NIL(mdd_t); 00396 bestCombinedSystem = NIL(Amc_SubsystemInfo_t); 00397 00398 arrayForEachItem(Amc_SubsystemInfo_t *, subSystemArray, i, subSystem) { 00399 00400 mdd_t *reachableStates, *fairStates, *satisfyStates; 00401 Fsm_Fsm_t *combinedFsm; 00402 Fsm_Fairness_t *fairCond; 00403 Amc_SubsystemInfo_t *combinedSystem; 00404 00405 /* Proceed if the subsystem had not yet been taken into the optimal system. */ 00406 if(!subSystem->takenIntoOptimal) { 00407 00408 /* 00409 * Combine subsystems. If optimal subsystem is NIL, duplicate the 00410 * subsystem. 00411 */ 00412 combinedSystem = Amc_CombineSubsystems(amcInfo->network, 00413 amcInfo->optimalSystem, 00414 subSystem); 00415 combinedFsm = AmcSubsystemReadFsm(combinedSystem); 00416 00417 quantifyVars = AmcInitializeQuantifyVars(combinedSystem); 00418 00419 /* 00420 * Currently forced not to compute reachable states. This is to reduce 00421 * computational overhead of computing it when dealing with complex 00422 * examples. 00423 */ 00424 reachableStates = mdd_one(mddManager); 00425 fairStates = mdd_one(mddManager); 00426 fairCond = Fsm_FsmReadFairnessConstraint(combinedFsm); 00427 00428 00429 /* Obtain new care set from fan-in systems */ 00430 careStates = mdd_dup(reachableStates); 00431 00432 Ctlp_FlushStates(formula); 00433 satisfyStates = mdd_dup(Amc_AmcEvaluateCTLFormula(combinedSystem, 00434 subSystemArray, 00435 formula, fairStates, 00436 fairCond, 00437 careStates, 00438 amcInfo->lowerBound, 00439 quantifyVars, 00440 /*NIL(array_t),*/ 00441 (Mc_VerbosityLevel) 00442 verbosity, dcLevel)); 00443 00444 { 00445 int x; array_t *quantifyStateVars; 00446 arrayForEachItem(array_t *, quantifyVars, x, quantifyStateVars) { 00447 array_free(quantifyStateVars); 00448 } 00449 array_free(quantifyVars); 00450 } 00451 /* Free */ 00452 mdd_free(careStates); 00453 mdd_free(reachableStates); mdd_free(fairStates); 00454 00455 00456 /* 00457 * Update the set of states satisfying the formula for each subsystems 00458 * when newly computed states are tighter than the one already stored. 00459 * Notice, "satisfySates" holds the set of states satisfying the formula 00460 * computed with the combined_system(optimal_system || current_subsystem). 00461 * 00462 */ 00463 if( subSystem->satisfyStates != NIL(mdd_t) ) { 00464 00465 if( !(mdd_equal(subSystem->satisfyStates, satisfyStates )) && 00466 (mdd_lequal(subSystem->satisfyStates, satisfyStates, 1, 1)) ) { 00467 /* We got a tighter approximation. */ 00468 mdd_free(subSystem->satisfyStates); 00469 AmcSubsystemSetSatisfy(subSystem, mdd_dup(satisfyStates)); 00470 } 00471 00472 } 00473 else { 00474 /* We are in the first level of the lattice */ 00475 AmcSubsystemSetSatisfy(subSystem, mdd_dup(satisfyStates)); 00476 00477 } 00478 00479 /* Update the set of states satisfying the formula for the combined_system. */ 00480 if( AmcSubsystemReadSatisfy(combinedSystem) != NIL(mdd_t) ) 00481 mdd_free( AmcSubsystemReadSatisfy(combinedSystem) ); 00482 AmcSubsystemSetSatisfy(combinedSystem, mdd_dup(satisfyStates)); 00483 00484 00485 if( verbosity == Amc_VerbosityVomit_c) { 00486 mdd_manager *mddMgr = Fsm_FsmReadMddManager(combinedSystem->fsm); 00487 array_t *psVars = Fsm_FsmReadPresentStateVars(combinedSystem->fsm); 00488 00489 fprintf(vis_stdout, "\n#AMC STATUS: The states satisfying the formula : %10g", 00490 mdd_count_onset( mddMgr, combinedSystem->satisfyStates, psVars ) ); 00491 fflush(vis_stdout); 00492 } 00493 00494 /* 00495 * Check whether the formula evaluates to TRUE. 00496 */ 00497 { 00498 mdd_t *notSatisfyStates = mdd_not(satisfyStates); 00499 currentErrorStates = mdd_and(initialStates, notSatisfyStates, 1, 1); 00500 mdd_free(notSatisfyStates); 00501 mdd_free(satisfyStates); 00502 } 00503 00504 if ( mdd_is_tautology(currentErrorStates, 0) ) { 00505 /* The formula is verified TRUE!! */ 00506 00507 AmcBlockSetBestSystem(BlockInfo, i); 00508 amcInfo->isVerified = 1; 00509 amcInfo->amcAnswer = Amc_Verified_True_c; 00510 fprintf(vis_stdout, "\n# AMC: formula passed --- "); 00511 Ctlp_FormulaPrint(vis_stdout, Ctlp_FormulaReadOriginalFormula(formula)); 00512 00513 if(currentErrorStates != NIL(mdd_t)) 00514 mdd_free(currentErrorStates); 00515 if(smallestStates != NIL(mdd_t)) 00516 mdd_free(smallestStates); 00517 if( bestCombinedSystem != NIL(Amc_SubsystemInfo_t) ) 00518 Amc_AmcSubsystemFree(bestCombinedSystem); 00519 00520 mdd_free(mddOne); Amc_AmcSubsystemFree(combinedSystem); 00521 Ctlp_FlushStates(formula); 00522 00523 return BlockInfo; 00524 } /* end of if */ 00525 else if (amcInfo->currentLevel == array_n(amcInfo->subSystemArray)){ 00526 /* The formula is verified FALSE!! */ 00527 array_t *careStatesArray; 00528 00529 AmcBlockSetBestSystem(BlockInfo, i); 00530 amcInfo->isVerified = 1; 00531 amcInfo->amcAnswer = Amc_Verified_False_c; 00532 fprintf(vis_stdout, "\n# AMC: formula failed --- "); 00533 Ctlp_FormulaPrint(vis_stdout, Ctlp_FormulaReadOriginalFormula(formula)); 00534 00535 if(currentErrorStates != NIL(mdd_t)) mdd_free(currentErrorStates); 00536 if(smallestStates != NIL(mdd_t)) mdd_free(smallestStates); 00537 00538 if( bestCombinedSystem != NIL(Amc_SubsystemInfo_t) ) 00539 Amc_AmcSubsystemFree(bestCombinedSystem); 00540 00541 { 00542 /* Temporarily stay here until the damn thing becomes visible. */ 00543 McOptions_t *mcOptions = ALLOC(McOptions_t, 1); 00544 mcOptions->useMore = FALSE; 00545 mcOptions->fwdBwd = McFwd_c; 00546 mcOptions->reduceFsm = FALSE; 00547 mcOptions->printInputs = FALSE; 00548 mcOptions->simFormat = FALSE; 00549 mcOptions->verbosityLevel = McVerbosityNone_c; 00550 mcOptions->dbgLevel = McDbgLevelMin_c; 00551 mcOptions->dcLevel = McDcLevelNone_c; 00552 mcOptions->ctlFile = NIL(FILE); 00553 mcOptions->debugFile = NIL(FILE); 00554 00555 careStatesArray = array_alloc(mdd_t *, 0); 00556 array_insert(mdd_t *, careStatesArray, 0, mddOne); 00557 fprintf(vis_stdout, "\n"); 00558 McFsmDebugFormula((McOptions_t *)mcOptions, formula, 00559 combinedSystem->fsm, careStatesArray); 00560 array_free(careStatesArray); 00561 FREE(mcOptions); 00562 } 00563 mdd_free(mddOne); 00564 Amc_AmcSubsystemFree(combinedSystem); 00565 Ctlp_FlushStates(formula); 00566 00567 return BlockInfo; 00568 } 00569 00570 /* 00571 * Get the locally optimal subsystem by choosing a subsystem that produces 00572 * smallest error states. 00573 */ 00574 if( smallestStates == NIL(mdd_t) || 00575 mdd_count_onset(mddManager, currentErrorStates, Fsm_FsmReadPresentStateVars(subSystem->fsm)) <= 00576 mdd_count_onset(mddManager, smallestStates, Fsm_FsmReadPresentStateVars(subSystem->fsm)) ) { 00577 00578 if( smallestStates != NIL(mdd_t) ) 00579 mdd_free(smallestStates); 00580 00581 smallestStates = currentErrorStates; 00582 00583 if(bestCombinedSystem != NIL(Amc_SubsystemInfo_t)) { 00584 Amc_AmcSubsystemFree(bestCombinedSystem); 00585 bestCombinedSystem = NIL(Amc_SubsystemInfo_t); 00586 } 00587 bestCombinedSystem = combinedSystem; 00588 best = i; 00589 } 00590 00591 else { /* Free combined system, current error states */ 00592 Amc_AmcSubsystemFree(combinedSystem); 00593 combinedSystem = NIL(Amc_SubsystemInfo_t); 00594 mdd_free(currentErrorStates); 00595 } 00596 00597 00598 } /* end of if(!takenIntoOptimal) */ 00599 00600 } /* end of arrayForEachItem(subSystemArray) */ 00601 00602 00603 /* 00604 * Flush the formula that was kept in last iteration. 00605 * Update Block Info. 00606 */ 00607 Ctlp_FlushStates(formula); 00608 00609 /* Update the inital states */ 00610 { 00611 mdd_t *initialStates; 00612 if((initialStates = AmcReadInitialStates(amcInfo)) != NIL(mdd_t)) 00613 mdd_free(initialStates); 00614 AmcSetInitialStates(amcInfo, smallestStates); 00615 } 00616 00617 if( verbosity == Amc_VerbositySpit_c ) { 00618 mdd_manager *mddMgr = Fsm_FsmReadMddManager(bestCombinedSystem->fsm); 00619 array_t *psVars = Fsm_FsmReadPresentStateVars(bestCombinedSystem->fsm); 00620 00621 fprintf(vis_stdout, "\n#AMC : The BDD size of the states satisfying the formula : %d", 00622 mdd_size(bestCombinedSystem->satisfyStates) ); 00623 fprintf(vis_stdout, "\n#AMC : The cardinality of the states satisfying the formula : %10g ", 00624 mdd_count_onset( mddMgr, bestCombinedSystem->satisfyStates, psVars ) ); 00625 fprintf(vis_stdout, "\n#AMC : The BDD size of the states new initial states : %d", 00626 mdd_size(smallestStates) ); 00627 fprintf(vis_stdout, "\n#AMC : The cardinality of the new initial states : %10g ", 00628 mdd_count_onset( mddMgr, smallestStates, psVars ) ); 00629 } 00630 00631 00632 /* 00633 * Update the optimal system BlockInfo->optimalSystem. BlockInfo is a temporary 00634 * storage that survive through single level of the lattice. 00635 */ 00636 if(BlockInfo->optimalSystem != NIL(Amc_SubsystemInfo_t)) { 00637 Amc_AmcSubsystemFree(BlockInfo->optimalSystem); 00638 AmcBlockSetOptimalSystem(BlockInfo, NIL(Amc_SubsystemInfo_t)); 00639 } 00640 AmcSetOptimalSystem(BlockInfo, bestCombinedSystem); 00641 00642 /* Set the best system. */ 00643 AmcBlockSetBestSystem(BlockInfo, best); 00644 00645 mdd_free(mddOne); 00646 00647 return BlockInfo; 00648 00649 } 00650 00651 00665 static BlockInfo_t * 00666 AmcObtainOptimalSystemLowerBound( 00667 Amc_Info_t *amcInfo, 00668 Ctlp_Formula_t *formula, 00669 BlockInfo_t *BlockInfo, 00670 int verbosity) 00671 { 00672 array_t *subSystemArray = amcInfo->subSystemArray; 00673 Amc_SubsystemInfo_t *subSystem, *bestCombinedSystem; 00674 mdd_t *initialStates; 00675 mdd_t *smallestStates, *currentErrorStates, *careStates; 00676 int i, best = 0; 00677 graph_t *partition = Part_NetworkReadPartition(amcInfo->network); 00678 mdd_manager *mddManager = Part_PartitionReadMddManager(partition); 00679 mdd_t *mddOne = mdd_one(mddManager); 00680 array_t *quantifyVars; 00681 Mc_DcLevel dcLevel; 00682 char *flagValue; 00683 00684 /* 00685 * Initial states must be set before coming into this routine. 00686 */ 00687 initialStates = amcInfo->initialStates; 00688 if( initialStates == NIL(mdd_t) ) { 00689 (void)fprintf(vis_stderr, "** amc error: \n"); 00690 return(NIL(BlockInfo_t)); 00691 } 00692 00693 /* Read in the usage of don't care level. Do not want to pass parameters. */ 00694 flagValue = Cmd_FlagReadByName("amc_DC_level"); 00695 if(flagValue != NIL(char)){ 00696 dcLevel = (Mc_DcLevel) atoi(flagValue); 00697 if( dcLevel > McDcLevelRchFrontier_c ) dcLevel = McDcLevelRchFrontier_c; 00698 } 00699 else{ 00700 /* default value set to McDcLevelNone_c. Mc's default is McDcLevelRch_c. */ 00701 dcLevel = McDcLevelNone_c; 00702 } 00703 00704 /* 00705 * Update the set of states satisfying the formula for each subsystem. 00706 * The process of "combining sub-systems" is equivalent of taking a 00707 * "synchronous product" of multiple subsystems. 00708 */ 00709 smallestStates = NIL(mdd_t); 00710 bestCombinedSystem = NIL(Amc_SubsystemInfo_t); 00711 00712 arrayForEachItem(Amc_SubsystemInfo_t *, subSystemArray, i, subSystem) { 00713 00714 mdd_t *reachableStates, *fairStates, *satisfyStates; 00715 Fsm_Fsm_t *combinedFsm; 00716 Fsm_Fairness_t *fairCond; 00717 Amc_SubsystemInfo_t *combinedSystem; 00718 00719 /* Proceed if the subsystem has not yet been taken into the optimal system. */ 00720 if(!subSystem->takenIntoOptimal) { 00721 00722 /* 00723 * Combine subsystems. If optimal subsystem is NIL, duplicate the 00724 * subsystem. 00725 */ 00726 combinedSystem = Amc_CombineSubsystems(amcInfo->network, 00727 amcInfo->optimalSystem, 00728 subSystem); 00729 /* Remove input variables from the FSM */ 00730 /* combinedSystem = AmcClearInputVarsFromFSM(combinedSystem);*/ 00731 combinedFsm = AmcSubsystemReadFsm(combinedSystem); 00732 00733 /* 00734 * Use takenIntoOptimal field for the purpose of excluding current block 00735 * when universally quantifying variables from transition relation. 00736 * Obtain lower bound of transition relation by universal quantification. 00737 */ 00738 00739 quantifyVars = AmcInitializeQuantifyVars(combinedSystem); 00740 combinedSystem->takenIntoOptimal = i; 00741 00742 00743 /* 00744 * Currently forced not to compute reachable states. This is to reduce 00745 * computational burden of computing it when dealing with complex 00746 * examples. 00747 */ 00748 reachableStates = mdd_one(mddManager); 00749 fairStates = mdd_one(mddManager); 00750 fairCond = Fsm_FsmReadFairnessConstraint(combinedFsm); 00751 careStates = mdd_dup(reachableStates); 00752 00753 Ctlp_FlushStates(formula); 00754 satisfyStates = mdd_dup(Amc_AmcEvaluateCTLFormula(combinedSystem, 00755 subSystemArray, 00756 formula, fairStates, 00757 fairCond, careStates, 00758 amcInfo->lowerBound, 00759 quantifyVars, 00760 (Mc_VerbosityLevel) 00761 verbosity, dcLevel)); 00762 { 00763 int x; array_t *quantifyStateVars; 00764 arrayForEachItem(array_t *, quantifyVars, x, quantifyStateVars) { 00765 array_free(quantifyStateVars); 00766 } 00767 array_free(quantifyVars); 00768 } 00769 mdd_free(careStates); mdd_free(reachableStates); mdd_free(fairStates); 00770 00771 00772 /* 00773 */ 00774 if( subSystem->satisfyStates != NIL(mdd_t) ) { 00775 if( !(mdd_equal(satisfyStates, subSystem->satisfyStates )) && 00776 (mdd_lequal(satisfyStates, subSystem->satisfyStates, 1, 1)) ) { 00777 /* We got a tighter approximation. */ 00778 mdd_free(subSystem->satisfyStates); 00779 AmcSubsystemSetSatisfy(subSystem, mdd_dup(satisfyStates)); 00780 } 00781 } /* end of if( subSystem->satisfyStates != NIL(mdd_t) ) */ 00782 else { 00783 /* Update subsystem when we are in level 1 of the lattice */ 00784 AmcSubsystemSetSatisfy(subSystem, mdd_dup(satisfyStates)); 00785 } 00786 00787 if( AmcSubsystemReadSatisfy(combinedSystem) != NIL(mdd_t) ) 00788 mdd_free( AmcSubsystemReadSatisfy(combinedSystem) ); 00789 AmcSubsystemSetSatisfy(combinedSystem, mdd_dup(satisfyStates)); 00790 00791 00792 /* Test if the formula is verified */ 00793 { 00794 mdd_t *notSatisfyStates = mdd_not(satisfyStates); 00795 currentErrorStates = mdd_and(initialStates, notSatisfyStates, 1, 1); 00796 mdd_free(notSatisfyStates); 00797 mdd_free(satisfyStates); 00798 } 00799 00800 if( verbosity == Amc_VerbosityVomit_c) { 00801 mdd_manager *mddMgr = Fsm_FsmReadMddManager(combinedSystem->fsm); 00802 array_t *psVars = Fsm_FsmReadPresentStateVars(combinedSystem->fsm); 00803 00804 fprintf(vis_stdout, 00805 "\n#AMC STATUS: The states satisfying the formula : %10g", 00806 mdd_count_onset(mddMgr, combinedSystem->satisfyStates, psVars ) ); 00807 fflush(vis_stdout); 00808 } 00809 00810 if ( !mdd_is_tautology(currentErrorStates, 0) ) { 00811 array_t *careStatesArray; 00812 00813 /* Verified the formula FALSE!! */ 00814 AmcBlockSetBestSystem(BlockInfo, i); 00815 amcInfo->isVerified = 1; 00816 amcInfo->amcAnswer = Amc_Verified_False_c; 00817 fprintf(vis_stdout, "\n# AMC: formula failed --- "); 00818 Ctlp_FormulaPrint(vis_stdout, Ctlp_FormulaReadOriginalFormula(formula)); 00819 00820 00821 if(currentErrorStates != NIL(mdd_t)) mdd_free(currentErrorStates); 00822 if(smallestStates != NIL(mdd_t)) mdd_free(smallestStates); 00823 00824 if( bestCombinedSystem != NIL(Amc_SubsystemInfo_t) ) 00825 Amc_AmcSubsystemFree(bestCombinedSystem); 00826 00827 { 00828 /* Temporarily stay here until the damn thing becomes visible. */ 00829 McOptions_t *mcOptions = ALLOC(McOptions_t, 1); 00830 mcOptions->useMore = FALSE; 00831 mcOptions->fwdBwd = McFwd_c; 00832 mcOptions->reduceFsm = FALSE; 00833 mcOptions->printInputs = FALSE; 00834 mcOptions->simFormat = FALSE; 00835 mcOptions->verbosityLevel = McVerbosityNone_c; 00836 mcOptions->dbgLevel = McDbgLevelMinVerbose_c; 00837 mcOptions->dcLevel = McDcLevelNone_c; 00838 mcOptions->ctlFile = NIL(FILE); 00839 mcOptions->debugFile = NIL(FILE); 00840 00841 careStatesArray = array_alloc(mdd_t *, 0); 00842 array_insert(mdd_t *, careStatesArray, 0, mddOne); 00843 fprintf(vis_stdout, "\n"); 00844 McFsmDebugFormula((McOptions_t *)mcOptions, formula, 00845 combinedSystem->fsm, careStatesArray); 00846 array_free(careStatesArray); 00847 FREE(mcOptions); 00848 } 00849 mdd_free(mddOne); 00850 Amc_AmcSubsystemFree(combinedSystem); 00851 Ctlp_FlushStates(formula); 00852 00853 return BlockInfo; 00854 00855 }else if (amcInfo->currentLevel == array_n(amcInfo->subSystemArray)){ 00856 /* The formula is verified true!! */ 00857 AmcBlockSetBestSystem(BlockInfo, i); 00858 amcInfo->isVerified = 1; 00859 amcInfo->amcAnswer = Amc_Verified_True_c; 00860 fprintf(vis_stdout, "\n# AMC: formula passed --- "); 00861 Ctlp_FormulaPrint(vis_stdout, Ctlp_FormulaReadOriginalFormula(formula)); 00862 00863 00864 if(currentErrorStates != NIL(mdd_t)) 00865 mdd_free(currentErrorStates); 00866 if(smallestStates != NIL(mdd_t)) 00867 mdd_free(smallestStates); 00868 if( bestCombinedSystem != NIL(Amc_SubsystemInfo_t) ) 00869 Amc_AmcSubsystemFree(bestCombinedSystem); 00870 00871 mdd_free(mddOne); Amc_AmcSubsystemFree(combinedSystem); 00872 Ctlp_FlushStates(formula); 00873 00874 return BlockInfo; 00875 } 00876 00877 mdd_free(currentErrorStates); 00878 00879 00880 /* 00881 * Choose a subsystem that produces smallest satisfying states. 00882 */ 00883 if( smallestStates == NIL(mdd_t) || 00884 mdd_count_onset(mddManager, subSystem->satisfyStates, Fsm_FsmReadPresentStateVars(subSystem->fsm)) <= 00885 mdd_count_onset(mddManager, smallestStates, Fsm_FsmReadPresentStateVars(subSystem->fsm)) ) { 00886 /* 00887 * Found locally optimal subsystem. 00888 * Free smallest-error-state, best combined system so far. 00889 * Update smallest-error-states and best combined system. 00890 */ 00891 if( smallestStates != NIL(mdd_t) ) mdd_free(smallestStates); 00892 00893 smallestStates = mdd_dup(subSystem->satisfyStates); 00894 00895 if(bestCombinedSystem != NIL(Amc_SubsystemInfo_t)) { 00896 Amc_AmcSubsystemFree(bestCombinedSystem); 00897 bestCombinedSystem = NIL(Amc_SubsystemInfo_t); 00898 } 00899 bestCombinedSystem = combinedSystem; 00900 best = i; 00901 } 00902 00903 else { /* Free combined system, current error states */ 00904 Amc_AmcSubsystemFree(combinedSystem); combinedSystem = NIL(Amc_SubsystemInfo_t); 00905 } 00906 00907 } /* end of if(!takenIntoOptimal) */ 00908 00909 } /* end of arrayForEachItem(subSystemArray) */ 00910 00911 mdd_free(smallestStates); 00912 00913 /* 00914 * Flush formula that was kept in last iteration. Update Block Info. 00915 */ 00916 Ctlp_FlushStates(formula); 00917 00918 /* 00919 * Update optimal system BlockInfo->optimalSystem. BlockInfo is a temporary 00920 * storage that survive through single level of the lattice. 00921 */ 00922 if(BlockInfo->optimalSystem != NIL(Amc_SubsystemInfo_t)) { 00923 Amc_AmcSubsystemFree(BlockInfo->optimalSystem); 00924 AmcBlockSetOptimalSystem(BlockInfo, NIL(Amc_SubsystemInfo_t)); 00925 } 00926 AmcSetOptimalSystem(BlockInfo, bestCombinedSystem); 00927 00928 /* Set best system. */ 00929 AmcBlockSetBestSystem(BlockInfo, best); 00930 mdd_free(mddOne); 00931 00932 return BlockInfo; 00933 00934 } 00935 00936 00937 00945 static void 00946 AmcInitializeDependency( 00947 array_t *subSystemArray, 00948 int isMBM) 00949 { 00950 Amc_SubsystemInfo_t *subSystem; 00951 BlockSubsystemInfo_t *BlockSubsystem; 00952 int i; 00953 00954 if(!isMBM) { 00955 int i; 00956 arrayForEachItem(Amc_SubsystemInfo_t *, subSystemArray, i, subSystem) { 00957 AmcSubsystemSetMethodSpecificData(subSystem, NIL(BlockSubsystemInfo_t)); 00958 } 00959 return; 00960 } 00961 00962 arrayForEachItem(Amc_SubsystemInfo_t *, subSystemArray, i, subSystem) { 00963 00964 BlockSubsystem = ALLOC(BlockSubsystemInfo_t, 1); 00965 00966 AmcSubsystemSetMethodSpecificData(subSystem, BlockSubsystem); 00967 00968 } 00969 00970 } 00971 00979 static void 00980 AmcInitializeSchedule( 00981 Amc_Info_t *amcInfo) 00982 { 00983 array_t *subSystemArray = amcInfo->subSystemArray; 00984 Amc_SubsystemInfo_t *subSystem; 00985 BlockSubsystemInfo_t *BlockSubsystem; 00986 int i; 00987 00988 /* If MBM flag is not set just return */ 00989 if(!amcInfo->isMBM) 00990 return; 00991 00992 arrayForEachItem(Amc_SubsystemInfo_t *, subSystemArray, i, subSystem) { 00993 00994 BlockSubsystem = (BlockSubsystemInfo_t *) AmcSubsystemReadMethodSpecificData(subSystem); 00995 if(!subSystem->takenIntoOptimal) 00996 AmcBlockSubsystemSetScheduledForRefinement(BlockSubsystem, 1); 00997 00998 } 00999 01000 } 01001 01002 01010 static int 01011 AmcIsEverySubsystemRescheduled( 01012 Amc_Info_t *amcInfo) 01013 { 01014 array_t *subSystemArray = amcInfo->subSystemArray; 01015 Amc_SubsystemInfo_t *subSystem; 01016 BlockSubsystemInfo_t *BlockSubsystem; 01017 int i; 01018 01019 /* If MBM flag is not set just return */ 01020 if( !amcInfo->isMBM ) 01021 return 1; 01022 01023 arrayForEachItem(Amc_SubsystemInfo_t *, subSystemArray, i, subSystem) { 01024 01025 BlockSubsystem = (BlockSubsystemInfo_t *) AmcSubsystemReadMethodSpecificData(subSystem); 01026 if( AmcBlockSubsystemReadScheduledForRefinement(BlockSubsystem) ) 01027 return 1; 01028 01029 } 01030 return 0; 01031 01032 } 01033 01041 static void 01042 AmcPrintScheduleInformation( 01043 Amc_Info_t *amcInfo) 01044 { 01045 array_t *subSystemArray = amcInfo->subSystemArray; 01046 Amc_SubsystemInfo_t *subSystem; 01047 BlockSubsystemInfo_t *BlockSubsystem; 01048 int i; 01049 01050 /* If MBM flag is not set just return */ 01051 if(!amcInfo->isMBM) 01052 return; 01053 01054 fprintf(vis_stdout, "\nSchedule information : "); 01055 01056 arrayForEachItem(Amc_SubsystemInfo_t *, subSystemArray, i, subSystem) { 01057 01058 BlockSubsystem = (BlockSubsystemInfo_t *) AmcSubsystemReadMethodSpecificData(subSystem); 01059 fprintf(vis_stdout, " %d ", AmcBlockSubsystemReadScheduledForRefinement(BlockSubsystem) ); 01060 01061 } 01062 01063 } 01064 01065 01066 #if 0 01067 01074 static void 01075 AmcRescheduleForRefinement( 01076 st_table *fanOutSystemTable) 01077 { 01078 Amc_SubsystemInfo_t *subSystem; 01079 BlockSubsystemInfo_t *BlockSubsystem; 01080 st_generator *stGen; 01081 01082 st_foreach_item(fanOutSystemTable, stGen, &subSystem, NIL(char *)) { 01083 01084 /* reschedule only ones that are not taken */ 01085 if(!subSystem->takenIntoOptimal) { 01086 BlockSubsystem = (BlockSubsystemInfo_t *) AmcSubsystemReadMethodSpecificData(subSystem); 01087 AmcBlockSubsystemSetScheduledForRefinement(BlockSubsystem, 1); 01088 } 01089 01090 } 01091 01092 } 01093 01101 static mdd_t * 01102 AmcRefineWithSatisfyStatesOfFanInSystem( 01103 Amc_SubsystemInfo_t *subSystem, 01104 mdd_t *careStates) 01105 { 01106 st_table *fanInTable = AmcSubsystemReadFanInTable(subSystem); 01107 Amc_SubsystemInfo_t *fanInSystem; 01108 st_generator *stGen; 01109 01110 mdd_t *oldCareStates = careStates; 01111 st_foreach_item(fanInTable, stGen, &fanInSystem, NIL(char *)) { 01112 01113 if(fanInSystem->satisfyStates != NIL(mdd_t)) { 01114 mdd_t *fanInSatisfyStates = mdd_dup(fanInSystem->satisfyStates); 01115 careStates = mdd_and(fanInSatisfyStates, oldCareStates, 1, 1); 01116 mdd_free(oldCareStates); mdd_free(fanInSatisfyStates); 01117 oldCareStates = careStates; 01118 } 01119 01120 } 01121 01122 return(careStates); 01123 } /* end of "machine by machine" refinement of the careset */ 01124 #endif 01125 01126 01135 static array_t * 01136 AmcInitializeQuantifyVars( 01137 Amc_SubsystemInfo_t *subSystem) 01138 { 01139 array_t *quantifyVars = array_alloc(array_t *, 0); 01140 array_t *quantifyPresentVars = array_alloc(int, 0); 01141 array_t *quantifyNextVars = array_alloc(int, 0); 01142 array_t *quantifyInputVars = array_alloc(int, 0); 01143 Ntk_Network_t *network = Fsm_FsmReadNetwork(AmcSubsystemReadFsm(subSystem)); 01144 Ntk_Node_t *latch; 01145 st_table *vertexTable = AmcSubsystemReadVertexTable(subSystem); 01146 lsGen gen; 01147 01148 Ntk_NetworkForEachLatch(network, gen, latch) { 01149 char *latchName = Ntk_NodeReadName(latch); 01150 #ifdef AMC_DEBUG 01151 fprintf(vis_stdout, "\nlatch name: %s", latchName); 01152 fprintf(vis_stdout, "\n latch id: %d", Ntk_NodeReadMddId(latch)); 01153 fprintf(vis_stdout, "\n latch id: %d", Ntk_NodeReadMddId(Ntk_NodeReadShadow(latch))); 01154 fflush(vis_stdout); 01155 #endif 01156 if(!st_lookup(vertexTable, latchName, (char **)0)) { 01157 01158 /* Next state variables. */ 01159 array_insert_last(int, quantifyNextVars, Ntk_NodeReadMddId(Ntk_NodeReadShadow(latch))); 01160 /* Present state variables. */ 01161 array_insert_last(int, quantifyPresentVars, Ntk_NodeReadMddId(latch)); 01162 01163 } /* end of if(st_lookup(vertexTable)) */ 01164 } /* end of Ntk_NetworkForEachLatch */ 01165 01166 01167 { 01168 st_table *inputVarTable = st_init_table(st_numcmp, st_numhash); 01169 Ntk_Node_t *primaryInput; 01170 /* Build the hash table of input vars of this subsystem. */ 01171 /* arrayForEachItem(int, inputVarArray, i, inputVar) { 01172 st_insert(inputVarTable, (char *)(long)inputVar, (char *)0); 01173 } */ 01174 01175 Ntk_NetworkForEachInput(network, gen, primaryInput) { 01176 int mddId = Ntk_NodeReadMddId(primaryInput); 01177 #ifdef AMC_DEBUG 01178 char *inputName = Ntk_NodeReadName(primaryInput); 01179 int testMddId = Ntk_NodeReadMddId(primaryInput); 01180 fprintf(vis_stdout, "\nprimary input name : %s", inputName); 01181 fprintf(vis_stdout, "\nprimary input mdd id : %d", testMddId); 01182 fflush(vis_stdout); 01183 #endif 01184 /* if(!st_lookup(inputVarTable, (char *)(long)mddId, (char **)0)) { */ 01185 array_insert_last(int, quantifyInputVars, mddId); 01186 /* } */ 01187 } 01188 st_free_table(inputVarTable); 01189 } 01190 01191 array_insert_last(array_t *, quantifyVars, quantifyPresentVars); 01192 array_insert_last(array_t *, quantifyVars, quantifyNextVars); 01193 array_insert_last(array_t *, quantifyVars, quantifyInputVars); 01194 01195 return quantifyVars; 01196 01197 } 01198 01199 01200 #if 0 01201 01208 static void 01209 AmcFreeBlockInfo( 01210 BlockInfo_t *BlockInfo) 01211 { 01212 01213 if(BlockInfo->optimalSystem != NIL(Amc_SubsystemInfo_t)) { 01214 Amc_AmcSubsystemFree(BlockInfo->optimalSystem); 01215 } 01216 01217 } 01218 #endif 01219 01220 01228 static int 01229 AmcBlockSubsystemReadScheduledForRefinement( 01230 BlockSubsystemInfo_t *system) 01231 { 01232 return system->scheduledForRefinement; 01233 } 01234 01242 static void 01243 AmcBlockSubsystemSetScheduledForRefinement( 01244 BlockSubsystemInfo_t *system, 01245 int data) 01246 { 01247 system->scheduledForRefinement = data; 01248 } 01249 01250 01251 #if 0 01252 01259 static Amc_SubsystemInfo_t * 01260 AmcBlockReadOptimalSubsystem( 01261 BlockInfo_t *system) 01262 { 01263 return system->optimalSystem; 01264 } 01265 #endif 01266 01274 static void 01275 AmcBlockSetOptimalSystem( 01276 BlockInfo_t *system, 01277 Amc_SubsystemInfo_t *data) 01278 { 01279 system->optimalSystem = data; 01280 } 01281 01282 #if 0 01283 01290 static int 01291 AmcBlockReadBestSystem( 01292 BlockInfo_t *system) 01293 { 01294 return system->bestSystem; 01295 } 01296 #endif 01297 01305 static void 01306 AmcBlockSetBestSystem( 01307 BlockInfo_t *system, 01308 int data) 01309 { 01310 system->bestSystem = data; 01311 } 01312 01313 #if 0 01314 01325 static Amc_SubsystemInfo_t * 01326 AmcClearInputVarsFromFSM( 01327 Amc_SubsystemInfo_t *subSystem) 01328 { 01329 Fsm_Fsm_t *fsm = subSystem->fsm; 01330 array_t *inputVarArray = Fsm_FsmReadInputVars(fsm); 01331 array_t *newInputVarArray = array_alloc(int, 0); 01332 01333 array_free(inputVarArray); 01334 (void) Fsm_FsmSetInputVars(fsm, newInputVarArray); 01335 01336 return(subSystem); 01337 } 01338 #endif