VIS
|
00001 00031 #include "mcInt.h" 00032 00033 static char rcsid[] UNUSED = "$Id: mcDnC.c,v 1.9 2005/05/18 18:12:00 jinh Exp $"; 00034 00035 /*---------------------------------------------------------------------------*/ 00036 /* Constant declarations */ 00037 /*---------------------------------------------------------------------------*/ 00038 00039 /*---------------------------------------------------------------------------*/ 00040 /* Structure declarations */ 00041 /*---------------------------------------------------------------------------*/ 00042 00043 /*---------------------------------------------------------------------------*/ 00044 /* Type declarations */ 00045 /*---------------------------------------------------------------------------*/ 00046 00047 /*---------------------------------------------------------------------------*/ 00048 /* Variable declarations */ 00049 /*---------------------------------------------------------------------------*/ 00050 00051 /*---------------------------------------------------------------------------*/ 00052 /* Macro declarations */ 00053 /*---------------------------------------------------------------------------*/ 00054 00057 /*---------------------------------------------------------------------------*/ 00058 /* Static function prototypes */ 00059 /*---------------------------------------------------------------------------*/ 00060 static int SccIsStrong(mdd_manager *mddMgr, array_t *buechiFairness, mdd_t *SCC); 00061 static array_t * SortMddArrayBySize(Fsm_Fsm_t *fsm, array_t *mddArray); 00062 static int stringCompare(const void * s1, const void * s2); 00066 /*---------------------------------------------------------------------------*/ 00067 /* Definition of exported functions */ 00068 /*---------------------------------------------------------------------------*/ 00069 00096 mdd_t * 00097 Mc_FsmCheckLanguageEmptinessByDnC( 00098 Fsm_Fsm_t *modelFsm, 00099 array_t *modelCareStates, 00100 Mc_AutStrength_t automatonStrength, 00101 int dcLevel, 00102 int dbgLevel, 00103 int printInputs, 00104 int verbosity, 00105 Mc_GSHScheduleType GSHschedule, 00106 Mc_FwdBwdAnalysis GSHdirection, 00107 int lockstep, 00108 FILE *dbgFile, 00109 int UseMore, 00110 int SimValue, 00111 char *driverName) 00112 { 00113 Ntk_Network_t *network = Fsm_FsmReadNetwork(modelFsm); 00114 mdd_manager *mddManager = Fsm_FsmReadMddManager(modelFsm); 00115 Fsm_Fairness_t *modelFairness = NIL(Fsm_Fairness_t); 00116 array_t *buechiFairness = NIL(array_t); 00117 int isExactReachableStatesAvailable = 0; 00118 mdd_t *reachableStates, *initialStates = NIL(mdd_t); 00119 mdd_t *fairStates, *fairInitialStates = NIL(mdd_t); 00120 array_t *onionRings = NIL(array_t); 00121 array_t *strongSccClosedSets = NIL(array_t); 00122 array_t *absLatchNameTableArray = NIL(array_t); 00123 int numOfAbstractModels, iter, i, exitFlag; 00124 array_t *arrayOfOnionRings = NIL(array_t); 00125 array_t *ctlArray = array_alloc(Ctlp_Formula_t *, 0); 00126 array_t *modelCareStatesArray = mdd_array_duplicate(modelCareStates); 00127 Mc_SccGen_t *sccgen; 00128 int composeIncSize, numOfLatches, maxLatchesToCompose; 00129 00130 int maxComposePercentage = 30; 00131 int maxSccsToEnum = 100; 00132 00133 00134 /* 00135 * Read fairness constraints. 00136 */ 00137 modelFairness = Fsm_FsmReadFairnessConstraint(modelFsm); 00138 buechiFairness = array_alloc(mdd_t *, 0); 00139 if (modelFairness != NIL(Fsm_Fairness_t)) { 00140 if (!Fsm_FairnessTestIsBuchi(modelFairness)) { 00141 (void) fprintf(vis_stdout, 00142 "** non-Buechi fairness constraints not supported\n"); 00143 array_free(buechiFairness); 00144 assert(0); 00145 } else { 00146 int j; 00147 int numBuchi = Fsm_FairnessReadNumConjunctsOfDisjunct(modelFairness, 0); 00148 for (j = 0; j < numBuchi; j++) { 00149 Ctlp_Formula_t *tmpFormula; 00150 mdd_t *tempMdd; 00151 tmpFormula = Fsm_FairnessReadFinallyInfFormula(modelFairness, 0, j ); 00152 tempMdd = Fsm_FairnessObtainFinallyInfMdd(modelFairness, 0, j, 00153 modelCareStatesArray, 00154 (Mc_DcLevel) dcLevel); 00155 array_insert_last(mdd_t *, buechiFairness, tempMdd); 00156 array_insert_last( Ctlp_Formula_t *, ctlArray, 00157 Ctlp_FormulaDup(tmpFormula)); 00158 #if 1 00159 fprintf(vis_stdout,"\nFairness[%d]:",j); 00160 Ctlp_FormulaPrint(vis_stdout, tmpFormula); 00161 fprintf(vis_stdout,"\n"); 00162 #endif 00163 } 00164 } 00165 } else { 00166 array_insert_last(mdd_t *, buechiFairness, mdd_one(mddManager)); 00167 } 00168 00169 /* 00170 * If we need debugging information, arrayOfOnionRings != NIL(array_t), 00171 */ 00172 if (dbgLevel != McDbgLevelNone_c) 00173 arrayOfOnionRings = array_alloc(array_t *, 0); 00174 else 00175 arrayOfOnionRings = NIL(array_t); 00176 00177 /* 00178 * If exact/approximate reachable states are available, use them. 00179 */ 00180 initialStates = Fsm_FsmComputeInitialStates(modelFsm); 00181 reachableStates = Fsm_FsmReadReachableStates(modelFsm); 00182 isExactReachableStatesAvailable = (reachableStates != NIL(mdd_t)); 00183 if (!isExactReachableStatesAvailable) 00184 reachableStates = McMddArrayAnd(modelCareStatesArray); 00185 else 00186 reachableStates = mdd_dup(reachableStates); 00187 onionRings = Fsm_FsmReadReachabilityOnionRings(modelFsm); 00188 if (onionRings == NIL(array_t)) { 00189 onionRings = array_alloc(mdd_t *, 0); 00190 array_insert(mdd_t *, onionRings, 0, mdd_dup(reachableStates)); 00191 }else 00192 onionRings = mdd_array_duplicate(onionRings); 00193 00194 strongSccClosedSets = array_alloc(mdd_t *, 0); 00195 array_insert(mdd_t *, strongSccClosedSets, 0, mdd_dup(reachableStates)); 00196 00197 /* 00198 * Compute a series of over-approximated abstract models 00199 */ 00200 numOfLatches = array_n(Fsm_FsmReadPresentStateVars(modelFsm)); 00201 maxLatchesToCompose = (numOfLatches * maxComposePercentage/100); 00202 maxLatchesToCompose = (maxLatchesToCompose > 20)? maxLatchesToCompose:20; 00203 composeIncSize = maxLatchesToCompose/10; 00204 composeIncSize = (composeIncSize > 4)? composeIncSize:4; 00205 00206 absLatchNameTableArray = 00207 Mc_CreateStaticRefinementScheduleArray(network, 00208 ctlArray, 00209 NIL(array_t), 00210 NIL(array_t), 00211 FALSE, 00212 FALSE, 00213 ((verbosity<McVerbosityMax_c)? 00214 0:McVerbositySome_c), 00215 composeIncSize, 00216 Part_CorrelationWithSupport); 00217 numOfAbstractModels = (array_n(absLatchNameTableArray) - 1); 00218 if (verbosity >= McVerbosityLittle_c) { 00219 fprintf(vis_stdout, 00220 "-- DnC: scheduled total %d abs models with %d latches\n", 00221 numOfAbstractModels, numOfLatches); 00222 } 00223 00224 if (verbosity >= McVerbositySome_c) { 00225 fprintf(vis_stdout, "-- DnC:\n"); 00226 fprintf(vis_stdout, 00227 "-- DnC: maxComposePercentage = %d\n", maxComposePercentage); 00228 fprintf(vis_stdout, 00229 "-- DnC: numOfLatches = %d\n", numOfLatches); 00230 fprintf(vis_stdout, 00231 "-- DnC: composeIncSize = %d\n", composeIncSize); 00232 fprintf(vis_stdout, 00233 "-- DnC: numOfAbstractModels = %d\n", numOfAbstractModels); 00234 fprintf(vis_stdout, 00235 "-- DnC: maxLatchesToCompose = %d\n", maxLatchesToCompose); 00236 fprintf(vis_stdout, 00237 "-- DnC: maxSccsToEnum = %d\n", maxSccsToEnum); 00238 fprintf(vis_stdout, "-- Dnc: \n"); 00239 } 00240 00241 exitFlag = 0; 00242 for (iter=0; iter<numOfAbstractModels; iter++) { 00243 Fsm_Fsm_t *absFsm = NIL(Fsm_Fsm_t); 00244 st_table *absLatchNameTable = NIL(st_table); 00245 array_t *absOnionRings; 00246 array_t *tempArray = NIL(array_t); 00247 mdd_t *sccClosedSet = NIL(mdd_t); 00248 mdd_t *tempMdd = NIL(mdd_t); 00249 mdd_t *absReachableStates = NIL(mdd_t); 00250 00251 absLatchNameTable = array_fetch(st_table *, absLatchNameTableArray, iter); 00252 absFsm = Fsm_FsmCreateSubsystemFromNetwork(network, NIL(graph_t), 00253 absLatchNameTable, TRUE, 1); 00254 00255 if (!isExactReachableStatesAvailable) { 00256 absReachableStates = Fsm_FsmComputeReachableStates(absFsm, 0, 0, 0, 0, 00257 1, 0, 0, 00258 Fsm_Rch_Default_c, 00259 0, 0, 00260 NIL(array_t), FALSE, 00261 NIL(array_t)); 00262 absOnionRings = Fsm_FsmReadReachabilityOnionRings(absFsm); 00263 assert(absOnionRings); 00264 absOnionRings = mdd_array_duplicate(absOnionRings); 00265 }else { 00266 absReachableStates = McComputeAbstractStates(absFsm, reachableStates); 00267 absOnionRings = array_alloc(mdd_t *, array_n(onionRings)); 00268 arrayForEachItem(mdd_t *, onionRings, i, tempMdd) { 00269 array_insert(mdd_t *, absOnionRings, i, 00270 McComputeAbstractStates(absFsm, tempMdd) ); 00271 } 00272 } 00273 00274 tempArray = strongSccClosedSets; 00275 strongSccClosedSets = array_alloc(mdd_t *, 0); 00276 arrayForEachItem(mdd_t *, tempArray, i, sccClosedSet) { 00277 sccClosedSet = (iter == 0)? 00278 McComputeAbstractStates(absFsm, sccClosedSet): mdd_dup(sccClosedSet); 00279 tempMdd = mdd_and(sccClosedSet, absReachableStates, 1, 1); 00280 if (mdd_is_tautology(tempMdd, 0)) 00281 mdd_free(tempMdd); 00282 else 00283 array_insert_last(mdd_t *, strongSccClosedSets, tempMdd); 00284 mdd_free(sccClosedSet); 00285 } 00286 mdd_array_free(tempArray); 00287 00288 /* Refine SCC-closed sets, but up to a certain number */ 00289 tempArray = strongSccClosedSets; 00290 strongSccClosedSets = array_alloc(mdd_t *, 0); 00291 Mc_FsmForEachFairScc(absFsm, sccgen, sccClosedSet, tempArray, 00292 strongSccClosedSets, /* new scc-closed sets */ 00293 buechiFairness, absOnionRings, FALSE, 00294 ((verbosity<McVerbosityMax_c)? 00295 McVerbosityNone_c:McVerbositySome_c), 00296 (Mc_DcLevel) dcLevel) { 00297 if (SccIsStrong(mddManager, buechiFairness, sccClosedSet)) { 00298 array_insert_last(mdd_t *, strongSccClosedSets, sccClosedSet); 00299 if (maxSccsToEnum>0 && array_n(strongSccClosedSets)>maxSccsToEnum) { 00300 Mc_FsmSccGenFree(sccgen, strongSccClosedSets); 00301 break; 00302 } 00303 00304 }else { 00305 array_t *newCareStatesArray; 00306 newCareStatesArray = mdd_array_duplicate(modelCareStatesArray); 00307 if (!isExactReachableStatesAvailable) 00308 array_insert_last(mdd_t *, newCareStatesArray, absReachableStates); 00309 00310 if (verbosity >= McVerbositySome_c) 00311 fprintf(vis_stdout, "-- DnC: search in a weak SCC-closed set\n"); 00312 00313 fairStates = McFsmRefineWeakFairSCCs(modelFsm, sccClosedSet, 00314 newCareStatesArray, 00315 arrayOfOnionRings, FALSE, 00316 dcLevel, 00317 ((verbosity<McVerbosityMax_c)? 0:McVerbositySome_c) ); 00318 fairInitialStates = mdd_and(initialStates, fairStates, 1, 1); 00319 mdd_free(fairStates); 00320 if (!mdd_is_tautology(fairInitialStates, 0)) { 00321 /* Done, find a reachable fair cycle */ 00322 exitFlag = 2; 00323 if (verbosity >= McVerbosityLittle_c) 00324 fprintf(vis_stdout, "-- DnC: find a weak SCC!\n"); 00325 Mc_FsmSccGenFree(sccgen, NIL(array_t)); 00326 break; 00327 }else { 00328 mdd_free(fairInitialStates); 00329 } 00330 } 00331 00332 }/*Mc_FsmForEachFairScc( ) {*/ 00333 mdd_array_free(tempArray); 00334 00335 SortMddArrayBySize(absFsm, strongSccClosedSets); 00336 00337 if (verbosity >= McVerbosityLittle_c && exitFlag != 2) { 00338 fprintf(vis_stdout, 00339 "-- DnC: found %d SCC-closed sets in abs model %d with %d latches\n", 00340 array_n(strongSccClosedSets), iter+1, 00341 st_count(absLatchNameTable)); 00342 if (verbosity >= McVerbositySome_c) { 00343 array_t *absPSvars = Fsm_FsmReadPresentStateVars(absFsm); 00344 array_t *PSvars = Fsm_FsmReadPresentStateVars(modelFsm); 00345 arrayForEachItem(mdd_t *, strongSccClosedSets, i, tempMdd) { 00346 fprintf(vis_stdout, "-- An SCC-closed set with %5g abs (%5g concrete) states\n", 00347 mdd_count_onset(mddManager, tempMdd, absPSvars), 00348 mdd_count_onset(mddManager, tempMdd, PSvars) 00349 ); 00350 } 00351 } 00352 } 00353 00354 if(exitFlag == 0 && array_n(strongSccClosedSets) == 0) { 00355 /* Done, no reachable fair cycle exists */ 00356 exitFlag = 1; 00357 } 00358 00359 mdd_array_free(absOnionRings); 00360 Fsm_FsmFree(absFsm); 00361 00362 /* existFlag: 0 --> unknown; 1 --> no fair SCC; 2 --> find a fair SCC */ 00363 if ( exitFlag != 0 || st_count(absLatchNameTable) > maxLatchesToCompose ) { 00364 if (!isExactReachableStatesAvailable) { 00365 array_insert_last(mdd_t *, modelCareStatesArray, absReachableStates); 00366 tempMdd = reachableStates; 00367 reachableStates = mdd_and(reachableStates, absReachableStates,1,1); 00368 mdd_free(tempMdd); 00369 } 00370 break; 00371 } 00372 00373 mdd_free(absReachableStates); 00374 00375 }/*for (iter=0; iter<numOfAbstractModels; iter++) {*/ 00376 00377 for (i=0; i<array_n(absLatchNameTableArray); i++) { 00378 st_free_table( array_fetch(st_table *, absLatchNameTableArray, i) ); 00379 } 00380 array_free(absLatchNameTableArray); 00381 00382 00383 /* 00384 * Compute fair SCCs on the concrete model if necessary 00385 */ 00386 if (exitFlag == 0) { 00387 array_t *tempArray; 00388 mdd_t *sccClosedSet = NIL(mdd_t); 00389 mdd_t *tempMdd = NIL(mdd_t); 00390 00391 if (verbosity >= McVerbosityLittle_c) 00392 fprintf(vis_stdout, "-- DnC: check the concrete model\n"); 00393 00394 tempArray = strongSccClosedSets; 00395 strongSccClosedSets = array_alloc(mdd_t *, 0); 00396 arrayForEachItem(mdd_t *, tempArray, i, sccClosedSet) { 00397 tempMdd = mdd_and(sccClosedSet, reachableStates, 1, 1); 00398 if (mdd_is_tautology(tempMdd, 0)) 00399 mdd_free(tempMdd); 00400 else 00401 array_insert_last(mdd_t *, strongSccClosedSets, tempMdd); 00402 mdd_free(sccClosedSet); 00403 } 00404 array_free(tempArray); 00405 00406 if (lockstep != MC_LOCKSTEP_OFF) { 00407 tempArray = array_alloc(mdd_t *, 0); 00408 fairStates = McFsmRefineFairSCCsByLockStep(modelFsm, lockstep, 00409 tempArray, 00410 strongSccClosedSets, 00411 NIL(array_t), 00412 arrayOfOnionRings, 00413 (Mc_VerbosityLevel) verbosity, 00414 (Mc_DcLevel) dcLevel); 00415 mdd_array_free(tempArray); 00416 }else{ 00417 mdd_t *fairStates0, *sccClosedSet; 00418 array_t *EUonionRings; 00419 mdd_t *mddOne = mdd_one(mddManager); 00420 Mc_EarlyTermination_t *earlyTermination; 00421 00422 sccClosedSet = McMddArrayOr(strongSccClosedSets); 00423 fairStates0 = Mc_FsmEvaluateEGFormula(modelFsm, sccClosedSet, 00424 NIL(mdd_t), mddOne, 00425 modelFairness, 00426 modelCareStatesArray, 00427 MC_NO_EARLY_TERMINATION, 00428 NIL(array_t), 00429 Mc_None_c, 00430 &arrayOfOnionRings, 00431 (Mc_VerbosityLevel) verbosity, 00432 (Mc_DcLevel) dcLevel, 00433 NIL(boolean), 00434 GSHschedule); 00435 mdd_free(sccClosedSet); 00436 00437 EUonionRings = ( (arrayOfOnionRings == NIL(array_t))? 00438 NIL(array_t):array_alloc(mdd_t *,0) ); 00439 00440 earlyTermination = Mc_EarlyTerminationAlloc(McSome_c, initialStates); 00441 fairStates = Mc_FsmEvaluateEUFormula(modelFsm, mddOne, 00442 fairStates0, NIL(mdd_t), mddOne, 00443 modelCareStatesArray, 00444 earlyTermination, 00445 NIL(array_t), Mc_None_c, 00446 EUonionRings, 00447 (Mc_VerbosityLevel) verbosity, 00448 (Mc_DcLevel) dcLevel, 00449 NIL(boolean)); 00450 mdd_free(fairStates0); 00451 mdd_free(mddOne); 00452 Mc_EarlyTerminationFree(earlyTermination); 00453 00454 if (arrayOfOnionRings != NIL(array_t)) { 00455 int j; 00456 arrayForEachItem(array_t *, arrayOfOnionRings, i, tempArray) { 00457 #ifndef NDEBUG 00458 mdd_t *mdd1 = array_fetch_last(mdd_t *, tempArray); 00459 #endif 00460 arrayForEachItem(mdd_t *, EUonionRings, j, tempMdd) { 00461 if (j != 0) 00462 array_insert_last(mdd_t *, tempArray, mdd_dup(tempMdd)); 00463 else 00464 assert( mdd_equal(tempMdd, mdd1) ); 00465 } 00466 } 00467 mdd_array_free(EUonionRings); 00468 } 00469 } 00470 00471 fairInitialStates = mdd_and(initialStates, fairStates, 1, 1); 00472 mdd_free(fairStates); 00473 exitFlag = mdd_is_tautology(fairInitialStates, 0)? 1:2; 00474 } 00475 00476 /* Clean-Ups */ 00477 mdd_array_free(modelCareStatesArray); 00478 mdd_array_free(strongSccClosedSets); 00479 mdd_array_free(onionRings); 00480 mdd_free(reachableStates); 00481 mdd_free(initialStates); 00482 00483 /* 00484 * Print out the verification result (pass/fail, empty/non-empty) 00485 */ 00486 if (exitFlag == 1) { 00487 if (strcmp(driverName, "LE") == 0) 00488 fprintf(vis_stdout, "# LE: language emptiness check passes\n"); 00489 else 00490 fprintf(vis_stdout, "# %s: formula passed\n", driverName); 00491 if (arrayOfOnionRings != NIL(array_t)) 00492 mdd_array_array_free(arrayOfOnionRings); 00493 return fairInitialStates; 00494 00495 }else if (exitFlag == 2) { 00496 if (strcmp(driverName, "LE") == 0) 00497 fprintf(vis_stdout, "# LE: language is not empty\n"); 00498 else 00499 fprintf(vis_stdout, "# %s: formula failed\n", driverName); 00500 00501 }else { 00502 fprintf(vis_stderr, "* DnC error, result is unknown!\n"); 00503 assert(0); 00504 } 00505 00506 /* 00507 * Print out the debugging information if requested 00508 */ 00509 if (dbgLevel == McDbgLevelNone_c) { 00510 if (arrayOfOnionRings != NIL(array_t)) 00511 mdd_array_array_free(arrayOfOnionRings); 00512 return fairInitialStates; 00513 00514 }else { 00515 mdd_t *badStates, *aBadState, *mddOne; 00516 McPath_t *fairPath, *normalPath; 00517 array_t *stemArray, *cycleArray; 00518 FILE *tmpFile = vis_stdout; 00519 extern FILE *vis_stdpipe; 00520 fprintf(vis_stdout, "# %s: generating path to fair cycle\n", driverName); 00521 00522 /* Generate witness. */ 00523 badStates = mdd_dup(fairInitialStates); 00524 aBadState = Mc_ComputeAState(badStates, modelFsm); 00525 mdd_free(badStates); 00526 00527 mddOne = mdd_one(mddManager); 00528 fairPath = McBuildFairPath(aBadState, mddOne, arrayOfOnionRings, modelFsm, 00529 modelCareStates, 00530 (Mc_VerbosityLevel) verbosity, 00531 (Mc_DcLevel) dcLevel, 00532 McFwd_c); 00533 mdd_free(mddOne); 00534 mdd_free(aBadState); 00535 mdd_array_array_free(arrayOfOnionRings); 00536 00537 /* Print witness. */ 00538 normalPath = McPathNormalize(fairPath); 00539 McPathFree(fairPath); 00540 00541 stemArray = McPathReadStemArray(normalPath); 00542 cycleArray = McPathReadCycleArray(normalPath); 00543 00544 /* we should pass dbgFile/UseMore as parameters 00545 dbgFile = McOptionsReadDebugFile(options);*/ 00546 if (dbgFile != NIL(FILE)) { 00547 vis_stdpipe = dbgFile; 00548 } else if (UseMore == TRUE) { 00549 vis_stdpipe = popen("more","w"); 00550 } else { 00551 vis_stdpipe = vis_stdout; 00552 } 00553 vis_stdout = vis_stdpipe; 00554 00555 /* We should also pass SimValue as a parameter */ 00556 if (SimValue == FALSE) { 00557 (void) fprintf(vis_stdout, "# %s: path to fair cycle:\n\n", driverName); 00558 Mc_PrintPath(stemArray, modelFsm, printInputs); 00559 fprintf (vis_stdout, "\n"); 00560 00561 (void) fprintf(vis_stdout, "# %s: fair cycle:\n\n", driverName); 00562 Mc_PrintPath(cycleArray, modelFsm, printInputs); 00563 fprintf (vis_stdout, "\n"); 00564 }else { 00565 array_t *completePath = McCreateMergedPath(stemArray, cycleArray); 00566 (void) fprintf(vis_stdout, "# %s: counter-example\n", driverName); 00567 McPrintSimPath(vis_stdout, completePath, modelFsm); 00568 mdd_array_free(completePath); 00569 } 00570 00571 if (dbgFile == NIL(FILE) && UseMore == TRUE) { 00572 (void) pclose(vis_stdpipe); 00573 } 00574 vis_stdout = tmpFile; 00575 00576 McPathFree(normalPath); 00577 } 00578 00579 return fairInitialStates; 00580 } 00581 00600 array_t * 00601 Mc_CreateStaticRefinementScheduleArray( 00602 Ntk_Network_t *network, 00603 array_t *ctlArray, 00604 array_t *ltlArray, 00605 array_t *fairArray, 00606 boolean dynamicIncrease, 00607 boolean isLatchNameSort, 00608 int verbosity, 00609 int incrementalSize, 00610 Part_CMethod correlationMethod) 00611 { 00612 array_t *partitionArray; 00613 Part_Subsystem_t *partitionSubsystem; 00614 Part_SubsystemInfo_t *subsystemInfo; 00615 st_table *latchNameTable; 00616 st_table *latchNameTableSum, *latchNameTableSumCopy; 00617 char *flagValue; 00618 st_generator *stGen; 00619 char *name; 00620 double affinityFactor; 00621 array_t *scheduleArray; 00622 boolean dynamicAndDependency = isLatchNameSort; 00623 array_t *tempArray, *tempArray2; 00624 int i, count; 00625 00626 /* affinity factor to decompose state space */ 00627 flagValue = Cmd_FlagReadByName("part_group_affinity_factor"); 00628 if(flagValue != NIL(char)){ 00629 affinityFactor = atof(flagValue); 00630 } 00631 else{ 00632 /* default value */ 00633 affinityFactor = 0.5; 00634 } 00635 00636 /* 00637 * Obtain submachines as array: The first sub-system includes 00638 * variables in CTL/LTL/fair formulas and other latches are grouped 00639 * in the same way as Part_PartCreateSubsystems() 00640 */ 00641 subsystemInfo = Part_PartitionSubsystemInfoInit(network); 00642 Part_PartitionSubsystemInfoSetBound(subsystemInfo, incrementalSize); 00643 Part_PartitionSubsystemInfoSetVerbosity(subsystemInfo, verbosity); 00644 Part_PartitionSubsystemInfoSetCorrelationMethod(subsystemInfo, 00645 correlationMethod); 00646 Part_PartitionSubsystemInfoSetAffinityFactor(subsystemInfo, affinityFactor); 00647 partitionArray = Part_PartCreateSubsystemsWithCtlAndLtl(subsystemInfo, 00648 ctlArray, ltlArray, fairArray, 00649 dynamicIncrease,dynamicAndDependency,FALSE); 00650 Part_PartitionSubsystemInfoFree(subsystemInfo); 00651 00652 scheduleArray = array_alloc(st_table *, 0); 00653 00654 00655 /* 00656 * For each partitioned submachines build an FSM. 00657 */ 00658 latchNameTableSum = st_init_table(strcmp, st_strhash); 00659 if (!dynamicAndDependency){ 00660 for (i=0;i<array_n(partitionArray);i++){ 00661 partitionSubsystem = array_fetch(Part_Subsystem_t *, partitionArray, i); 00662 if (partitionSubsystem != NIL(Part_Subsystem_t)) { 00663 latchNameTable = Part_PartitionSubsystemReadVertexTable(partitionSubsystem); 00664 st_foreach_item(latchNameTable, stGen, &name, NIL(char *)) { 00665 if (!st_lookup(latchNameTableSum, name, NIL(char *))){ 00666 st_insert(latchNameTableSum, name, NIL(char)); 00667 } 00668 } 00669 Part_PartitionSubsystemFree(partitionSubsystem); 00670 } 00671 latchNameTableSumCopy = st_copy(latchNameTableSum); 00672 array_insert_last(st_table *, scheduleArray, latchNameTableSumCopy); 00673 } 00674 }else{ 00675 partitionSubsystem = array_fetch(Part_Subsystem_t *, partitionArray, 0); 00676 latchNameTable = Part_PartitionSubsystemReadVertexTable(partitionSubsystem); 00677 st_foreach_item(latchNameTable, stGen, &name, NIL(char *)) { 00678 st_insert(latchNameTableSum, name, NIL(char)); 00679 } 00680 latchNameTableSumCopy = st_copy(latchNameTableSum); 00681 array_insert_last(st_table *, scheduleArray, latchNameTableSumCopy); 00682 Part_PartitionSubsystemFree(partitionSubsystem); 00683 00684 partitionSubsystem = array_fetch(Part_Subsystem_t *, partitionArray, 1); 00685 tempArray = array_alloc(char *, 0); 00686 if (partitionSubsystem != NIL(Part_Subsystem_t)){ 00687 latchNameTable = Part_PartitionSubsystemReadVertexTable(partitionSubsystem); 00688 st_foreach_item(latchNameTable, stGen, &name, NIL(char *)) { 00689 array_insert_last(char *, tempArray, name); 00690 } 00691 array_sort(tempArray, stringCompare); 00692 Part_PartitionSubsystemFree(partitionSubsystem); 00693 } 00694 00695 partitionSubsystem = array_fetch(Part_Subsystem_t *, partitionArray, 2); 00696 tempArray2 = array_alloc(char *, 0); 00697 if (partitionSubsystem != NIL(Part_Subsystem_t)) { 00698 latchNameTable = Part_PartitionSubsystemReadVertexTable(partitionSubsystem); 00699 st_foreach_item(latchNameTable, stGen, &name, NIL(char *)) { 00700 array_insert_last(char *, tempArray2, name); 00701 } 00702 array_sort(tempArray2, stringCompare); 00703 Part_PartitionSubsystemFree(partitionSubsystem); 00704 } 00705 00706 array_append(tempArray, tempArray2); 00707 array_free(tempArray2); 00708 00709 count = 0; 00710 arrayForEachItem(char *, tempArray, i, name){ 00711 if (!st_lookup(latchNameTableSum, name, NIL(char *))){ 00712 st_insert(latchNameTableSum, (char *)name, (char *)0); 00713 count++; 00714 } 00715 if ((count == incrementalSize) && (i < array_n(tempArray)-1)){ 00716 latchNameTableSumCopy = st_copy(latchNameTableSum); 00717 array_insert_last(st_table *, scheduleArray, latchNameTableSumCopy); 00718 count = 0; 00719 } 00720 } 00721 array_free(tempArray); 00722 latchNameTableSumCopy = st_copy(latchNameTableSum); 00723 array_insert_last(st_table *, scheduleArray, latchNameTableSumCopy); 00724 } 00725 00726 array_free(partitionArray); 00727 st_free_table(latchNameTableSum); 00728 00729 return (scheduleArray); 00730 } 00731 00732 00733 /*---------------------------------------------------------------------------*/ 00734 /* Definition of internal functions */ 00735 /*---------------------------------------------------------------------------*/ 00736 00756 mdd_t * 00757 McFsmRefineWeakFairSCCs( 00758 Fsm_Fsm_t *modelFsm, 00759 mdd_t *sccClosedSet, 00760 array_t *modelCareStatesArray, 00761 array_t *arrayOfOnionRings, 00762 boolean isSccTerminal, 00763 int dcLevel, 00764 int verbosity) 00765 { 00766 mdd_manager *mddManager = Fsm_FsmReadMddManager(modelFsm); 00767 mdd_t *initialStates; 00768 mdd_t *mddOne, *mddEgFair, *mddEfEgFair, *fairInitStates, *mdd1; 00769 array_t *EFonionRings, *EGArrayOfOnionRings, *EGonionRings; 00770 array_t *newOnionRings; 00771 int i, j; 00772 Mc_EarlyTermination_t *earlyTermination; 00773 00774 initialStates = Fsm_FsmComputeInitialStates(modelFsm); 00775 mddOne = mdd_one(mddManager); 00776 00777 /* if debugging information is requested, arrayOfOnionRings!=NIL(array_t) */ 00778 if (arrayOfOnionRings != NIL(array_t)) { 00779 EGArrayOfOnionRings = array_alloc(array_t *, 0); 00780 EFonionRings = array_alloc(mdd_t *, 0); 00781 }else { 00782 EGArrayOfOnionRings = NIL(array_t); 00783 EFonionRings = NIL(array_t); 00784 } 00785 00786 if (isSccTerminal) 00787 mddEgFair = mdd_dup(sccClosedSet); 00788 else 00789 mddEgFair = Mc_FsmEvaluateEGFormula(modelFsm, sccClosedSet, 00790 NIL(mdd_t), mddOne, 00791 NIL(Fsm_Fairness_t), 00792 modelCareStatesArray, 00793 NIL(Mc_EarlyTermination_t), 00794 NIL(array_t), Mc_None_c, 00795 &EGArrayOfOnionRings, 00796 (Mc_VerbosityLevel) verbosity, 00797 (Mc_DcLevel) dcLevel, 00798 NIL(boolean), McGSH_EL_c); 00799 00800 earlyTermination = Mc_EarlyTerminationAlloc(McSome_c, initialStates); 00801 mddEfEgFair = Mc_FsmEvaluateEUFormula(modelFsm, mddOne, 00802 mddEgFair, NIL(mdd_t), mddOne, 00803 modelCareStatesArray, 00804 earlyTermination, 00805 NIL(array_t), Mc_None_c, 00806 EFonionRings, 00807 (Mc_VerbosityLevel) verbosity, 00808 (Mc_DcLevel) dcLevel, 00809 NIL(boolean)); 00810 mdd_free(mddEgFair); 00811 Mc_EarlyTerminationFree(earlyTermination); 00812 00813 fairInitStates = mdd_and(mddEfEgFair, initialStates, 1, 1); 00814 00815 /* create the arrayOfOnionRings */ 00816 if (arrayOfOnionRings!=NIL(array_t) && !mdd_is_tautology(fairInitStates,0)) { 00817 if (isSccTerminal) 00818 array_insert_last(array_t *, 00819 arrayOfOnionRings, mdd_array_duplicate(EFonionRings)); 00820 else { 00821 arrayForEachItem(array_t *, EGArrayOfOnionRings, i, EGonionRings) { 00822 newOnionRings = mdd_array_duplicate(EGonionRings); 00823 arrayForEachItem(mdd_t *, EFonionRings, j, mdd1) { 00824 if (j != 0) 00825 array_insert_last(mdd_t *, newOnionRings, mdd_dup(mdd1)); 00826 } 00827 array_insert_last(array_t *, arrayOfOnionRings, newOnionRings); 00828 } 00829 } 00830 } 00831 mdd_free(fairInitStates); 00832 00833 if (arrayOfOnionRings != NIL(array_t)) { 00834 mdd_array_free(EFonionRings); 00835 mdd_array_array_free(EGArrayOfOnionRings); 00836 } 00837 00838 mdd_free(initialStates); 00839 mdd_free(mddOne); 00840 00841 return mddEfEgFair; 00842 } 00843 00844 00857 mdd_t * 00858 McComputeAbstractStates( 00859 Fsm_Fsm_t *absFsm, 00860 mdd_t *states) 00861 { 00862 mdd_t *result; 00863 mdd_manager *mddManager = Fsm_FsmReadMddManager(absFsm); 00864 array_t *psVars = Fsm_FsmReadPresentStateVars(absFsm); 00865 array_t *supportVars; 00866 array_t *invisibleVars = array_alloc(long, 0); 00867 st_table *psVarTable = st_init_table(st_numcmp, st_numhash); 00868 int i; 00869 long mddId; 00870 00871 arrayForEachItem(long, psVars, i, mddId) { 00872 st_insert(psVarTable, (char *)mddId, NIL(char)); 00873 } 00874 00875 supportVars = mdd_get_support(mddManager, states); 00876 arrayForEachItem(long, supportVars, i, mddId) { 00877 if (!st_is_member(psVarTable, (char *)mddId)) 00878 array_insert_last(long, invisibleVars, mddId); 00879 } 00880 array_free(supportVars); 00881 st_free_table(psVarTable); 00882 00883 result = mdd_smooth(mddManager, states, invisibleVars); 00884 00885 array_free(invisibleVars); 00886 00887 return result; 00888 } 00889 00890 00902 boolean 00903 McGetDncEnabled(void) 00904 { 00905 char *flagValue; 00906 boolean result = FALSE; 00907 00908 flagValue = Cmd_FlagReadByName("divide_and_compose"); 00909 if (flagValue != NIL(char)) { 00910 if (strcmp(flagValue, "true") == 0) 00911 result = TRUE; 00912 else if (strcmp(flagValue, "false") == 0) 00913 result = FALSE; 00914 else { 00915 fprintf(vis_stderr, "** dnc error: invalid dnc_enable flag %s, dnc is disabled. \n", flagValue); 00916 } 00917 } 00918 00919 return result; 00920 } 00921 00922 00923 /*---------------------------------------------------------------------------*/ 00924 /* Definition of static functions */ 00925 /*---------------------------------------------------------------------------*/ 00926 00940 static boolean 00941 SccIsStrong(mdd_manager *mddMgr, array_t *buechiFairness, mdd_t *SCC) 00942 { 00943 boolean strength; 00944 mdd_t *LabeledAllFairness = mdd_dup(SCC); 00945 mdd_t *NotLabeledAllFairness; 00946 mdd_t *fairSet; 00947 int i; 00948 00949 /* 00950 * check whether SCC intersects all the fairness constraints 00951 * if yes, WEAK 00952 * if no, WEAK or STRONG 00953 */ 00954 arrayForEachItem(mdd_t *, buechiFairness, i, fairSet) { 00955 mdd_t *tmpMdd = LabeledAllFairness; 00956 LabeledAllFairness = mdd_and(LabeledAllFairness, fairSet, 1,1 ); 00957 mdd_free( tmpMdd ); 00958 } 00959 NotLabeledAllFairness = mdd_and(SCC, LabeledAllFairness, 1, 0); 00960 mdd_free(LabeledAllFairness); 00961 00962 if(mdd_is_tautology(NotLabeledAllFairness, 0)) { 00963 mdd_free(NotLabeledAllFairness); 00964 strength = FALSE; /* WEAK*/ 00965 } 00966 else { 00967 mdd_free(NotLabeledAllFairness); 00968 strength = TRUE; 00969 } 00970 00971 return strength; 00972 } 00973 00983 static st_table *array_mdd_compare_table = NIL(st_table); 00984 static int 00985 array_mdd_compare_size( 00986 const void *obj1, 00987 const void *obj2) 00988 { 00989 double *val1, *val2; 00990 int flag1, flag2; 00991 00992 flag1 = st_lookup(array_mdd_compare_table, *((char **)obj1), &val1); 00993 flag2 = st_lookup(array_mdd_compare_table, *((char **)obj2), &val2); 00994 assert(flag1 && flag2); 00995 00996 if (*val1 < *val2) 00997 return -1; 00998 else if (*val1> *val2) 00999 return +1; 01000 else 01001 return 0; 01002 } 01003 01016 static array_t * 01017 SortMddArrayBySize(Fsm_Fsm_t *fsm, array_t *mddArray) 01018 { 01019 mdd_manager *mddManager = Fsm_FsmReadMddManager(fsm); 01020 array_t *psVars = Fsm_FsmReadPresentStateVars(fsm); 01021 01022 if (array_n(psVars) < 1024) { 01023 st_table *mddToSizeTable =st_init_table(st_ptrcmp, st_ptrhash); 01024 double *sizes = ALLOC(double, array_n(mddArray)); 01025 mdd_t *mdd1; 01026 int i; 01027 01028 arrayForEachItem(mdd_t *, mddArray, i, mdd1) { 01029 *(sizes+i) = mdd_count_onset(mddManager, mdd1, psVars); 01030 st_insert(mddToSizeTable, (char *)mdd1, (char *)(sizes+i)); 01031 } 01032 01033 array_mdd_compare_table = mddToSizeTable; 01034 array_sort(mddArray, array_mdd_compare_size); 01035 01036 FREE(sizes); 01037 st_free_table(mddToSizeTable); 01038 } 01039 01040 return mddArray; 01041 } 01042 01043 01051 static int 01052 stringCompare( 01053 const void * s1, 01054 const void * s2) 01055 { 01056 return(strcmp(*(char **)s1, *(char **)s2)); 01057 } 01058 01059