VIS
|
00001 00079 #include "fsmInt.h" 00080 #include "ntm.h" 00081 00082 static char rcsid[] UNUSED = "$Id: fsmArdc.c,v 1.86 2009/04/12 00:44:04 fabio Exp $"; 00083 00084 /*---------------------------------------------------------------------------*/ 00085 /* Constant declarations */ 00086 /*---------------------------------------------------------------------------*/ 00087 00088 #define ARDC_MAX_LINE_LEN 4096 00089 00090 /*---------------------------------------------------------------------------*/ 00091 /* Structure declarations */ 00092 /*---------------------------------------------------------------------------*/ 00093 00094 00095 /*---------------------------------------------------------------------------*/ 00096 /* Type declarations */ 00097 /*---------------------------------------------------------------------------*/ 00098 00099 00102 /*---------------------------------------------------------------------------*/ 00103 /* Static function prototypes */ 00104 /*---------------------------------------------------------------------------*/ 00105 00106 static void SortSubFsmsForApproximateTraversal(array_t **subFsmArray, array_t **fanInsIndexArray, array_t **fanOutsIndexArray, int verbosityLevel); 00107 static array_t * ArdcMbmTraversal(Fsm_Fsm_t *fsm, int nvars, array_t *subFsmArray, array_t *fanInsIndexArray, array_t *fanOutsIndexArray, mdd_t ***subReached, int incrementalFlag, int verbosityLevel, int printStep, int depthValue, int shellFlag, int reorderFlag, int reorderThreshold, Fsm_RchType_t approxFlag, Fsm_ArdcOptions_t *options, boolean lfpFlag); 00108 static array_t * ArdcRfbfTraversal(Fsm_Fsm_t *fsm, int nvars, array_t *subFsmArray, array_t *fanInsIndexArray, int incrementalFlag, int verbosityLevel, int printStep, int depthValue, int shellFlag, int reorderFlag, int reorderThreshold, Fsm_RchType_t approxFlag, Fsm_ArdcOptions_t *options); 00109 static array_t * ArdcTfbfTraversal(Fsm_Fsm_t *fsm, int nvars, array_t *subFsmArray, array_t *fanInsIndexArray, mdd_t ***subReached, mdd_t ***subTo, int incrementalFlag, int verbosityLevel, int printStep, int depthValue, int shellFlag, int reorderFlag, int reorderThreshold, Fsm_RchType_t approxFlag, Fsm_ArdcOptions_t *options); 00110 static array_t * ArdcTmbmTraversal(Fsm_Fsm_t *fsm, int nvars, array_t *subFsmArray, array_t *fanInsIndexArray, array_t *fanOutsIndexArray, int incrementalFlag, int verbosityLevel, int printStep, int depthValue, int shellFlag, int reorderFlag, int reorderThreshold, Fsm_RchType_t approxFlag, Fsm_ArdcOptions_t *options, boolean lfpFlag); 00111 static array_t * ArdcSimpleTraversal(Fsm_Fsm_t *fsm, int nvars, array_t *subFsmArray, int incrementalFlag, int verbosityLevel, int printStep, int depthValue, int shellFlag, int reorderFlag, int reorderThreshold, Fsm_RchType_t approxFlag, Fsm_ArdcOptions_t *options, int setFlag); 00112 static void ComputeFaninConstrainArray(array_t *faninConstrainArray, mdd_t **constraint, int current, array_t *fans, int decomposeFlag, int faninConstrainMode); 00113 static void MinimizeTransitionRelationWithFaninConstraint(Img_ImageInfo_t *imageInfo, array_t *faninConstrainArray, Img_MinimizeType constrainMethod, boolean reorderPtrFlag, boolean duplicate); 00114 static void ComputeConstrainedInitialStates(Fsm_Fsm_t *subFsm, array_t *faninConstrainArray, Img_MinimizeType constrainMethod); 00115 static void ComputeApproximateReachableStatesArray(mdd_manager *mddManager, array_t *reachedArray, mdd_t **reached, mdd_t ***subReached, int nSubFsms, int decomposeFlag); 00116 static array_t * ArdcCopyOverApproxReachableStatesFromExact(Fsm_Fsm_t *fsm); 00117 static void PrintCurrentReachedStates(mdd_manager *mddManager, Fsm_Fsm_t **subFsm, mdd_t **reached, Fsm_Ardc_TraversalType_t method, int nSubFsms, int iteration, int nvars, int ardcVerbosity, boolean supportCheckFlag); 00118 static void PrintBddWithName(Fsm_Fsm_t *fsm, array_t *mddIdArr, mdd_t *node); 00119 static void ArdcReadGroup(Ntk_Network_t *network, FILE *groupFile, array_t *latchNameArray, array_t *groupIndexArray); 00120 static void ArdcWriteOneGroup(Part_Subsystem_t *partitionSubsystem, FILE *groupFile, int i); 00121 static void ArdcPrintOneGroup(Part_Subsystem_t *partitionSubsystem, int i, int nLatches, array_t *fanIns, array_t *fanOuts); 00122 static int GetArdcSetIntValue(char *string, int l, int u, int defaultValue); 00123 static void ArdcEpdCountOnsetOfOverApproximateReachableStates(Fsm_Fsm_t *fsm, EpDouble *epd); 00124 static mdd_t * QuantifyVariables(mdd_t *state, array_t *smoothArray, mdd_t *smoothCube); 00125 static void UpdateMbmEventSchedule(Fsm_Fsm_t **subFsm, array_t *fanOutIndices, int *traverse, int lfpFlag); 00126 static void PrintTfmStatistics(array_t *subFsmArray); 00127 00131 /*---------------------------------------------------------------------------*/ 00132 /* Definition of exported functions */ 00133 /*---------------------------------------------------------------------------*/ 00134 00153 void 00154 Fsm_ArdcMinimizeTransitionRelation(Fsm_Fsm_t *fsm, Img_DirectionType fwdbwd) 00155 { 00156 char *flagValue; 00157 int value = 0; 00158 int fwd = 0; 00159 int bwd = 0; 00160 Img_ImageInfo_t *imageInfo; 00161 int saveStatus; 00162 boolean reorderPtrFlag = FALSE; 00163 00164 switch (fwdbwd) { 00165 case Img_Forward_c: 00166 fwd = 1; 00167 break; 00168 case Img_Backward_c: 00169 bwd = 1; 00170 break; 00171 case Img_Both_c: 00172 fwd = 1; 00173 bwd= 1; 00174 break; 00175 } 00176 00177 imageInfo = Fsm_FsmReadOrCreateImageInfo(fsm, bwd, fwd); 00178 00179 saveStatus = 0; 00180 flagValue = Cmd_FlagReadByName("ardc_verbosity"); 00181 if (flagValue != NIL(char)) { 00182 sscanf(flagValue, "%d", &value); 00183 if (value > 1) { 00184 saveStatus = Img_ReadPrintMinimizeStatus(imageInfo); 00185 Img_SetPrintMinimizeStatus(imageInfo, 1); 00186 } 00187 } 00188 00189 reorderPtrFlag = FsmGetArdcSetBooleanValue("ardc_reorder_ptr", 00190 reorderPtrFlag); 00191 Img_MinimizeTransitionRelation( 00192 imageInfo, 00193 Fsm_FsmReadCurrentOverApproximateReachableStates(fsm), 00194 Img_DefaultMinimizeMethod_c, fwdbwd, reorderPtrFlag); 00195 00196 if (value > 1) 00197 Img_SetPrintMinimizeStatus(fsm->imageInfo, saveStatus); 00198 return; 00199 } 00200 00201 00214 mdd_t * 00215 Fsm_ArdcComputeImage(Fsm_Fsm_t *fsm, 00216 mdd_t *fromLowerBound, 00217 mdd_t *fromUpperBound, 00218 array_t *toCareSetArray) 00219 { 00220 Img_ImageInfo_t *imageInfo = NIL(Img_ImageInfo_t); 00221 mdd_t *image; 00222 00223 /* Create an imageInfo for image computations, if not already created. */ 00224 imageInfo = Fsm_FsmReadOrCreateImageInfo(fsm, 0, 1); 00225 00226 /* Compute the image */ 00227 image = Img_ImageInfoComputeImageWithDomainVars(imageInfo, 00228 fromLowerBound, fromUpperBound, toCareSetArray); 00229 00230 return(image); 00231 } 00232 00233 00246 array_t * 00247 Fsm_FsmComputeOverApproximateReachableStates(Fsm_Fsm_t *fsm, 00248 int incrementalFlag, int verbosityLevel, int printStep, int depthValue, 00249 int shellFlag, int reorderFlag, int reorderThreshold, int recompute) 00250 { 00251 array_t *apprReachableStates; 00252 Fsm_ArdcOptions_t options; 00253 00254 Fsm_ArdcGetDefaultOptions(&options); 00255 00256 if (printStep && options.verbosity < 2) 00257 printStep = 0; 00258 00259 apprReachableStates = Fsm_ArdcComputeOverApproximateReachableStates(fsm, 00260 incrementalFlag, verbosityLevel, printStep, depthValue, shellFlag, 00261 reorderFlag, reorderThreshold, recompute, &options); 00262 00263 return(apprReachableStates); 00264 } 00265 00266 00285 array_t * 00286 Fsm_ArdcComputeOverApproximateReachableStates(Fsm_Fsm_t *fsm, 00287 int incrementalFlag, 00288 int verbosityLevel, 00289 int printStep, 00290 int depthValue, int shellFlag, 00291 int reorderFlag, 00292 int reorderThreshold, 00293 int recompute, 00294 Fsm_ArdcOptions_t *options) 00295 { 00296 array_t *reachableStatesArray = NIL(array_t); 00297 mdd_t *reachableStates = NIL(mdd_t); 00298 mdd_t *initialStates; 00299 Ntk_Network_t *network = Fsm_FsmReadNetwork(fsm); 00300 Part_Subsystem_t *partitionSubsystem; 00301 array_t *partitionArray; 00302 int i; 00303 graph_t *partition = Part_NetworkReadPartition(network); 00304 st_table *vertexTable; 00305 Fsm_Fsm_t *subFsm; 00306 array_t *subFsmArray; 00307 array_t *fanIns, *fanOuts; 00308 array_t *fanInsIndexArray, *fanOutsIndexArray; 00309 array_t *fans; 00310 array_t *psVars; 00311 mdd_manager *mddManager = Fsm_FsmReadMddManager(fsm); 00312 char *flagValue; 00313 Fsm_RchType_t approxFlag; 00314 int nvars; /* the number of binary variables of the fsm */ 00315 FILE *groupFile = NIL(FILE); 00316 Img_MethodType imageMethod = Img_Default_c; 00317 Img_MethodType saveImageMethod = Img_Default_c; 00318 char *imageMethodString; 00319 Fsm_Ardc_AbstPpiType_t saveAbstractPseudoInput; 00320 00321 if (recompute) 00322 FsmResetReachabilityFields(fsm, Fsm_Rch_Oa_c); 00323 00324 /* If exact is already computed, copy exact to overapproximate. */ 00325 if (Fsm_FsmReadReachableStates(fsm) != NIL(mdd_t)) { 00326 if (Fsm_FsmReadCurrentOverApproximateReachableStates(fsm) != NIL(array_t)) { 00327 /* If the overapproximation is already the exact set, return it, 00328 * otherwise discard it. */ 00329 if (FsmReadReachabilityOverApproxComputationStatus(fsm) == 00330 Fsm_Ardc_Exact_c) { 00331 return(Fsm_FsmReadOverApproximateReachableStates(fsm)); 00332 } else { 00333 fprintf(vis_stdout, 00334 "** ardc warning : ignoring previous computation.\n"); 00335 Fsm_FsmFreeOverApproximateReachableStates(fsm); 00336 } 00337 } 00338 if (verbosityLevel > 0 || options->verbosity > 0) { 00339 fprintf(vis_stdout, 00340 "** ardc info : exact reached states are already computed.\n"); 00341 } 00342 /* Either we had no overapproximation, or it was not the exact set, and 00343 * hence it was discarded. Copy from exact to overapproximate. */ 00344 reachableStatesArray = ArdcCopyOverApproxReachableStatesFromExact(fsm); 00345 return(reachableStatesArray); 00346 } 00347 00348 /* If already computed, just return the array. */ 00349 if (Fsm_FsmReadCurrentOverApproximateReachableStates(fsm) != NIL(array_t)) { 00350 if (FsmReadReachabilityOverApproxComputationStatus(fsm) >= 00351 Fsm_Ardc_Converged_c) { 00352 return(Fsm_FsmReadOverApproximateReachableStates(fsm)); 00353 } else { 00354 /* Here, at this time, we just throw away current approximate 00355 * reachable states which is not converged yet, then restart. 00356 */ 00357 fprintf(vis_stdout, 00358 "** ardc warning : ignoring previous computation.\n"); 00359 Fsm_FsmFreeOverApproximateReachableStates(fsm); 00360 } 00361 } 00362 00363 /* Perform state space decomposition. */ 00364 partitionArray = Fsm_ArdcDecomposeStateSpace(network, 00365 fsm->fsmData.presentStateVars, 00366 fsm->fsmData.nextStateFunctions, 00367 options); 00368 00369 /* If there is only one group, call exact reachability analysis. */ 00370 if (array_n(partitionArray) == 1) { 00371 if (options->verbosity > 0) { 00372 fprintf(vis_stdout, 00373 "** ardc info : changing to exact reachability analysis.\n"); 00374 } 00375 arrayForEachItem(Part_Subsystem_t *, partitionArray, i, 00376 partitionSubsystem) { 00377 Part_PartitionSubsystemFree(partitionSubsystem); 00378 } 00379 array_free(partitionArray); 00380 00381 if (options->useHighDensity) 00382 approxFlag = Fsm_Rch_Hd_c; 00383 else 00384 approxFlag = Fsm_Rch_Bfs_c; 00385 reachableStates = Fsm_FsmComputeReachableStates(fsm, 00386 0, verbosityLevel, printStep, 0, 00387 0, reorderFlag, reorderThreshold, 00388 approxFlag, 0, 0, NIL(array_t), (verbosityLevel > 1), 00389 NIL(array_t)); 00390 mdd_free(reachableStates); 00391 reachableStatesArray = ArdcCopyOverApproxReachableStatesFromExact(fsm); 00392 return(reachableStatesArray); 00393 } 00394 00395 /* Read the image_method flag, and save its value in imageMethodString. */ 00396 flagValue = Cmd_FlagReadByName("image_method"); 00397 if (flagValue != NIL(char)) { 00398 if (strcmp(flagValue, "iwls95") == 0 || strcmp(flagValue, "default") == 0) 00399 imageMethod = Img_Iwls95_c; 00400 else if (strcmp(flagValue, "monolithic") == 0) 00401 imageMethod = Img_Monolithic_c; 00402 else if (strcmp(flagValue, "tfm") == 0) 00403 imageMethod = Img_Tfm_c; 00404 else if (strcmp(flagValue, "hybrid") == 0) 00405 imageMethod = Img_Hybrid_c; 00406 else if (strcmp(flagValue, "mlp") == 0) 00407 imageMethod = Img_Mlp_c; 00408 else { 00409 fprintf(vis_stderr, "** ardc error: invalid image method %s.\n", 00410 flagValue); 00411 } 00412 } 00413 imageMethodString = flagValue; 00414 /* Update the image_method flag to the method specified for approximate 00415 * reachability. */ 00416 if (options->ardcImageMethod != Img_Default_c && 00417 options->ardcImageMethod != imageMethod) { 00418 saveImageMethod = imageMethod; 00419 if (options->ardcImageMethod == Img_Monolithic_c) { 00420 Cmd_FlagUpdateValue("image_method", "monolithic"); 00421 imageMethod = Img_Monolithic_c; 00422 } else if (options->ardcImageMethod == Img_Iwls95_c) { 00423 Cmd_FlagUpdateValue("image_method", "iwls95"); 00424 imageMethod = Img_Iwls95_c; 00425 } else if (options->ardcImageMethod == Img_Tfm_c) { 00426 Cmd_FlagUpdateValue("image_method", "tfm"); 00427 imageMethod = Img_Tfm_c; 00428 } else if (options->ardcImageMethod == Img_Hybrid_c) { 00429 Cmd_FlagUpdateValue("image_method", "hybrid"); 00430 imageMethod = Img_Hybrid_c; 00431 } else if (options->ardcImageMethod == Img_Mlp_c) { 00432 Cmd_FlagUpdateValue("image_method", "mlp"); 00433 imageMethod = Img_Mlp_c; 00434 } 00435 } 00436 00437 /* Open the file where to save the result of partitioning is so requested. */ 00438 if (options->writeGroupFile) { 00439 groupFile = Cmd_FileOpen(options->writeGroupFile, "w", NIL(char *), 0); 00440 if (groupFile == NIL(FILE)) { 00441 fprintf(vis_stderr, "** ardc error : can't open file [%s] to write.\n", 00442 options->writeGroupFile); 00443 } 00444 } 00445 00446 /* Compute the set of initial states, if not already computed. */ 00447 initialStates = Fsm_FsmComputeInitialStates(fsm); 00448 00449 subFsmArray = array_alloc(Fsm_Fsm_t *, 0); 00450 fanInsIndexArray = array_alloc(array_t *, 0); 00451 fanOutsIndexArray = array_alloc(array_t *, 0); 00452 00453 /* For each partitioned submachines build an FSM. */ 00454 arrayForEachItem(Part_Subsystem_t *, partitionArray, i, partitionSubsystem) { 00455 vertexTable = Part_PartitionSubsystemReadVertexTable(partitionSubsystem); 00456 fanIns = Part_PartitionSubsystemReadFanIn(partitionSubsystem); 00457 fanOuts = Part_PartitionSubsystemReadFanOut(partitionSubsystem); 00458 subFsm = Fsm_FsmCreateSubsystemFromNetwork(network, partition, 00459 vertexTable, TRUE, 00460 options->createPseudoVarMode); 00461 /* Depending on the options, the initial states of each submachine 00462 * are either the states of the entire system or their projection 00463 * on the subspace of the submachine. */ 00464 if (!options->projectedInitialFlag && 00465 options->abstractPseudoInput != Fsm_Ardc_Abst_Ppi_Before_Image_c) { 00466 subFsm->reachabilityInfo.initialStates = mdd_dup(initialStates); 00467 } else { 00468 mdd_t *dummy; 00469 00470 dummy = Fsm_FsmComputeInitialStates(subFsm); 00471 mdd_free(dummy); 00472 } 00473 array_insert_last(Fsm_Fsm_t *, subFsmArray, subFsm); 00474 array_insert_last(array_t *, fanInsIndexArray, fanIns); 00475 array_insert_last(array_t *, fanOutsIndexArray, fanOuts); 00476 00477 if (options->verbosity > 1) { 00478 int nLatches; 00479 nLatches = mdd_get_number_of_bdd_vars(mddManager, 00480 subFsm->fsmData.presentStateVars); 00481 ArdcPrintOneGroup(partitionSubsystem, i, nLatches, fanIns, fanOuts); 00482 } 00483 if (groupFile) 00484 ArdcWriteOneGroup(partitionSubsystem, groupFile, i); 00485 00486 st_free_table(vertexTable); 00487 } /* end of arrayForEachItem(partitionArray) */ 00488 mdd_free(initialStates); 00489 00490 if (groupFile) 00491 fclose(groupFile); 00492 00493 /* Sort submachines to find the order in which to traverse them. */ 00494 SortSubFsmsForApproximateTraversal(&subFsmArray, &fanInsIndexArray, 00495 &fanOutsIndexArray, options->verbosity); 00496 00497 /* Optimize pseudo-input variables to contain only the variables of fanin 00498 * submachines. If createPseudoVarMode is 0, the set of pseudo-input 00499 * variables is just the collection of the variables of all other 00500 * submachines. 00501 * If createPseudoVarMode is 1, the set is the collection of the variables 00502 * of only its fanin submachines. If createPseudoVarMode is 2, the set is 00503 * the collection of the support variables that appear in other submachines. 00504 */ 00505 if (options->createPseudoVarMode == 0) { 00506 arrayForEachItem(Fsm_Fsm_t *, subFsmArray, i, subFsm) { 00507 Fsm_Fsm_t *faninSubfsm; 00508 int j, fanin; 00509 00510 subFsm->fsmData.primaryInputVars = array_dup(subFsm->fsmData.inputVars); 00511 subFsm->fsmData.pseudoInputVars = array_alloc(int, 0); 00512 fanIns = array_fetch(array_t *, fanInsIndexArray, i); 00513 arrayForEachItem(int, fanIns, j, fanin) { 00514 if (fanin == i) 00515 continue; 00516 faninSubfsm = array_fetch(Fsm_Fsm_t *, subFsmArray, fanin); 00517 array_append(subFsm->fsmData.pseudoInputVars, 00518 faninSubfsm->fsmData.presentStateVars); 00519 } 00520 subFsm->fsmData.globalPsVars = array_dup( 00521 subFsm->fsmData.presentStateVars); 00522 array_append(subFsm->fsmData.globalPsVars, 00523 subFsm->fsmData.pseudoInputVars); 00524 array_append(subFsm->fsmData.inputVars, subFsm->fsmData.pseudoInputVars); 00525 00526 subFsm->fsmData.pseudoInputBddVars = mdd_id_array_to_bdd_array(mddManager, 00527 subFsm->fsmData.pseudoInputVars); 00528 00529 if (subFsm->fsmData.createVarCubesFlag) { 00530 subFsm->fsmData.pseudoInputCube = mdd_id_array_to_bdd_cube(mddManager, 00531 subFsm->fsmData.pseudoInputVars); 00532 subFsm->fsmData.primaryInputCube = subFsm->fsmData.inputCube; 00533 subFsm->fsmData.inputCube = mdd_id_array_to_bdd_cube(mddManager, 00534 subFsm->fsmData.inputVars); 00535 subFsm->fsmData.globalPsCube = mdd_id_array_to_bdd_cube(mddManager, 00536 subFsm->fsmData.globalPsVars); 00537 } 00538 } 00539 } 00540 00541 if (options->useHighDensity) 00542 approxFlag = Fsm_Rch_Hd_c; 00543 else 00544 approxFlag = Fsm_Rch_Bfs_c; 00545 00546 /* In case of transition function method, since quantification doesn't 00547 * make any sense, we turn it off. We turn quantification off also for the 00548 * hybrid method, because it starts with tfm. 00549 */ 00550 saveAbstractPseudoInput = options->abstractPseudoInput; 00551 if (imageMethod == Img_Tfm_c || imageMethod == Img_Hybrid_c) 00552 options->abstractPseudoInput = Fsm_Ardc_Abst_Ppi_No_c; 00553 00554 nvars = mdd_get_number_of_bdd_vars(mddManager, fsm->fsmData.presentStateVars); 00555 if (options->traversalMethod == Fsm_Ardc_Traversal_Mbm_c) { 00556 reachableStatesArray = ArdcMbmTraversal(fsm, nvars, subFsmArray, 00557 fanInsIndexArray, fanOutsIndexArray, NULL, 00558 incrementalFlag, verbosityLevel, printStep, 00559 depthValue, shellFlag, reorderFlag, 00560 reorderThreshold, approxFlag, options, FALSE); 00561 } else if (options->traversalMethod == Fsm_Ardc_Traversal_Rfbf_c) { 00562 if (approxFlag == Fsm_Rch_Hd_c) { 00563 fprintf(vis_stderr, 00564 "** ardc error : High Density Traversal is not allowed in FBF.\n"); 00565 } 00566 reachableStatesArray = ArdcRfbfTraversal(fsm, nvars, subFsmArray, 00567 fanInsIndexArray, 00568 incrementalFlag, verbosityLevel, printStep, 00569 depthValue, shellFlag, reorderFlag, reorderThreshold, 00570 approxFlag, options); 00571 } else if (options->traversalMethod == Fsm_Ardc_Traversal_Tfbf_c) { 00572 if (approxFlag == Fsm_Rch_Hd_c) { 00573 fprintf(vis_stderr, 00574 "** ardc error : High Density Traversal is not allowed in FBF.\n"); 00575 } 00576 reachableStatesArray = ArdcTfbfTraversal(fsm, nvars, subFsmArray, 00577 fanInsIndexArray, NULL, NULL, 00578 incrementalFlag, verbosityLevel, printStep, 00579 depthValue, shellFlag, reorderFlag, reorderThreshold, 00580 approxFlag, options); 00581 } else if (options->traversalMethod == Fsm_Ardc_Traversal_Tmbm_c) { 00582 reachableStatesArray = ArdcTmbmTraversal(fsm, nvars, subFsmArray, 00583 fanInsIndexArray, fanOutsIndexArray, 00584 incrementalFlag, verbosityLevel, printStep, 00585 depthValue, shellFlag, reorderFlag, reorderThreshold, 00586 approxFlag, options, FALSE); 00587 } else if (options->traversalMethod == Fsm_Ardc_Traversal_Lmbm_c) { 00588 reachableStatesArray = ArdcMbmTraversal(fsm, nvars, subFsmArray, 00589 fanInsIndexArray, fanOutsIndexArray, NULL, 00590 incrementalFlag, verbosityLevel, printStep, 00591 depthValue, shellFlag, reorderFlag, 00592 reorderThreshold, approxFlag, options, TRUE); 00593 } else if (options->traversalMethod == Fsm_Ardc_Traversal_Tlmbm_c) { 00594 reachableStatesArray = ArdcTmbmTraversal(fsm, nvars, subFsmArray, 00595 fanInsIndexArray, fanOutsIndexArray, 00596 incrementalFlag, verbosityLevel, printStep, 00597 depthValue, shellFlag, reorderFlag, reorderThreshold, 00598 approxFlag, options, TRUE); 00599 } else { 00600 reachableStatesArray = ArdcSimpleTraversal(fsm, nvars, subFsmArray, 00601 incrementalFlag, verbosityLevel, printStep, 00602 depthValue, shellFlag, reorderFlag, reorderThreshold, 00603 approxFlag, options, TRUE); 00604 } 00605 options->abstractPseudoInput = saveAbstractPseudoInput; 00606 00607 if (options->verbosity && 00608 (options->ardcImageMethod == Img_Tfm_c || 00609 options->ardcImageMethod == Img_Hybrid_c)) { 00610 PrintTfmStatistics(subFsmArray); 00611 } 00612 00613 fsm->reachabilityInfo.subPsVars = array_alloc(array_t *, 0); 00614 if (options->decomposeFlag) { 00615 for (i = 0; i < array_n(subFsmArray); i++) { 00616 subFsm = array_fetch(Fsm_Fsm_t *, subFsmArray, i); 00617 psVars = array_dup(subFsm->fsmData.presentStateVars); 00618 array_insert_last(array_t *, fsm->reachabilityInfo.subPsVars, psVars); 00619 } 00620 } else { 00621 psVars = array_dup(fsm->fsmData.presentStateVars); 00622 array_insert_last(array_t *, fsm->reachabilityInfo.subPsVars, psVars); 00623 } 00624 00625 arrayForEachItem(array_t *, fanInsIndexArray, i, fans) { 00626 array_free(fans); 00627 } 00628 array_free(fanInsIndexArray); 00629 arrayForEachItem(array_t *, fanOutsIndexArray, i, fans) { 00630 array_free(fans); 00631 } 00632 array_free(fanOutsIndexArray); 00633 arrayForEachItem(Part_Subsystem_t *, partitionArray, i, partitionSubsystem) { 00634 FREE(partitionSubsystem); 00635 } 00636 array_free(partitionArray); 00637 00638 arrayForEachItem(Fsm_Fsm_t *, subFsmArray, i, subFsm) { 00639 Fsm_FsmSubsystemFree(subFsm); 00640 } 00641 array_free(subFsmArray); 00642 00643 /* Restore value of image_method flag. */ 00644 if (options->ardcImageMethod != Img_Default_c && 00645 options->ardcImageMethod != saveImageMethod) { 00646 if (imageMethodString) { 00647 if (saveImageMethod == Img_Monolithic_c) 00648 Cmd_FlagUpdateValue("image_method", "monolithic"); 00649 else if (saveImageMethod == Img_Iwls95_c) 00650 Cmd_FlagUpdateValue("image_method", "iwls95"); 00651 else if (saveImageMethod == Img_Tfm_c) 00652 Cmd_FlagUpdateValue("image_method", "tfm"); 00653 else if (saveImageMethod == Img_Hybrid_c) 00654 Cmd_FlagUpdateValue("image_method", "hybrid"); 00655 else if (saveImageMethod == Img_Mlp_c) 00656 Cmd_FlagUpdateValue("image_method", "mlp"); 00657 } else 00658 Cmd_FlagDeleteByName("image_method"); 00659 } 00660 00661 fsm->reachabilityInfo.apprReachableStates = reachableStatesArray; 00662 return(reachableStatesArray); 00663 } 00664 00665 00677 array_t * 00678 Fsm_ArdcDecomposeStateSpace(Ntk_Network_t *network, array_t *presentStateVars, 00679 array_t *nextStateFunctions, Fsm_ArdcOptions_t *options) 00680 { 00681 array_t *latchNameArray; 00682 array_t *groupIndexArray; 00683 char *name; 00684 Ntk_Node_t *latch; 00685 int i, mddId; 00686 Part_SubsystemInfo_t *subsystemInfo; 00687 array_t *partitionArray; 00688 FILE *groupFile = NIL(FILE); 00689 long initialTime = 0, finalTime; 00690 int verbosity = 0; 00691 float affinityFactor = 0.5; 00692 int groupSize = 8; 00693 00694 if (options) { 00695 verbosity = options->verbosity; 00696 affinityFactor = options->affinityFactor; 00697 groupSize = options->groupSize; 00698 } else { 00699 char *flagValue; 00700 00701 flagValue = Cmd_FlagReadByName("ardc_group_size"); 00702 if (flagValue != NIL(char)) { 00703 sscanf(flagValue, "%d", &groupSize); 00704 if (groupSize <= 0) { 00705 fprintf(vis_stderr, 00706 "** ardc error: invalid value %s for ardc_group_size[>0]. **\n", 00707 flagValue); 00708 groupSize = 8; 00709 } 00710 } 00711 flagValue = Cmd_FlagReadByName("ardc_verbosity"); 00712 if (flagValue != NIL(char)) 00713 sscanf(flagValue, "%d", &verbosity); 00714 flagValue = Cmd_FlagReadByName("ardc_affinity_factor"); 00715 if (flagValue != NIL(char)) { 00716 sscanf(flagValue, "%f", &affinityFactor); 00717 if (affinityFactor < 0.0 || affinityFactor > 1.0) { 00718 fprintf(vis_stderr, 00719 "** ardc error :invalid value %s for ardc_affinity_factor[0.0-1.0]. **\n", 00720 flagValue); 00721 affinityFactor = 0.5; 00722 } 00723 } 00724 } 00725 00726 if (verbosity > 0) 00727 initialTime = util_cpu_time(); 00728 00729 if (options && options->readGroupFile) { 00730 groupFile = Cmd_FileOpen(options->readGroupFile, "r", NIL(char *), 1); 00731 if (groupFile == NIL(FILE)) { 00732 fprintf(vis_stderr, "** ardc error : can't open file [%s] to read.\n", 00733 options->readGroupFile); 00734 } 00735 } 00736 00737 if (groupFile) { 00738 latchNameArray = array_alloc(char *, 0); 00739 groupIndexArray = array_alloc(int, 0); 00740 ArdcReadGroup(network, groupFile, latchNameArray, groupIndexArray); 00741 subsystemInfo = Part_PartitionSubsystemInfoInit(network); 00742 partitionArray = Part_PartCreateSubsystems(subsystemInfo, 00743 latchNameArray, groupIndexArray); 00744 Part_PartitionSubsystemInfoFree(subsystemInfo); 00745 arrayForEachItem(char *, latchNameArray, i, name) { 00746 FREE(name); 00747 } 00748 array_free(latchNameArray); 00749 array_free(groupIndexArray); 00750 fclose(groupFile); 00751 groupFile = NIL(FILE); 00752 } else if (groupSize > 0) { 00753 subsystemInfo = Part_PartitionSubsystemInfoInit(network); 00754 /* 00755 Part_PartitionSubsystemInfoSetVerbosity(subsystemInfo, verbosity); 00756 */ 00757 Part_PartitionSubsystemInfoSetBound(subsystemInfo, groupSize); 00758 Part_PartitionSubsystemInfoSetAffinityFactor(subsystemInfo, affinityFactor); 00759 latchNameArray = array_alloc(char *, 0); 00760 arrayForEachItem(int, presentStateVars, i, mddId) { 00761 latch = Ntk_NetworkFindNodeByMddId(network, mddId); 00762 name = Ntk_NodeReadName(latch); 00763 array_insert_last(char *, latchNameArray, name); 00764 } 00765 partitionArray = Part_PartCreateSubsystems(subsystemInfo, 00766 latchNameArray, NIL(array_t)); 00767 array_free(latchNameArray); 00768 Part_PartitionSubsystemInfoFree(subsystemInfo); 00769 } else { 00770 partitionArray = Part_PartGroupVeriticesBasedOnHierarchy(network, 00771 nextStateFunctions); 00772 } 00773 if (verbosity > 0) { 00774 finalTime = util_cpu_time(); 00775 fprintf(vis_stdout, "grouping(state space decomposition) time = %g\n", 00776 (double)(finalTime - initialTime) / 1000.0); 00777 } 00778 00779 return(partitionArray); 00780 } 00781 00782 00794 Fsm_ArdcOptions_t * 00795 Fsm_ArdcAllocOptionsStruct(void) 00796 { 00797 Fsm_ArdcOptions_t *options; 00798 00799 options = ALLOC(Fsm_ArdcOptions_t, 1); 00800 (void)memset((void *)options, 0, sizeof(Fsm_ArdcOptions_t)); 00801 00802 return(options); 00803 } 00804 00805 00892 void 00893 Fsm_ArdcGetDefaultOptions(Fsm_ArdcOptions_t *options) 00894 { 00895 int groupSize = 8; 00896 float affinityFactor = 0.5; 00897 Fsm_Ardc_TraversalType_t traversalMethod = Fsm_Ardc_Traversal_Lmbm_c; 00898 int maxIteration = 0; 00899 Fsm_Ardc_ConstrainTargetType_t constrainTarget = Fsm_Ardc_Constrain_Tr_c; 00900 Img_MinimizeType constrainMethod = Img_Restrict_c; 00901 boolean decomposeFlag = TRUE; 00902 Fsm_Ardc_AbstPpiType_t abstractPseudoInput = Fsm_Ardc_Abst_Ppi_Before_Image_c; 00903 boolean projectedInitialFlag = TRUE; 00904 boolean constrainReorderFlag = TRUE; 00905 Img_MethodType ardcImageMethod = Img_Default_c; 00906 boolean useHighDensity = FALSE; 00907 int createPseudoVarMode = 0; 00908 int verbosity = 0; 00909 char *flagValue; 00910 int value; 00911 float affinity; 00912 boolean reorderPtrFlag = FALSE; 00913 int faninConstrainMode = 0; 00914 int lmbmInitialStatesMode = 1; 00915 int mbmReuseTrFlag = 0; 00916 00917 flagValue = Cmd_FlagReadByName("ardc_traversal_method"); 00918 if (flagValue != NIL(char)) { 00919 sscanf(flagValue, "%d", &value); 00920 switch (value) { 00921 case 0 : 00922 traversalMethod = Fsm_Ardc_Traversal_Mbm_c; 00923 break; 00924 case 1 : 00925 traversalMethod = Fsm_Ardc_Traversal_Rfbf_c; 00926 break; 00927 case 2 : 00928 traversalMethod = Fsm_Ardc_Traversal_Tfbf_c; 00929 break; 00930 case 3 : 00931 traversalMethod = Fsm_Ardc_Traversal_Tmbm_c; 00932 break; 00933 case 4 : 00934 traversalMethod = Fsm_Ardc_Traversal_Lmbm_c; 00935 break; 00936 case 5 : 00937 traversalMethod = Fsm_Ardc_Traversal_Tlmbm_c; 00938 break; 00939 case 6 : /* hidden option */ 00940 traversalMethod = Fsm_Ardc_Traversal_Simple_c; 00941 break; 00942 default : 00943 fprintf(vis_stderr, "** ardc error : invalid value %s", flagValue); 00944 fprintf(vis_stderr, " for ardc_traversal_method[0-5]. **\n"); 00945 break; 00946 } 00947 } 00948 options->traversalMethod = traversalMethod; 00949 00950 flagValue = Cmd_FlagReadByName("ardc_group_size"); 00951 if (flagValue != NIL(char)) { 00952 sscanf(flagValue, "%d", &value); 00953 if (value > 0) 00954 groupSize = value; 00955 else { 00956 fprintf(vis_stderr, 00957 "** ardc error : invalid value %s for ardc_group_size[>0]. **\n", 00958 flagValue); 00959 } 00960 } 00961 options->groupSize = groupSize; 00962 00963 flagValue = Cmd_FlagReadByName("ardc_affinity_factor"); 00964 if (flagValue != NIL(char)) { 00965 sscanf(flagValue, "%f", &affinity); 00966 if (affinity >= 0.0 && affinity <= 1.0) 00967 affinityFactor = affinity; 00968 else { 00969 fprintf(vis_stderr, 00970 "** ardc error : invalid value %s for ardc_affinity_factor[0.0-1.0]. **\n", 00971 flagValue); 00972 } 00973 } 00974 options->affinityFactor = affinityFactor; 00975 00976 flagValue = Cmd_FlagReadByName("ardc_constrain_method"); 00977 if (flagValue != NIL(char)) { 00978 sscanf(flagValue, "%d", &value); 00979 switch (value) { 00980 case 0 : 00981 constrainMethod = Img_Restrict_c; 00982 break; 00983 case 1 : 00984 constrainMethod = Img_Constrain_c; 00985 break; 00986 case 2 : 00987 if (bdd_get_package_name() != CUDD) { 00988 fprintf(vis_stderr, "** ardc error : Compact in ardc_constrain_method"); 00989 fprintf(vis_stderr, " is currently supported by only CUDD. **\n"); 00990 break; 00991 } 00992 constrainMethod = Img_Compact_c; 00993 break; 00994 case 3 : 00995 if (bdd_get_package_name() != CUDD) { 00996 fprintf(vis_stderr, "** ardc error : Squeeze in ardc_constrain_method"); 00997 fprintf(vis_stderr, " is currently supported by only CUDD. **\n"); 00998 break; 00999 } 01000 constrainMethod = Img_Squeeze_c; 01001 break; 01002 case 4 : 01003 constrainMethod = Img_And_c; 01004 break; 01005 default : 01006 fprintf(vis_stderr, 01007 "** ardc error : invalid value %s for ardc_constrain_method[0-4]. **\n", 01008 flagValue); 01009 break; 01010 } 01011 } 01012 options->constrainMethod = constrainMethod; 01013 01014 flagValue = Cmd_FlagReadByName("ardc_constran_to"); 01015 if (flagValue != NIL(char)) { 01016 sscanf(flagValue, "%d", &value); 01017 switch (value) { 01018 case 0 : 01019 constrainTarget = Fsm_Ardc_Constrain_Tr_c; 01020 break; 01021 case 1 : 01022 constrainTarget = Fsm_Ardc_Constrain_Initial_c; 01023 break; 01024 case 2 : 01025 constrainTarget = Fsm_Ardc_Constrain_Both_c; 01026 break; 01027 default : 01028 fprintf(vis_stderr, 01029 "** ardc error : invalid value %s for ardc_constrain_target[0-2]. **\n", 01030 flagValue); 01031 break; 01032 } 01033 } 01034 options->constrainTarget = constrainTarget; 01035 01036 flagValue = Cmd_FlagReadByName("ardc_max_iteration"); 01037 if (flagValue != NIL(char)) { 01038 sscanf(flagValue, "%d", &value); 01039 if (value >= 0) 01040 maxIteration = value; 01041 else { 01042 fprintf(vis_stderr, 01043 "** ardc error : invalid value %s for ardc_max_iteration[>=0]. **\n", 01044 flagValue); 01045 } 01046 } 01047 options->maxIteration = maxIteration; 01048 01049 flagValue = Cmd_FlagReadByName("ardc_abstract_pseudo_input"); 01050 if (flagValue != NIL(char)) { 01051 sscanf(flagValue, "%d", &value); 01052 switch (value) { 01053 case 0 : 01054 abstractPseudoInput = Fsm_Ardc_Abst_Ppi_No_c; 01055 break; 01056 case 1 : 01057 abstractPseudoInput = Fsm_Ardc_Abst_Ppi_Before_Image_c; 01058 break; 01059 case 2 : 01060 abstractPseudoInput = Fsm_Ardc_Abst_Ppi_After_Image_c; 01061 break; 01062 case 3 : 01063 abstractPseudoInput = Fsm_Ardc_Abst_Ppi_At_End_c; 01064 break; 01065 default : 01066 fprintf(vis_stderr, "** ardc error : invalid value %s", flagValue); 01067 fprintf(vis_stderr, " for ardc_abstract_pseudo_input[0-3]. **\n"); 01068 break; 01069 } 01070 } 01071 options->abstractPseudoInput = abstractPseudoInput; 01072 01073 decomposeFlag = FsmGetArdcSetBooleanValue("ardc_decompose_flag", 01074 decomposeFlag); 01075 options->decomposeFlag = decomposeFlag; 01076 01077 projectedInitialFlag = 01078 FsmGetArdcSetBooleanValue("ardc_projected_initial_flag", 01079 projectedInitialFlag); 01080 options->projectedInitialFlag = projectedInitialFlag; 01081 01082 constrainReorderFlag = FsmGetArdcSetBooleanValue("ardc_constrain_reorder", 01083 constrainReorderFlag); 01084 options->constrainReorderFlag = constrainReorderFlag; 01085 01086 flagValue = Cmd_FlagReadByName("ardc_image_method"); 01087 if (flagValue != NIL(char)) { 01088 if (strcmp(flagValue, "monolithic") == 0) 01089 ardcImageMethod = Img_Monolithic_c; 01090 else if (strcmp(flagValue, "iwls95") == 0) 01091 ardcImageMethod = Img_Iwls95_c; 01092 else if (strcmp(flagValue, "mlp") == 0) 01093 ardcImageMethod = Img_Mlp_c; 01094 else if (strcmp(flagValue, "tfm") == 0) 01095 ardcImageMethod = Img_Tfm_c; 01096 else if (strcmp(flagValue, "hybrid") == 0) 01097 ardcImageMethod = Img_Hybrid_c; 01098 else 01099 fprintf(vis_stderr, "** ardc error : invalid value %s\n", flagValue); 01100 } 01101 options->ardcImageMethod = ardcImageMethod; 01102 01103 useHighDensity = FsmGetArdcSetBooleanValue("ardc_use_high_density", 01104 useHighDensity); 01105 options->useHighDensity = useHighDensity; 01106 01107 createPseudoVarMode = GetArdcSetIntValue("ardc_create_pseudo_var_mode", 0, 2, 01108 createPseudoVarMode); 01109 options->createPseudoVarMode = createPseudoVarMode; 01110 01111 reorderPtrFlag = FsmGetArdcSetBooleanValue("ardc_reorder_ptr", 01112 reorderPtrFlag); 01113 options->reorderPtrFlag = reorderPtrFlag; 01114 01115 faninConstrainMode = GetArdcSetIntValue("ardc_fanin_constrain_mode", 0, 1, 01116 faninConstrainMode); 01117 options->faninConstrainMode = faninConstrainMode; 01118 01119 flagValue = Cmd_FlagReadByName("ardc_read_group"); 01120 if (flagValue) 01121 options->readGroupFile = flagValue; 01122 else 01123 options->readGroupFile = NIL(char); 01124 01125 flagValue = Cmd_FlagReadByName("ardc_write_group"); 01126 if (flagValue) 01127 options->writeGroupFile = flagValue; 01128 else 01129 options->writeGroupFile = NIL(char); 01130 01131 lmbmInitialStatesMode = GetArdcSetIntValue("ardc_lmbm_initial_mode", 0, 2, 01132 lmbmInitialStatesMode); 01133 options->lmbmInitialStatesMode = lmbmInitialStatesMode; 01134 01135 mbmReuseTrFlag = FsmGetArdcSetBooleanValue("ardc_mbm_reuse_tr", 01136 mbmReuseTrFlag); 01137 options->mbmReuseTrFlag = mbmReuseTrFlag; 01138 01139 verbosity = GetArdcSetIntValue("ardc_verbosity", 0, 3, verbosity); 01140 options->verbosity = verbosity; 01141 } 01142 01143 01155 Fsm_Ardc_TraversalType_t 01156 Fsm_ArdcOptionsReadTraversalMethod(Fsm_ArdcOptions_t *options) 01157 { 01158 return(options->traversalMethod); 01159 } 01160 01161 01173 int 01174 Fsm_ArdcOptionsReadGroupSize(Fsm_ArdcOptions_t *options) 01175 { 01176 return(options->groupSize); 01177 } 01178 01179 01191 float 01192 Fsm_ArdcOptionsReadAffinityFactor(Fsm_ArdcOptions_t *options) 01193 { 01194 return(options->affinityFactor); 01195 } 01196 01197 01209 Img_MinimizeType 01210 Fsm_ArdcOptionsReadConstrainMethod(Fsm_ArdcOptions_t *options) 01211 { 01212 return(options->constrainMethod); 01213 } 01214 01215 01227 Fsm_Ardc_ConstrainTargetType_t 01228 Fsm_ArdcOptionsReadConstrainTarget(Fsm_ArdcOptions_t *options) 01229 { 01230 return(options->constrainTarget); 01231 } 01232 01233 01245 int 01246 Fsm_ArdcOptionsReadMaxIteration(Fsm_ArdcOptions_t *options) 01247 { 01248 return(options->maxIteration); 01249 } 01250 01251 01263 Fsm_Ardc_AbstPpiType_t 01264 Fsm_ArdcOptionsReadAbstractPseudoInput(Fsm_ArdcOptions_t *options) 01265 { 01266 return(options->abstractPseudoInput); 01267 } 01268 01269 01281 boolean 01282 Fsm_ArdcOptionsReadDecomposeFlag(Fsm_ArdcOptions_t *options) 01283 { 01284 return(options->decomposeFlag); 01285 } 01286 01287 01299 boolean 01300 Fsm_ArdcOptionsReadProjectedInitialFlag(Fsm_ArdcOptions_t *options) 01301 { 01302 return(options->projectedInitialFlag); 01303 } 01304 01305 01317 boolean 01318 Fsm_ArdcOptionsReadConstrainReorderFlag(Fsm_ArdcOptions_t *options) 01319 { 01320 return(options->constrainReorderFlag); 01321 } 01322 01323 01335 Img_MethodType 01336 Fsm_ArdcOptionsReadImageMethod(Fsm_ArdcOptions_t *options) 01337 { 01338 return(options->ardcImageMethod); 01339 } 01340 01341 01353 boolean 01354 Fsm_ArdcOptionsReadUseHighDensity(Fsm_ArdcOptions_t *options) 01355 { 01356 return(options->useHighDensity); 01357 } 01358 01359 01371 int 01372 Fsm_ArdcOptionsReadVerbosity(Fsm_ArdcOptions_t *options) 01373 { 01374 return(options->verbosity); 01375 } 01376 01377 01389 void 01390 Fsm_ArdcOptionsSetTraversalMethod(Fsm_ArdcOptions_t *options, 01391 Fsm_Ardc_TraversalType_t traversalMethod) 01392 { 01393 options->traversalMethod = traversalMethod; 01394 } 01395 01396 01408 void 01409 Fsm_ArdcOptionsSetGroupSize(Fsm_ArdcOptions_t *options, int groupSize) 01410 { 01411 options->groupSize = groupSize; 01412 } 01413 01414 01426 void 01427 Fsm_ArdcOptionsSetAffinityFactor(Fsm_ArdcOptions_t *options, 01428 float affinityFactor) 01429 { 01430 options->affinityFactor = affinityFactor; 01431 } 01432 01433 01445 void 01446 Fsm_ArdcOptionsSetConstrainMethod(Fsm_ArdcOptions_t *options, 01447 Img_MinimizeType constrainMethod) 01448 { 01449 options->constrainMethod = constrainMethod; 01450 } 01451 01452 01464 void 01465 Fsm_ArdcOptionsSetConstrainTarget(Fsm_ArdcOptions_t *options, 01466 Fsm_Ardc_ConstrainTargetType_t constrainTarget) 01467 { 01468 options->constrainTarget = constrainTarget; 01469 } 01470 01471 01483 void 01484 Fsm_ArdcOptionsSetMaxIteration(Fsm_ArdcOptions_t *options, int maxIteration) 01485 { 01486 options->maxIteration = maxIteration; 01487 } 01488 01489 01501 void 01502 Fsm_ArdcOptionsSetAbstractPseudoInput(Fsm_ArdcOptions_t *options, 01503 Fsm_Ardc_AbstPpiType_t abstractPseudoInput) 01504 { 01505 options->abstractPseudoInput = abstractPseudoInput; 01506 } 01507 01508 01520 void 01521 Fsm_ArdcOptionsSetDecomposeFlag(Fsm_ArdcOptions_t *options, 01522 boolean decomposeFlag) 01523 { 01524 options->decomposeFlag = decomposeFlag; 01525 } 01526 01527 01539 void 01540 Fsm_ArdcOptionsSetProjectedInitialFlag(Fsm_ArdcOptions_t *options, 01541 boolean projectedInitialFlag) 01542 { 01543 options->projectedInitialFlag = projectedInitialFlag; 01544 } 01545 01546 01558 void 01559 Fsm_ArdcOptionsSetConstrainReorderFlag(Fsm_ArdcOptions_t *options, 01560 int constrainReorderFlag) 01561 { 01562 options->constrainReorderFlag = constrainReorderFlag; 01563 } 01564 01565 01577 void 01578 Fsm_ArdcOptionsSetImageMethod(Fsm_ArdcOptions_t *options, 01579 Img_MethodType ardcImageMethod) 01580 { 01581 options->ardcImageMethod = ardcImageMethod; 01582 } 01583 01584 01596 void 01597 Fsm_ArdcOptionsSetUseHighDensity(Fsm_ArdcOptions_t *options, 01598 boolean useHighDensity) 01599 { 01600 options->useHighDensity = useHighDensity; 01601 } 01602 01603 01615 void 01616 Fsm_ArdcOptionsSetVerbosity(Fsm_ArdcOptions_t *options, int verbosity) 01617 { 01618 options->verbosity = verbosity; 01619 } 01620 01621 01633 double 01634 Fsm_ArdcCountOnsetOfOverApproximateReachableStates(Fsm_Fsm_t *fsm) 01635 { 01636 mdd_t *reached; 01637 array_t *psVars, *reachedArray; 01638 mdd_manager *mddManager = Fsm_FsmReadMddManager(fsm); 01639 double numReached = 1.0, tmpReached; 01640 int i; 01641 01642 if (!Fsm_FsmReadCurrentOverApproximateReachableStates(fsm)) 01643 return(0.0); 01644 01645 reachedArray = Fsm_FsmReadCurrentOverApproximateReachableStates(fsm); 01646 arrayForEachItem(mdd_t *, reachedArray, i, reached) { 01647 psVars = array_fetch(array_t *, fsm->reachabilityInfo.subPsVars, i); 01648 tmpReached = mdd_count_onset(mddManager, reached, psVars); 01649 numReached *= tmpReached; 01650 } 01651 01652 return(numReached); 01653 } 01654 01668 int 01669 Fsm_ArdcBddSizeOfOverApproximateReachableStates(Fsm_Fsm_t *fsm) 01670 { 01671 mdd_t *reached; 01672 array_t *reachedArray; 01673 int i, size = 0; 01674 01675 if (!Fsm_FsmReadCurrentOverApproximateReachableStates(fsm)) 01676 return(0); 01677 01678 reachedArray = Fsm_FsmReadCurrentOverApproximateReachableStates(fsm); 01679 arrayForEachItem(mdd_t *, reachedArray, i, reached) { 01680 size += mdd_size(reached); 01681 } 01682 01683 return(size); 01684 } 01685 01699 mdd_t * 01700 Fsm_ArdcGetMddOfOverApproximateReachableStates(Fsm_Fsm_t *fsm) 01701 { 01702 mdd_t *reached, *reachedSet, *tmp; 01703 mdd_manager *mddManager = Fsm_FsmReadMddManager(fsm); 01704 array_t *reachedArray; 01705 int i; 01706 01707 if (!Fsm_FsmReadCurrentOverApproximateReachableStates(fsm)) 01708 return(NIL(mdd_t)); 01709 01710 reachedSet = mdd_one(mddManager); 01711 reachedArray = Fsm_FsmReadCurrentOverApproximateReachableStates(fsm); 01712 arrayForEachItem(mdd_t *, reachedArray, i, reached) { 01713 tmp = reachedSet; 01714 reachedSet = mdd_and(reachedSet, reached, 1, 1); 01715 mdd_free(tmp); 01716 } 01717 01718 return(reachedSet); 01719 } 01720 01732 void 01733 Fsm_ArdcPrintReachabilityResults(Fsm_Fsm_t *fsm, long elapseTime) 01734 { 01735 array_t *psVars = Fsm_FsmReadPresentStateVars(fsm); 01736 mdd_manager *mddMgr = Fsm_FsmReadMddManager(fsm); 01737 int nvars = mdd_get_number_of_bdd_vars(mddMgr, psVars); 01738 char apprStr[24], ardcStr[24]; 01739 01740 if (nvars <= EPD_MAX_BIN) { 01741 double mintermAppr, mintermArdc; 01742 01743 mintermAppr = Fsm_ArdcCountOnsetOfOverApproximateReachableStates(fsm); 01744 sprintf(apprStr, "%10g", mintermAppr); 01745 mintermArdc = pow((double)2.0, (double)nvars) - mintermAppr; 01746 sprintf(ardcStr, "%10g", mintermArdc); 01747 } else { 01748 EpDouble apprEpd, ardcEpd; 01749 01750 ArdcEpdCountOnsetOfOverApproximateReachableStates(fsm, &apprEpd); 01751 EpdPow2(nvars, &ardcEpd); 01752 EpdSubtract2(&ardcEpd, &apprEpd); 01753 EpdGetString(&apprEpd, apprStr); 01754 EpdGetString(&ardcEpd, ardcStr); 01755 } 01756 01757 (void)fprintf(vis_stdout,"***********************************************\n"); 01758 (void)fprintf(vis_stdout,"Over-approximate Reachability analysis results:\n"); 01759 (void)fprintf(vis_stdout, "%-30s%s\n", "reachable states = ", apprStr); 01760 (void)fprintf(vis_stdout, "%-30s%s\n", "unreachable states(ARDCs) = ", 01761 ardcStr); 01762 (void)fprintf(vis_stdout, "%-30s%10d\n", "BDD size = ", 01763 Fsm_ArdcBddSizeOfOverApproximateReachableStates(fsm)); 01764 (void)fprintf(vis_stdout, "%-30s%10g\n", "analysis time = ", 01765 (double)elapseTime / 1000.0); 01766 switch (FsmReadReachabilityOverApproxComputationStatus(fsm)) { 01767 case Fsm_Ardc_NotConverged_c : 01768 (void) fprintf(vis_stdout, "%-30s%10s\n", "reachability status = ", 01769 "not converged(invalid)"); 01770 break; 01771 case Fsm_Ardc_Valid_c : 01772 (void) fprintf(vis_stdout, "%-30s%10s\n", "reachability status = ", 01773 "not converged(valid)"); 01774 break; 01775 case Fsm_Ardc_Converged_c : 01776 (void) fprintf(vis_stdout, "%-30s%10s\n", "reachability status = ", 01777 "converged"); 01778 break; 01779 case Fsm_Ardc_Exact_c : 01780 (void) fprintf(vis_stdout, "%-30s%10s\n", "reachability status = ", 01781 "exact"); 01782 break; 01783 default : 01784 break; 01785 } 01786 } 01787 01799 int 01800 Fsm_ArdcReadVerbosity(void) 01801 { 01802 char *flagValue; 01803 int verbosity = 0; 01804 01805 flagValue = Cmd_FlagReadByName("ardc_verbosity"); 01806 if (flagValue != NIL(char)) 01807 sscanf(flagValue, "%d", &verbosity); 01808 return(verbosity); 01809 } 01810 01811 01812 /*---------------------------------------------------------------------------*/ 01813 /* Definition of internal functions */ 01814 /*---------------------------------------------------------------------------*/ 01815 01827 int 01828 FsmArdcCheckInvariant(Fsm_Fsm_t *fsm, array_t *invarStates) 01829 { 01830 array_t *overApproxArray; 01831 mdd_t *conjunct; 01832 int i, j; 01833 mdd_t *invariant; 01834 01835 overApproxArray = Fsm_ArdcComputeOverApproximateReachableStates(fsm, 01836 0, 0, 0, 0, 0, 0, 0, 0, NIL(Fsm_ArdcOptions_t)); 01837 01838 /* for each invariant check if the over approx holds */ 01839 arrayForEachItem(mdd_t *, invarStates, i, invariant) { 01840 arrayForEachItem(mdd_t *, overApproxArray, j, conjunct) { 01841 if (conjunct == NIL(mdd_t)) 01842 continue; 01843 if (!mdd_lequal(conjunct, invariant, 1, 1)) 01844 return 0; 01845 } 01846 } 01847 return 1; 01848 } 01849 01850 01862 void 01863 FsmArdcPrintOptions(void) 01864 { 01865 Fsm_ArdcOptions_t options; 01866 char dummy[31]; 01867 01868 Fsm_ArdcGetDefaultOptions(&options); 01869 01870 switch (options.traversalMethod) { 01871 case Fsm_Ardc_Traversal_Mbm_c : 01872 sprintf(dummy, "MBM"); 01873 break; 01874 case Fsm_Ardc_Traversal_Rfbf_c : 01875 sprintf(dummy, "RFBF"); 01876 break; 01877 case Fsm_Ardc_Traversal_Tfbf_c : 01878 sprintf(dummy, "TFBF"); 01879 break; 01880 case Fsm_Ardc_Traversal_Tmbm_c : 01881 sprintf(dummy, "TMBM"); 01882 break; 01883 case Fsm_Ardc_Traversal_Lmbm_c : 01884 sprintf(dummy, "LMBM"); 01885 break; 01886 case Fsm_Ardc_Traversal_Tlmbm_c : 01887 sprintf(dummy, "TLMBM"); 01888 break; 01889 case Fsm_Ardc_Traversal_Simple_c : 01890 sprintf(dummy, "SIMPLE"); 01891 break; 01892 default : 01893 sprintf(dummy, "invalid"); 01894 break; 01895 } 01896 fprintf(vis_stdout, "ARDC: ardc_traversal_method = %d (%s)\n", 01897 options.traversalMethod, dummy); 01898 fprintf(vis_stdout, "ARDC: ardc_group_size = %d\n", options.groupSize); 01899 fprintf(vis_stdout, "ARDC: ardc_affinity_factor = %f\n", 01900 options.affinityFactor); 01901 fprintf(vis_stdout, "ARDC: ardc_max_iteration = %d\n", options.maxIteration); 01902 switch (options.constrainTarget) { 01903 case Fsm_Ardc_Constrain_Tr_c : 01904 sprintf(dummy, "transition relation"); 01905 break; 01906 case Fsm_Ardc_Constrain_Initial_c : 01907 sprintf(dummy, "initial"); 01908 break; 01909 case Fsm_Ardc_Constrain_Both_c : 01910 sprintf(dummy, "both"); 01911 break; 01912 default : 01913 sprintf(dummy, "invalid"); 01914 break; 01915 } 01916 fprintf(vis_stdout, "ARDC: ardc_constrain_target = %d (%s)\n", 01917 options.constrainTarget, dummy); 01918 switch (options.constrainMethod) { 01919 case Img_Restrict_c : 01920 sprintf(dummy, "restrict"); 01921 break; 01922 case Img_Constrain_c : 01923 sprintf(dummy, "constrain"); 01924 break; 01925 case Img_Compact_c : 01926 sprintf(dummy, "compact"); 01927 break; 01928 case Img_Squeeze_c : 01929 sprintf(dummy, "squeeze"); 01930 break; 01931 case Img_And_c : 01932 sprintf(dummy, "and"); 01933 break; 01934 case Img_DefaultMinimizeMethod_c : 01935 sprintf(dummy, "restrict"); 01936 break; 01937 default : 01938 sprintf(dummy, "invalid"); 01939 break; 01940 } 01941 fprintf(vis_stdout, "ARDC: ardc_constrain_method = %d (%s)\n", 01942 options.constrainMethod, dummy); 01943 if (options.constrainReorderFlag) 01944 sprintf(dummy, "yes"); 01945 else 01946 sprintf(dummy, "no"); 01947 fprintf(vis_stdout, "ARDC: ardc_constrain_reorder = %s\n", dummy); 01948 if (options.decomposeFlag) 01949 sprintf(dummy, "yes"); 01950 else 01951 sprintf(dummy, "no"); 01952 fprintf(vis_stdout, "ARDC: ardc_decompose_flag = %s\n", dummy); 01953 switch (options.abstractPseudoInput) { 01954 case Fsm_Ardc_Abst_Ppi_No_c : 01955 sprintf(dummy, "no"); 01956 break; 01957 case Fsm_Ardc_Abst_Ppi_Before_Image_c : 01958 sprintf(dummy, "before image"); 01959 break; 01960 case Fsm_Ardc_Abst_Ppi_After_Image_c : 01961 sprintf(dummy, "after image"); 01962 break; 01963 case Fsm_Ardc_Abst_Ppi_At_End_c : 01964 sprintf(dummy, "at end"); 01965 break; 01966 default : 01967 sprintf(dummy, "invalid"); 01968 break; 01969 } 01970 fprintf(vis_stdout, "ARDC: ardc_abstract_pseudo_input = %d (%s)\n", 01971 options.abstractPseudoInput, dummy); 01972 if (options.projectedInitialFlag) 01973 sprintf(dummy, "yes"); 01974 else 01975 sprintf(dummy, "no"); 01976 fprintf(vis_stdout, "ARDC: ardc_projected_initial_flag = %s\n", dummy); 01977 if (options.ardcImageMethod == Img_Monolithic_c) 01978 sprintf(dummy, "monolithic"); 01979 else if (options.ardcImageMethod == Img_Tfm_c) 01980 sprintf(dummy, "tfm"); 01981 else if (options.ardcImageMethod == Img_Hybrid_c) 01982 sprintf(dummy, "hybrid"); 01983 else if (options.ardcImageMethod == Img_Mlp_c) 01984 sprintf(dummy, "mlp"); 01985 else 01986 sprintf(dummy, "iwls95"); 01987 fprintf(vis_stdout, "ARDC: ardc_image_method = %s\n", dummy); 01988 if (options.useHighDensity) 01989 sprintf(dummy, "yes"); 01990 else 01991 sprintf(dummy, "no"); 01992 fprintf(vis_stdout, "ARDC: ardc_use_high_density = %s\n", dummy); 01993 if (options.reorderPtrFlag) 01994 sprintf(dummy, "yes"); 01995 else 01996 sprintf(dummy, "no"); 01997 fprintf(vis_stdout, "ARDC: ardc_reorder_ptr = %s\n", dummy); 01998 if (options.faninConstrainMode == 0) 01999 sprintf(dummy, "only fanin"); 02000 else 02001 sprintf(dummy, "fanin + itself"); 02002 fprintf(vis_stdout, "ARDC: ardc_fanin_constrain_mode = %d (%s)\n", 02003 options.faninConstrainMode, dummy); 02004 if (options.createPseudoVarMode == 0) 02005 sprintf(dummy, "with exact support"); 02006 else if (options.createPseudoVarMode == 1) 02007 sprintf(dummy, "all the other submachines"); 02008 else 02009 sprintf(dummy, "only fanin submachines"); 02010 fprintf(vis_stdout, "ARDC: ardc_create_pseudo_var_mode = %d (%s)\n", 02011 options.createPseudoVarMode, dummy); 02012 if (options.lmbmInitialStatesMode == 0) 02013 sprintf(dummy, "given initial"); 02014 else if (options.lmbmInitialStatesMode == 1) 02015 sprintf(dummy, "reached set"); 02016 else 02017 sprintf(dummy, "frontier set"); 02018 fprintf(vis_stdout, "ARDC: ardc_lmbm_initial_mode = %d (%s)\n", 02019 options.lmbmInitialStatesMode, dummy); 02020 if (options.mbmReuseTrFlag) 02021 sprintf(dummy, "yes"); 02022 else 02023 sprintf(dummy, "no"); 02024 fprintf(vis_stdout, "ARDC: ardc_mbm_reuse_tr = %s\n", dummy); 02025 if (options.readGroupFile) 02026 fprintf(vis_stdout, "ARDC: ardc_read_group = %s\n", options.readGroupFile); 02027 else 02028 fprintf(vis_stdout, "ARDC: ardc_read_group = nil\n"); 02029 if (options.writeGroupFile) { 02030 fprintf(vis_stdout, "ARDC: ardc_write_group = %s\n", 02031 options.writeGroupFile); 02032 } else 02033 fprintf(vis_stdout, "ARDC: ardc_write_group = nil\n"); 02034 fprintf(vis_stdout, "ARDC: ardc_verbosity = %d\n", options.verbosity); 02035 fprintf(vis_stdout, 02036 "See help page on print_ardc_options for setting these options\n"); 02037 } 02038 02039 02040 02052 void 02053 FsmArdcPrintOverApproximateReachableStates(Fsm_Fsm_t *fsm) 02054 { 02055 mdd_t *appr; 02056 array_t *mddIdArr; 02057 02058 if (!Fsm_FsmTestIsOverApproximateReachabilityDone(fsm)) { 02059 fprintf(vis_stdout, "** ardc warning : no approximate reachable states **\n"); 02060 return; 02061 } 02062 appr = Fsm_ArdcGetMddOfOverApproximateReachableStates(fsm); 02063 mddIdArr = Fsm_FsmReadPresentStateVars(fsm); 02064 PrintBddWithName(fsm, mddIdArr, appr); 02065 } 02066 02078 void 02079 FsmArdcPrintExactReachableStates(Fsm_Fsm_t *fsm) 02080 { 02081 mdd_t *reachableStates; 02082 array_t *mddIdArr; 02083 02084 if (!Fsm_FsmTestIsReachabilityDone(fsm)) { 02085 fprintf(vis_stdout, "** ardc warning : no reachable states **\n"); 02086 return; 02087 } 02088 reachableStates = Fsm_FsmReadReachableStates(fsm); 02089 mddIdArr = Fsm_FsmReadPresentStateVars(fsm); 02090 PrintBddWithName(fsm, mddIdArr, reachableStates); 02091 } 02092 02093 02105 void 02106 FsmArdcPrintBddOfNode(Fsm_Fsm_t *fsm, mdd_t *node) 02107 { 02108 PrintBddWithName(fsm, NIL(array_t), node); 02109 } 02110 02111 02123 void 02124 FsmArdcPrintArrayOfArrayInt(array_t *arrayOfArray) 02125 { 02126 int i, j, n; 02127 array_t *array; 02128 02129 for (i = 0; i < array_n(arrayOfArray); i++) { 02130 array = array_fetch(array_t *, arrayOfArray, i); 02131 fprintf(vis_stdout, "array[%d] =", i); 02132 for (j = 0; j < array_n(array); j++) { 02133 n = array_fetch(int, array, j); 02134 fprintf(vis_stdout, " %d", n); 02135 } 02136 fprintf(vis_stdout, "\n"); 02137 } 02138 } 02139 02151 boolean 02152 FsmGetArdcSetBooleanValue(char *string, boolean defaultValue) 02153 { 02154 char *flagValue; 02155 boolean value = defaultValue; 02156 02157 flagValue = Cmd_FlagReadByName(string); 02158 if (flagValue != NIL(char)) { 02159 if (strcmp(flagValue, "yes") == 0) 02160 value = TRUE; 02161 else if (strcmp(flagValue, "no") == 0) 02162 value = FALSE; 02163 else { 02164 fprintf(vis_stderr, 02165 "** ardc error : invalid value %s for %s[yes/no]. **\n", 02166 flagValue, string); 02167 } 02168 } 02169 02170 return(value); 02171 } 02172 02173 02174 02175 /*---------------------------------------------------------------------------*/ 02176 /* Definition of static functions */ 02177 /*---------------------------------------------------------------------------*/ 02178 02179 02191 static void 02192 SortSubFsmsForApproximateTraversal(array_t **subFsmArray, 02193 array_t **fanInsIndexArray, 02194 array_t **fanOutsIndexArray, 02195 int verbosityLevel) 02196 { 02197 int n = array_n(*subFsmArray); 02198 array_t *newSubFsmArray; 02199 array_t *newFanInsIndexArray; 02200 array_t *newFanOutsIndexArray; 02201 int i, j, smallest; 02202 Fsm_Fsm_t *subFsm; 02203 array_t *fanIns, *fanOuts; 02204 Fsm_Fsm_t *smallestSubFsm = NIL(Fsm_Fsm_t); 02205 array_t *smallestFanIns = NIL(array_t); 02206 array_t *smallestFanOuts = NIL(array_t); 02207 int *flag; 02208 int *nFanIns, *nFanOuts; 02209 int fanIn, fanOut; 02210 int *order = NIL(int); 02211 int *target; 02212 02213 newSubFsmArray = array_alloc(Fsm_Fsm_t *, 0); 02214 newFanInsIndexArray = array_alloc(array_t *, 0); 02215 newFanOutsIndexArray = array_alloc(array_t *, 0); 02216 02217 flag = ALLOC(int, n); 02218 (void)memset((void *)flag, 0, sizeof(int) * n); 02219 02220 if (verbosityLevel > 1) 02221 order = ALLOC(int, n); 02222 target = ALLOC(int, n); 02223 nFanIns = ALLOC(int, n); 02224 nFanOuts = ALLOC(int, n); 02225 for (i = 0; i < n; i++) { 02226 fanIns = array_fetch(array_t *, *fanInsIndexArray, i); 02227 nFanIns[i] = array_n(fanIns); 02228 fanOuts = array_fetch(array_t *, *fanOutsIndexArray, i); 02229 nFanOuts[i] = array_n(fanOuts); 02230 } 02231 02232 for (i = 0; i < n; i++) { 02233 /* 02234 ** finds a submachine which has the smallest number of fanins 02235 ** if tie, use number of fanouts 02236 */ 02237 smallest = -1; 02238 for (j = 0; j < n; j++) { 02239 if (flag[j]) 02240 continue; 02241 subFsm = array_fetch(Fsm_Fsm_t *, *subFsmArray, j); 02242 fanIns = array_fetch(array_t *, *fanInsIndexArray, j); 02243 fanOuts = array_fetch(array_t *, *fanOutsIndexArray, j); 02244 if (smallest == -1 || nFanIns[j] < nFanIns[smallest] || 02245 (nFanIns[j] == nFanIns[smallest] && 02246 nFanOuts[j] < nFanOuts[smallest])) { 02247 smallest = j; 02248 smallestSubFsm = subFsm; 02249 smallestFanIns = fanIns; 02250 smallestFanOuts = fanOuts; 02251 } 02252 } 02253 target[smallest] = i; 02254 if (verbosityLevel > 1) 02255 order[i] = smallest; 02256 flag[smallest] = 1; 02257 array_insert_last(Fsm_Fsm_t *, newSubFsmArray, smallestSubFsm); 02258 array_insert_last(array_t *, newFanInsIndexArray, smallestFanIns); 02259 array_insert_last(array_t *, newFanOutsIndexArray, smallestFanOuts); 02260 /* 02261 ** decrease number of fanouts by 1 from each submachine 02262 ** which is not chosen yet 02263 */ 02264 for (j = 0; j < array_n(smallestFanIns); j++) { 02265 fanIn = array_fetch(int, smallestFanIns, j); 02266 if (flag[fanIn]) 02267 continue; 02268 nFanOuts[fanIn]--; 02269 } 02270 /* 02271 ** decrease number of fanins by 1 from each submachine 02272 ** which is not chosen yet 02273 */ 02274 for (j = 0; j < array_n(smallestFanOuts); j++) { 02275 fanOut = array_fetch(int, smallestFanOuts, j); 02276 if (flag[fanOut]) 02277 continue; 02278 nFanIns[fanOut]--; 02279 } 02280 } 02281 02282 /* make new fanins & fanouts index array according to new order */ 02283 for (i = 0; i < n; i++) { 02284 fanIns = array_fetch(array_t *, newFanInsIndexArray, i); 02285 for (j = 0; j < array_n(fanIns); j++) { 02286 fanIn = array_fetch(int, fanIns, j); 02287 array_insert(int, fanIns, j, target[fanIn]); 02288 } 02289 fanOuts = array_fetch(array_t *, newFanOutsIndexArray, i); 02290 for (j = 0; j < array_n(fanOuts); j++) { 02291 fanOut = array_fetch(int, fanOuts, j); 02292 array_insert(int, fanOuts, j, target[fanOut]); 02293 } 02294 } 02295 02296 if (verbosityLevel > 1) { 02297 int k; 02298 02299 fprintf(vis_stdout, "=== sorted sub-fsm order ===\n"); 02300 for (i = 0; i < n; i++) 02301 fprintf(vis_stdout, " %d", order[i]); 02302 fprintf(vis_stdout, "\n"); 02303 02304 for (i = 0; i < n; i++) { 02305 fprintf(vis_stdout, "SUB-FSM [%d]\n", i); 02306 fanIns = array_fetch(array_t *, newFanInsIndexArray, i); 02307 fanOuts = array_fetch(array_t *, newFanOutsIndexArray, i); 02308 fprintf(vis_stdout, "== fanins(%d) :", array_n(fanIns)); 02309 for (j = 0; j < array_n(fanIns); j++) { 02310 k = array_fetch(int, fanIns, j); 02311 fprintf(vis_stdout, " %d", k); 02312 } 02313 fprintf(vis_stdout, "\n"); 02314 fprintf(vis_stdout, "== fanouts(%d) :", array_n(fanOuts)); 02315 for (j = 0; j < array_n(fanOuts); j++) { 02316 k = array_fetch(int, fanOuts, j); 02317 fprintf(vis_stdout, " %d", k); 02318 } 02319 fprintf(vis_stdout, "\n"); 02320 } 02321 } 02322 02323 FREE(flag); 02324 FREE(nFanIns); 02325 FREE(nFanOuts); 02326 if (verbosityLevel > 1) 02327 FREE(order); 02328 FREE(target); 02329 array_free(*subFsmArray); 02330 array_free(*fanInsIndexArray); 02331 array_free(*fanOutsIndexArray); 02332 *subFsmArray = newSubFsmArray; 02333 *fanInsIndexArray = newFanInsIndexArray; 02334 *fanOutsIndexArray = newFanOutsIndexArray; 02335 } 02336 02337 02400 static array_t * 02401 ArdcMbmTraversal( 02402 Fsm_Fsm_t *fsm, 02403 int nvars, 02404 array_t *subFsmArray, 02405 array_t *fanInsIndexArray, 02406 array_t *fanOutsIndexArray, 02407 mdd_t ***subReached /* sub-result for TMBM, pointer of bdd array */, 02408 /* The following arguments up to approxFlag are passed for exact 02409 * reachability. */ 02410 int incrementalFlag, 02411 int verbosityLevel, 02412 int printStep, 02413 int depthValue, 02414 int shellFlag, 02415 int reorderFlag, 02416 int reorderThreshold, 02417 Fsm_RchType_t approxFlag, 02418 Fsm_ArdcOptions_t *options, 02419 boolean lfpFlag /* If TRUE, performs LMBM */ 02420 ) 02421 { 02422 mdd_manager *mddManager; 02423 int i, n = array_n(subFsmArray); 02424 int *traverse; 02425 mdd_t **reached, **constraint; 02426 mdd_t **oldReached; 02427 mdd_t **frontier; 02428 int converged = 0; 02429 Fsm_Fsm_t **subFsm; 02430 array_t *fans; 02431 mdd_t *tmp; 02432 int iteration = 0; 02433 mdd_t **initial = NIL(mdd_t *); 02434 array_t *reachedArray = array_alloc(mdd_t *, 0); 02435 array_t *faninConstrainArray; 02436 Img_ImageInfo_t *imageInfo = NIL(Img_ImageInfo_t); 02437 int dynStatus; 02438 bdd_reorder_type_t dynMethod; 02439 boolean restoreContainmentFlag; 02440 boolean reuseTrFlag = FALSE; 02441 /* If set, just update the transition relation 02442 without copying the original transition relation */ 02443 boolean reused = FALSE; 02444 boolean duplicate; 02445 boolean tmpReorderPtrFlag; 02446 int nConstrainOps = 0; 02447 long tImgComps = 0; 02448 long tConstrainOps = 0; 02449 long tRestoreContainment = 0; 02450 long tAbstractVars = 0; 02451 long tBuildTr = 0; 02452 long initialTime = 0, finalTime; 02453 int maxIteration = options->maxIteration; 02454 int constrainTarget = options->constrainTarget; 02455 boolean decomposeFlag = options->decomposeFlag; 02456 int abstractPseudoInput = options->abstractPseudoInput; 02457 Img_MinimizeType constrainMethod = options->constrainMethod; 02458 boolean projectedInitialFlag = options->projectedInitialFlag; 02459 int ardcVerbosity = options->verbosity; 02460 boolean constrainReorderFlag = options->constrainReorderFlag; 02461 boolean reorderPtrFlag = options->reorderPtrFlag; 02462 int faninConstrainMode = options->faninConstrainMode; 02463 int lmbmInitialStatesMode = options->lmbmInitialStatesMode; 02464 02465 reuseTrFlag = FsmGetArdcSetBooleanValue("ardc_mbm_reuse_tr", reuseTrFlag); 02466 if (reuseTrFlag && lfpFlag) { 02467 /* This is to use the i-th constrained transition relation in 02468 * the (i+1)-th iteration, instead of the original transition relation. 02469 * Therefore, the i-th constraint should be a superset of the (i+1)-th. */ 02470 fprintf(vis_stderr, 02471 "** ardc error : can't reuse transition relation in LMBM. **\n"); 02472 reuseTrFlag = FALSE; 02473 } 02474 02475 Img_ResetNumberOfImageComputation(Img_Forward_c); 02476 02477 reached = ALLOC(mdd_t *, n); 02478 constraint = ALLOC(mdd_t *, n); 02479 traverse = ALLOC(int, n); /* array used for scheduling */ 02480 subFsm = ALLOC(Fsm_Fsm_t *, n); 02481 oldReached = ALLOC(mdd_t *, n); 02482 02483 mddManager = Fsm_FsmReadMddManager(fsm); 02484 for (i = 0; i < n; i++) { 02485 subFsm[i] = array_fetch(Fsm_Fsm_t *, subFsmArray, i); 02486 oldReached[i] = NIL(mdd_t); 02487 } 02488 02489 /* Set up. */ 02490 if (lfpFlag) { /* LMBM */ 02491 initial = ALLOC(mdd_t *, n); 02492 for (i = 0; i < n; i++) 02493 initial[i] = Fsm_FsmComputeInitialStates(subFsm[i]); 02494 if (lmbmInitialStatesMode >= 1) /* restart from frontier states */ 02495 frontier = ALLOC(mdd_t *, n); 02496 else 02497 frontier = NIL(mdd_t *); 02498 02499 for (i = 0; i < n; i++) { 02500 reached[i] = mdd_dup(initial[i]); 02501 constraint[i] = mdd_dup(initial[i]); 02502 traverse[i] = 1; 02503 if (frontier) 02504 frontier[i] = NIL(mdd_t); 02505 } 02506 } else { /* MBM */ 02507 for (i = 0; i < n; i++) { 02508 reached[i] = mdd_one(mddManager); 02509 constraint[i] = mdd_one(mddManager); 02510 traverse[i] = 1; 02511 } 02512 02513 if (constrainTarget == Fsm_Ardc_Constrain_Initial_c || 02514 constrainTarget == Fsm_Ardc_Constrain_Both_c) { 02515 initial = ALLOC(mdd_t *, n); 02516 for (i = 0; i < n; i++) 02517 initial[i] = Fsm_FsmComputeInitialStates(subFsm[i]); 02518 } 02519 02520 frontier = NIL(mdd_t *); 02521 } 02522 02523 /* Set the flag for containment restoration according to the options. */ 02524 if (constrainMethod == Img_Constrain_c && 02525 constrainReorderFlag == FALSE && 02526 abstractPseudoInput == Fsm_Ardc_Abst_Ppi_No_c) { 02527 restoreContainmentFlag = FALSE; 02528 } else 02529 restoreContainmentFlag = TRUE; 02530 02531 /* Compute fixpoint. */ 02532 do { 02533 converged = 1; 02534 for (i = 0; i < n; i++) { 02535 if (!traverse[i]) 02536 continue; 02537 if (ardcVerbosity > 1) 02538 fprintf(vis_stdout, "--- sub fsm [%d] ---\n", i); 02539 if (oldReached[i]) 02540 mdd_free(oldReached[i]); 02541 oldReached[i] = reached[i]; 02542 /* Build constraint array. */ 02543 faninConstrainArray = array_alloc(mdd_t *, 0); 02544 fans = array_fetch(array_t *, fanInsIndexArray, i); 02545 ComputeFaninConstrainArray(faninConstrainArray, constraint, 02546 i, fans, decomposeFlag, faninConstrainMode); 02547 /* Build constrained transition relation. */ 02548 dynStatus = bdd_reordering_status(mddManager, &dynMethod); 02549 if (dynStatus != 0 && constrainReorderFlag == 0) 02550 bdd_dynamic_reordering_disable(mddManager); 02551 if (ardcVerbosity > 0) 02552 initialTime = util_cpu_time(); 02553 imageInfo = Fsm_FsmReadOrCreateImageInfo(subFsm[i], 0, 1); /* forward */ 02554 if (ardcVerbosity > 0) { 02555 finalTime = util_cpu_time(); 02556 tBuildTr += finalTime - initialTime; 02557 } 02558 /* Minimize the transition relation of the current submachine w.r.t. 02559 * the reached set of its fanin submachines. 02560 */ 02561 if (constrainTarget != Fsm_Ardc_Constrain_Initial_c) { 02562 int saveStatus = Img_ReadPrintMinimizeStatus(imageInfo); 02563 if (ardcVerbosity > 2) 02564 Img_SetPrintMinimizeStatus(imageInfo, 2); 02565 else if (ardcVerbosity > 0) 02566 Img_SetPrintMinimizeStatus(imageInfo, 1); 02567 else 02568 Img_SetPrintMinimizeStatus(imageInfo, 0); 02569 if (reuseTrFlag) { 02570 if (reused) 02571 duplicate = FALSE; 02572 else 02573 duplicate = TRUE; 02574 } else 02575 duplicate = TRUE; 02576 if (reorderPtrFlag && 02577 abstractPseudoInput != Fsm_Ardc_Abst_Ppi_Before_Image_c) { 02578 tmpReorderPtrFlag = 1; 02579 } else 02580 tmpReorderPtrFlag = 0; 02581 if (ardcVerbosity > 0) 02582 initialTime = util_cpu_time(); 02583 MinimizeTransitionRelationWithFaninConstraint(imageInfo, 02584 faninConstrainArray, constrainMethod, tmpReorderPtrFlag, 02585 duplicate); 02586 if (ardcVerbosity > 0) { 02587 finalTime = util_cpu_time(); 02588 tConstrainOps += finalTime - initialTime; 02589 } 02590 Img_SetPrintMinimizeStatus(imageInfo, saveStatus); 02591 } 02592 if (constrainTarget != Fsm_Ardc_Constrain_Tr_c) { 02593 ComputeConstrainedInitialStates(subFsm[i], faninConstrainArray, 02594 constrainMethod); 02595 } 02596 nConstrainOps++; 02597 mdd_array_free(faninConstrainArray); 02598 /* Restore dynamic reordering options if they had been changed. */ 02599 if (dynStatus != 0 && constrainReorderFlag == 0) { 02600 bdd_dynamic_reordering(mddManager, dynMethod, 02601 BDD_REORDER_VERBOSITY_DEFAULT); 02602 } 02603 /* Quantify pseudo-input variables from the transition relation. */ 02604 if (abstractPseudoInput == Fsm_Ardc_Abst_Ppi_Before_Image_c) { 02605 int saveStatus = Img_ReadPrintMinimizeStatus(imageInfo); 02606 if (ardcVerbosity > 2) 02607 Img_SetPrintMinimizeStatus(imageInfo, 2); 02608 else if (ardcVerbosity > 0) 02609 Img_SetPrintMinimizeStatus(imageInfo, 1); 02610 else 02611 Img_SetPrintMinimizeStatus(imageInfo, 0); 02612 if (ardcVerbosity > 0) 02613 initialTime = util_cpu_time(); 02614 Img_AbstractTransitionRelation(imageInfo, 02615 subFsm[i]->fsmData.pseudoInputBddVars, 02616 subFsm[i]->fsmData.pseudoInputCube, Img_Forward_c); 02617 if (reorderPtrFlag) 02618 Img_ReorderPartitionedTransitionRelation(imageInfo, Img_Forward_c); 02619 if (ardcVerbosity > 0) { 02620 finalTime = util_cpu_time(); 02621 tAbstractVars += finalTime - initialTime; 02622 } 02623 Img_SetPrintMinimizeStatus(imageInfo, saveStatus); 02624 } 02625 if (lfpFlag && lmbmInitialStatesMode > 0 && iteration > 0) { 02626 /* Update the initial states to either reached or frontier. */ 02627 FsmSetReachabilityApproxComputationStatus(subFsm[i], Fsm_Rch_Under_c); 02628 mdd_free(subFsm[i]->reachabilityInfo.initialStates); 02629 if (lmbmInitialStatesMode == 1) 02630 subFsm[i]->reachabilityInfo.initialStates = mdd_dup(reached[i]); 02631 else 02632 subFsm[i]->reachabilityInfo.initialStates = mdd_dup(frontier[i]); 02633 } else { 02634 /* Reset the reachable states for a new reachability. */ 02635 if (subFsm[i]->reachabilityInfo.reachableStates) { 02636 mdd_free(subFsm[i]->reachabilityInfo.reachableStates); 02637 subFsm[i]->reachabilityInfo.reachableStates = NIL(mdd_t); 02638 } 02639 subFsm[i]->reachabilityInfo.depth = 0; 02640 } 02641 /* Traverse this submachine. */ 02642 if (ardcVerbosity > 0) 02643 initialTime = util_cpu_time(); 02644 reached[i] = Fsm_FsmComputeReachableStates(subFsm[i], 02645 incrementalFlag, verbosityLevel, printStep, depthValue, 02646 shellFlag, reorderFlag, reorderThreshold, 02647 approxFlag, 0, 0, NIL(array_t), FALSE, NIL(array_t)); 02648 if (Img_ImageInfoObtainMethodType(imageInfo) == Img_Tfm_c || 02649 Img_ImageInfoObtainMethodType(imageInfo) == Img_Hybrid_c) { 02650 Img_TfmFlushCache(imageInfo, FALSE); 02651 } 02652 if (ardcVerbosity > 0) { 02653 finalTime = util_cpu_time(); 02654 tImgComps += finalTime - initialTime; 02655 } 02656 /* Compute the frontier for LMBM. */ 02657 if (lfpFlag && lmbmInitialStatesMode > 0) { 02658 if (lmbmInitialStatesMode >= 1) { 02659 if (iteration == 0) 02660 frontier[i] = mdd_dup(reached[i]); 02661 else { 02662 mdd_t *fromLowerBound; 02663 02664 fromLowerBound = mdd_and(reached[i], oldReached[i], 1, 0); 02665 tmp = reached[i]; 02666 reached[i] = mdd_or(oldReached[i], tmp, 1, 1); 02667 mdd_free(tmp); 02668 mdd_free(frontier[i]); 02669 if (lmbmInitialStatesMode == 2) { 02670 frontier[i] = bdd_between(fromLowerBound, reached[i]); 02671 mdd_free(fromLowerBound); 02672 } else 02673 frontier[i] = fromLowerBound; 02674 } 02675 } 02676 if (iteration > 0) { 02677 mdd_free(subFsm[i]->reachabilityInfo.initialStates); 02678 subFsm[i]->reachabilityInfo.initialStates = mdd_dup(initial[i]); 02679 } 02680 } 02681 /* Restore the original transition relation. */ 02682 if (constrainTarget != Fsm_Ardc_Constrain_Initial_c) { 02683 if (!reuseTrFlag) 02684 Img_RestoreTransitionRelation(imageInfo, Img_Forward_c); 02685 } 02686 /* Quantify the pseudo-input variables from reached. */ 02687 if (abstractPseudoInput == Fsm_Ardc_Abst_Ppi_After_Image_c) { 02688 if (ardcVerbosity > 0) 02689 initialTime = util_cpu_time(); 02690 if (n > 1) { 02691 tmp = reached[i]; 02692 reached[i] = QuantifyVariables(reached[i], 02693 subFsm[i]->fsmData.pseudoInputBddVars, 02694 subFsm[i]->fsmData.pseudoInputCube); 02695 mdd_free(tmp); 02696 } 02697 if (ardcVerbosity > 0) { 02698 finalTime = util_cpu_time(); 02699 tAbstractVars += finalTime - initialTime; 02700 } 02701 } 02702 02703 mdd_free(constraint[i]); 02704 constraint[i] = mdd_dup(reached[i]); 02705 /* Update traversal schedule and possibly restore containment. */ 02706 traverse[i] = 0; 02707 if (!mdd_equal(oldReached[i], reached[i])) { 02708 if (ardcVerbosity > 2) { 02709 double r1, r2; 02710 02711 r1 = mdd_count_onset(mddManager, reached[i], 02712 subFsm[i]->fsmData.presentStateVars); 02713 r2 = mdd_count_onset(mddManager, oldReached[i], 02714 subFsm[i]->fsmData.presentStateVars); 02715 fprintf(vis_stdout, "oldReached = %g, reached = %g\n", r2, r1); 02716 } 02717 02718 /* Restore-containment operation. */ 02719 if (restoreContainmentFlag) { 02720 if (ardcVerbosity > 0) 02721 initialTime = util_cpu_time(); 02722 if (lfpFlag) { /* LMBM */ 02723 if (mdd_lequal(oldReached[i], reached[i], 1, 1)) { 02724 /* Containment OK. */ 02725 fans = array_fetch(array_t *, fanOutsIndexArray, i); 02726 UpdateMbmEventSchedule(subFsm, fans, traverse, lfpFlag); 02727 } else { 02728 /* Restoration needed. */ 02729 if (ardcVerbosity > 1) { 02730 fprintf(vis_stdout, 02731 "** ardc info: reached is not superset of oldReached in subFsm[%d] **\n", 02732 i); 02733 } 02734 mdd_free(reached[i]); 02735 reached[i] = mdd_or(oldReached[i], 02736 subFsm[i]->reachabilityInfo.reachableStates, 1, 1); 02737 mdd_free(subFsm[i]->reachabilityInfo.reachableStates); 02738 subFsm[i]->reachabilityInfo.reachableStates = mdd_dup(reached[i]); 02739 mdd_free(constraint[i]); 02740 constraint[i] = mdd_dup(reached[i]); 02741 if (!mdd_equal(oldReached[i], reached[i])) { 02742 fans = array_fetch(array_t *, fanOutsIndexArray, i); 02743 UpdateMbmEventSchedule(subFsm, fans, traverse, lfpFlag); 02744 } 02745 } 02746 } else { /* MBM */ 02747 if (!mdd_lequal(reached[i], oldReached[i], 1, 1)) { 02748 /* Restoration needed. */ 02749 if (ardcVerbosity > 1) { 02750 fprintf(vis_stdout, 02751 "** ardc info: reached is not subset of oldReached in subFsm[%d] **\n", i); 02752 } 02753 mdd_free(reached[i]); 02754 reached[i] = mdd_and(oldReached[i], 02755 subFsm[i]->reachabilityInfo.reachableStates, 1, 1); 02756 mdd_free(subFsm[i]->reachabilityInfo.reachableStates); 02757 subFsm[i]->reachabilityInfo.reachableStates = mdd_dup(reached[i]); 02758 mdd_free(constraint[i]); 02759 constraint[i] = mdd_dup(reached[i]); 02760 if (!mdd_equal(oldReached[i], reached[i])) { 02761 fans = array_fetch(array_t *, fanOutsIndexArray, i); 02762 UpdateMbmEventSchedule(subFsm, fans, traverse, lfpFlag); 02763 } 02764 } else { 02765 /* Containment OK. */ 02766 fans = array_fetch(array_t *, fanOutsIndexArray, i); 02767 UpdateMbmEventSchedule(subFsm, fans, traverse, lfpFlag); 02768 } 02769 } 02770 if (ardcVerbosity > 0) { 02771 finalTime = util_cpu_time(); 02772 tRestoreContainment += finalTime - initialTime; 02773 } 02774 } else { /* no containment restoration needed */ 02775 fans = array_fetch(array_t *, fanOutsIndexArray, i); 02776 UpdateMbmEventSchedule(subFsm, fans, traverse, lfpFlag); 02777 } 02778 } 02779 } 02780 /* Check for convergence. */ 02781 for (i = 0; i < n; i++) { 02782 if (traverse[i]) { 02783 converged = 0; 02784 break; 02785 } 02786 } 02787 iteration++; 02788 if (ardcVerbosity > 0) { 02789 boolean supportCheckFlag = FALSE; 02790 02791 /* Print the current reached states and check the supports. */ 02792 if (projectedInitialFlag || 02793 abstractPseudoInput == Fsm_Ardc_Abst_Ppi_Before_Image_c) { 02794 supportCheckFlag = TRUE; 02795 } 02796 if (lfpFlag) { 02797 PrintCurrentReachedStates(mddManager, subFsm, reached, 02798 Fsm_Ardc_Traversal_Lmbm_c, 02799 n, iteration, nvars, ardcVerbosity, 02800 supportCheckFlag); 02801 } else { 02802 PrintCurrentReachedStates(mddManager, subFsm, reached, 02803 Fsm_Ardc_Traversal_Mbm_c, 02804 n, iteration, nvars, ardcVerbosity, 02805 supportCheckFlag); 02806 } 02807 } 02808 02809 if (iteration == maxIteration) 02810 break; 02811 } while (!converged); 02812 02813 /* Restore the original transtion relation. */ 02814 if (reuseTrFlag) { 02815 if (constrainTarget != Fsm_Ardc_Constrain_Initial_c) 02816 Img_RestoreTransitionRelation(imageInfo, Img_Forward_c); 02817 } 02818 02819 if (ardcVerbosity > 0) { 02820 if (lfpFlag) 02821 fprintf(vis_stdout, "LMBM : total iterations %d\n", iteration); 02822 else 02823 fprintf(vis_stdout, "MBM : total iterations %d\n", iteration); 02824 } 02825 02826 /* Reset the initial states to the original. */ 02827 if (constrainTarget == Fsm_Ardc_Constrain_Initial_c || 02828 constrainTarget == Fsm_Ardc_Constrain_Both_c || lfpFlag) { 02829 for (i = 0; i < n; i++) { 02830 mdd_free(subFsm[i]->reachabilityInfo.initialStates); 02831 subFsm[i]->reachabilityInfo.initialStates = initial[i]; 02832 } 02833 FREE(initial); 02834 } 02835 02836 /* Quantify the pseudo-input variables from reached. */ 02837 if (abstractPseudoInput == Fsm_Ardc_Abst_Ppi_At_End_c) { 02838 if (ardcVerbosity > 0) 02839 initialTime = util_cpu_time(); 02840 for (i = 0; i < n; i++) { 02841 tmp = reached[i]; 02842 reached[i] = QuantifyVariables(reached[i], 02843 subFsm[i]->fsmData.pseudoInputBddVars, 02844 subFsm[i]->fsmData.pseudoInputCube); 02845 mdd_free(tmp); 02846 } 02847 if (ardcVerbosity > 0) { 02848 finalTime = util_cpu_time(); 02849 tAbstractVars += finalTime - initialTime; 02850 } 02851 } 02852 02853 /* Set the status of current overapproximate reached states. */ 02854 if (converged) 02855 FsmSetReachabilityOverApproxComputationStatus(fsm, Fsm_Ardc_Converged_c); 02856 else if (lfpFlag) 02857 FsmSetReachabilityOverApproxComputationStatus(fsm, Fsm_Ardc_NotConverged_c); 02858 else 02859 FsmSetReachabilityOverApproxComputationStatus(fsm, Fsm_Ardc_Valid_c); 02860 02861 ComputeApproximateReachableStatesArray(mddManager, reachedArray, 02862 reached, subReached, n, 02863 decomposeFlag); 02864 /* Clean up. */ 02865 if (decomposeFlag) { 02866 for (i = 0; i < n; i++) { 02867 mdd_free(oldReached[i]); 02868 mdd_free(constraint[i]); 02869 } 02870 } else { 02871 for (i = 0; i < n; i++) { 02872 mdd_free(oldReached[i]); 02873 if (subReached == NULL) 02874 mdd_free(reached[i]); 02875 mdd_free(constraint[i]); 02876 } 02877 } 02878 02879 if (subReached) 02880 *subReached = reached; 02881 else 02882 FREE(reached); 02883 FREE(traverse); 02884 FREE(constraint); 02885 FREE(subFsm); 02886 FREE(oldReached); 02887 if (lfpFlag && lmbmInitialStatesMode >= 1) {/*consistent:from >1 to >=1 C.W*/ 02888 for (i = 0; i < n; i++) { 02889 if (frontier[i]) 02890 mdd_free(frontier[i]); 02891 } 02892 FREE(frontier); 02893 } 02894 02895 /* Print final stats. */ 02896 if (ardcVerbosity > 0) { 02897 fprintf(vis_stdout, "%d image computations, %d constrain operations\n", 02898 Img_GetNumberOfImageComputation(Img_Forward_c), nConstrainOps); 02899 fprintf(vis_stdout, 02900 "image computation time = %g, constrain operation time = %g\n", 02901 (double)tImgComps / 1000.0, (double)tConstrainOps / 1000.0); 02902 fprintf(vis_stdout, "restore-containment time = %g\n", 02903 (double)tRestoreContainment / 1000.0); 02904 fprintf(vis_stdout, "abstract variables time = %g\n", 02905 (double)tAbstractVars / 1000.0); 02906 fprintf(vis_stdout, "build TR time = %g\n", 02907 (double)tBuildTr / 1000.0); 02908 } 02909 02910 return(reachedArray); 02911 } 02912 02913 02930 static array_t * 02931 ArdcRfbfTraversal(Fsm_Fsm_t *fsm, int nvars, 02932 array_t *subFsmArray, array_t *fanInsIndexArray, 02933 int incrementalFlag, int verbosityLevel, 02934 int printStep, int depthValue, int shellFlag, 02935 int reorderFlag, int reorderThreshold, 02936 Fsm_RchType_t approxFlag, Fsm_ArdcOptions_t *options) 02937 { 02938 mdd_manager *mddManager; 02939 int i, n = array_n(subFsmArray); 02940 mdd_t **reached, **constraint, **newConstraint; 02941 mdd_t **newReached, *to; 02942 int converged = 0; 02943 Fsm_Fsm_t **subFsm; 02944 array_t *fans; 02945 mdd_t *tmp; 02946 mdd_t *initialStates; 02947 int iteration = 0; 02948 mdd_t **initial = NIL(mdd_t *); 02949 array_t *reachedArray = array_alloc(mdd_t *, 0); 02950 array_t *faninConstrainArray; 02951 Img_ImageInfo_t *imageInfo = NIL(Img_ImageInfo_t); 02952 int dynStatus; 02953 bdd_reorder_type_t dynMethod; 02954 boolean restoreContainmentFlag; 02955 mdd_t *toCareSet; 02956 array_t *toCareSetArray = array_alloc(mdd_t *, 0); 02957 int depth = 0; 02958 boolean tmpReorderPtrFlag; 02959 long tImgComps = 0; 02960 long tConstrainOps = 0; 02961 long initialTime = 0, finalTime; 02962 int maxIteration = options->maxIteration; 02963 int constrainTarget = options->constrainTarget; 02964 boolean decomposeFlag = options->decomposeFlag; 02965 int abstractPseudoInput = options->abstractPseudoInput; 02966 Img_MinimizeType constrainMethod = options->constrainMethod; 02967 boolean projectedInitialFlag = options->projectedInitialFlag; 02968 int ardcVerbosity = options->verbosity; 02969 boolean constrainReorderFlag = options->constrainReorderFlag; 02970 boolean reorderPtrFlag = options->reorderPtrFlag; 02971 int faninConstrainMode = options->faninConstrainMode; 02972 02973 Img_ResetNumberOfImageComputation(Img_Forward_c); 02974 02975 reached = ALLOC(mdd_t *, n); 02976 constraint = ALLOC(mdd_t *, n); 02977 newConstraint = ALLOC(mdd_t *, n); 02978 subFsm = ALLOC(Fsm_Fsm_t *, n); 02979 newReached = ALLOC(mdd_t *, n); 02980 02981 mddManager = Fsm_FsmReadMddManager(fsm); 02982 for (i = 0; i < n; i++) { 02983 subFsm[i] = array_fetch(Fsm_Fsm_t *, subFsmArray, i); 02984 initialStates = Fsm_FsmComputeInitialStates(subFsm[i]); 02985 reached[i] = initialStates; 02986 constraint[i] = mdd_dup(initialStates); 02987 02988 if (printStep && ((depth % printStep) == 0)) { 02989 if (ardcVerbosity > 1) 02990 fprintf(vis_stdout, "--- sub fsm [%d] ---\n", i); 02991 (void)fprintf(vis_stdout, 02992 "BFS step = %d\t|states| = %8g\tBdd size = %8ld\n", depth, 02993 mdd_count_onset(mddManager, reached[i], 02994 subFsm[i]->fsmData.presentStateVars), 02995 (long)mdd_size(reached[i])); 02996 } 02997 } 02998 02999 if (constrainTarget == Fsm_Ardc_Constrain_Initial_c || 03000 constrainTarget == Fsm_Ardc_Constrain_Both_c) { 03001 initial = ALLOC(mdd_t *, n); 03002 for (i = 0; i < n; i++) 03003 initial[i] = mdd_dup(reached[i]); 03004 } 03005 03006 if (constrainMethod != Img_Constrain_c || 03007 constrainReorderFlag == TRUE || 03008 abstractPseudoInput != Fsm_Ardc_Abst_Ppi_No_c) { 03009 restoreContainmentFlag = TRUE; 03010 } else 03011 restoreContainmentFlag = FALSE; 03012 03013 converged = 0; 03014 do { 03015 depth++; 03016 for (i = 0; i < n; i++) { 03017 if (ardcVerbosity > 1) 03018 fprintf(vis_stdout, "--- sub fsm [%d] ---\n", i); 03019 faninConstrainArray = array_alloc(mdd_t *, 0); 03020 fans = array_fetch(array_t *, fanInsIndexArray, i); 03021 ComputeFaninConstrainArray(faninConstrainArray, constraint, 03022 i, fans, decomposeFlag, faninConstrainMode); 03023 dynStatus = bdd_reordering_status(mddManager, &dynMethod); 03024 if (dynStatus != 0 && constrainReorderFlag == 0) 03025 bdd_dynamic_reordering_disable(mddManager); 03026 imageInfo = Fsm_FsmReadOrCreateImageInfo(subFsm[i], 0, 1); 03027 if (constrainTarget != Fsm_Ardc_Constrain_Initial_c) { 03028 int saveStatus = Img_ReadPrintMinimizeStatus(imageInfo); 03029 if (ardcVerbosity > 2) 03030 Img_SetPrintMinimizeStatus(imageInfo, 2); 03031 else if (ardcVerbosity > 0) 03032 Img_SetPrintMinimizeStatus(imageInfo, 1); 03033 else 03034 Img_SetPrintMinimizeStatus(imageInfo, 0); 03035 if (reorderPtrFlag && 03036 abstractPseudoInput != Fsm_Ardc_Abst_Ppi_Before_Image_c) { 03037 tmpReorderPtrFlag = 1; 03038 } else 03039 tmpReorderPtrFlag = 0; 03040 if (ardcVerbosity > 0) 03041 initialTime = util_cpu_time(); 03042 MinimizeTransitionRelationWithFaninConstraint(imageInfo, 03043 faninConstrainArray, constrainMethod, tmpReorderPtrFlag, 03044 TRUE); 03045 if (ardcVerbosity > 0) { 03046 finalTime = util_cpu_time(); 03047 tConstrainOps += finalTime - initialTime; 03048 } 03049 Img_SetPrintMinimizeStatus(imageInfo, saveStatus); 03050 } 03051 if (constrainTarget != Fsm_Ardc_Constrain_Tr_c) { 03052 ComputeConstrainedInitialStates(subFsm[i], faninConstrainArray, 03053 constrainMethod); 03054 } 03055 mdd_array_free(faninConstrainArray); 03056 if (dynStatus != 0 && constrainReorderFlag == 0) { 03057 bdd_dynamic_reordering(mddManager, dynMethod, 03058 BDD_REORDER_VERBOSITY_DEFAULT); 03059 } 03060 if (abstractPseudoInput == Fsm_Ardc_Abst_Ppi_Before_Image_c) { 03061 int saveStatus = Img_ReadPrintMinimizeStatus(imageInfo); 03062 if (ardcVerbosity > 2) 03063 Img_SetPrintMinimizeStatus(imageInfo, 2); 03064 else if (ardcVerbosity > 0) 03065 Img_SetPrintMinimizeStatus(imageInfo, 1); 03066 else 03067 Img_SetPrintMinimizeStatus(imageInfo, 0); 03068 Img_AbstractTransitionRelation(imageInfo, 03069 subFsm[i]->fsmData.pseudoInputBddVars, 03070 subFsm[i]->fsmData.pseudoInputCube, Img_Forward_c); 03071 if (reorderPtrFlag) 03072 Img_ReorderPartitionedTransitionRelation(imageInfo, Img_Forward_c); 03073 Img_SetPrintMinimizeStatus(imageInfo, saveStatus); 03074 } 03075 toCareSet = mdd_not(reached[i]); 03076 array_insert(mdd_t *, toCareSetArray, 0, toCareSet); 03077 if (ardcVerbosity > 0) 03078 initialTime = util_cpu_time(); 03079 to = Fsm_ArdcComputeImage(subFsm[i], reached[i], reached[i], 03080 toCareSetArray); 03081 if (Img_ImageInfoObtainMethodType(imageInfo) == Img_Tfm_c || 03082 Img_ImageInfoObtainMethodType(imageInfo) == Img_Hybrid_c) { 03083 Img_TfmFlushCache(imageInfo, FALSE); 03084 } 03085 if (ardcVerbosity > 0) { 03086 finalTime = util_cpu_time(); 03087 tImgComps += finalTime - initialTime; 03088 } 03089 mdd_free(toCareSet); 03090 03091 newReached[i] = mdd_or(reached[i], to, 1, 1); 03092 mdd_free(to); 03093 if (constrainTarget != Fsm_Ardc_Constrain_Initial_c) 03094 Img_RestoreTransitionRelation(imageInfo, Img_Forward_c); 03095 if (abstractPseudoInput == Fsm_Ardc_Abst_Ppi_After_Image_c) { 03096 tmp = newReached[i]; 03097 newReached[i] = QuantifyVariables(newReached[i], 03098 subFsm[i]->fsmData.pseudoInputBddVars, 03099 subFsm[i]->fsmData.pseudoInputCube); 03100 mdd_free(tmp); 03101 } 03102 03103 /* restore-containment operation */ 03104 if (restoreContainmentFlag) { 03105 if (!mdd_lequal(reached[i], newReached[i], 1, 1)) { 03106 if (ardcVerbosity > 2) { 03107 double r1, r2; 03108 03109 fprintf(vis_stdout, 03110 "** ardc warning : newReached is not superset of reached in subFsm[%d] **\n", 03111 i); 03112 r1 = mdd_count_onset(mddManager, reached[i], 03113 subFsm[i]->fsmData.presentStateVars); 03114 r2 = mdd_count_onset(mddManager, newReached[i], 03115 subFsm[i]->fsmData.presentStateVars); 03116 fprintf(vis_stdout, "reached = %g, newReached = %g\n", r1, r2); 03117 } 03118 tmp = newReached[i]; 03119 newReached[i] = mdd_or(newReached[i], reached[i], 1, 1); 03120 mdd_free(tmp); 03121 } 03122 } 03123 03124 newConstraint[i] = mdd_dup(newReached[i]); 03125 03126 if (printStep && ((depth % printStep) == 0)) { 03127 (void)fprintf(vis_stdout, 03128 "BFS step = %d\t|states| = %8g\tBdd size = %8ld\n", 03129 depth, mdd_count_onset(mddManager, newReached[i], 03130 subFsm[i]->fsmData.presentStateVars), 03131 (long)mdd_size(newReached[i])); 03132 } 03133 } 03134 converged = 1; 03135 for (i = 0; i < n; i++) { 03136 if (mdd_equal(reached[i], newReached[i])) 03137 mdd_free(newReached[i]); 03138 else { 03139 converged = 0; 03140 mdd_free(reached[i]); 03141 reached[i] = newReached[i]; 03142 } 03143 } 03144 iteration++; 03145 if (ardcVerbosity > 0) { 03146 boolean supportCheckFlag = FALSE; 03147 03148 if (projectedInitialFlag || 03149 abstractPseudoInput == Fsm_Ardc_Abst_Ppi_Before_Image_c) { 03150 supportCheckFlag = TRUE; 03151 } 03152 PrintCurrentReachedStates(mddManager, subFsm, reached, 03153 Fsm_Ardc_Traversal_Rfbf_c, 03154 n, iteration, nvars, ardcVerbosity, 03155 supportCheckFlag); 03156 } 03157 03158 /* update constraints */ 03159 for (i = 0; i < n; i++) { 03160 mdd_free(constraint[i]); 03161 constraint[i] = newConstraint[i]; 03162 newConstraint[i] = NIL(mdd_t); 03163 } 03164 03165 if (iteration == maxIteration) 03166 break; 03167 } while (!converged); 03168 if (ardcVerbosity > 0) { 03169 fprintf(vis_stdout, "RFBF : total iteration %d\n", iteration); 03170 fprintf(vis_stdout, "%d image computations, %d constrain operations\n", 03171 Img_GetNumberOfImageComputation(Img_Forward_c), n * iteration); 03172 fprintf(vis_stdout, 03173 "image computation time = %g, constrain operation time = %g\n", 03174 (double)tImgComps / 1000.0, (double)tConstrainOps / 1000.0); 03175 } 03176 03177 if (constrainTarget == Fsm_Ardc_Constrain_Initial_c || 03178 constrainTarget == Fsm_Ardc_Constrain_Both_c) { 03179 for (i = 0; i < n; i++) { 03180 mdd_free(subFsm[i]->reachabilityInfo.initialStates); 03181 subFsm[i]->reachabilityInfo.initialStates = initial[i]; 03182 } 03183 FREE(initial); 03184 } 03185 03186 if (abstractPseudoInput == Fsm_Ardc_Abst_Ppi_At_End_c) { 03187 for (i = 0; i < n; i++) { 03188 tmp = reached[i]; 03189 reached[i] = QuantifyVariables(reached[i], 03190 subFsm[i]->fsmData.pseudoInputBddVars, 03191 subFsm[i]->fsmData.pseudoInputCube); 03192 mdd_free(tmp); 03193 } 03194 } 03195 03196 /* sets the status of current overapproximate reached states */ 03197 if (converged) 03198 FsmSetReachabilityOverApproxComputationStatus(fsm, Fsm_Ardc_Converged_c); 03199 else 03200 FsmSetReachabilityOverApproxComputationStatus(fsm, Fsm_Ardc_NotConverged_c); 03201 03202 ComputeApproximateReachableStatesArray(mddManager, reachedArray, 03203 reached, NULL, n, decomposeFlag); 03204 if (decomposeFlag) { 03205 for (i = 0; i < n; i++) { 03206 mdd_free(constraint[i]); 03207 } 03208 } else { 03209 for (i = 0; i < n; i++) { 03210 mdd_free(reached[i]); 03211 mdd_free(constraint[i]); 03212 } 03213 } 03214 03215 FREE(reached); 03216 FREE(constraint); 03217 FREE(newConstraint); 03218 FREE(subFsm); 03219 FREE(newReached); 03220 array_free(toCareSetArray); 03221 03222 return(reachedArray); 03223 } 03224 03225 03242 static array_t * 03243 ArdcTfbfTraversal(Fsm_Fsm_t *fsm, int nvars, 03244 array_t *subFsmArray, array_t *fanInsIndexArray, 03245 mdd_t ***subReached, mdd_t ***subTo, 03246 int incrementalFlag, int verbosityLevel, 03247 int printStep, int depthValue, int shellFlag, 03248 int reorderFlag, int reorderThreshold, 03249 Fsm_RchType_t approxFlag, Fsm_ArdcOptions_t *options) 03250 { 03251 mdd_manager *mddManager = NIL(mdd_manager); 03252 int i, j, n = array_n(subFsmArray); 03253 mdd_t **reached, **constraint, **newConstraint; 03254 mdd_t **to, **old_to; 03255 int converged = 0; 03256 Fsm_Fsm_t **subFsm; 03257 array_t *pi_to; 03258 mdd_t *tmp; 03259 array_t *fans; 03260 mdd_t *initialStates; 03261 int iteration = 0; 03262 mdd_t **initial = NIL(mdd_t *); 03263 array_t *reachedArray = array_alloc(mdd_t *, 0); 03264 array_t *faninConstrainArray; 03265 Img_ImageInfo_t *imageInfo = NIL(Img_ImageInfo_t); 03266 int dynStatus; 03267 bdd_reorder_type_t dynMethod; 03268 mdd_t *toCareSet; 03269 array_t *toCareSetArray = array_alloc(mdd_t *, 0); 03270 int depth = 0; 03271 boolean tmpReorderPtrFlag; 03272 long tImgComps = 0; 03273 long tConstrainOps = 0; 03274 long initialTime = 0, finalTime; 03275 int maxIteration = options->maxIteration; 03276 int constrainTarget = options->constrainTarget; 03277 boolean decomposeFlag = options->decomposeFlag; 03278 int abstractPseudoInput = options->abstractPseudoInput; 03279 Img_MinimizeType constrainMethod = options->constrainMethod; 03280 boolean projectedInitialFlag = options->projectedInitialFlag; 03281 int ardcVerbosity = options->verbosity; 03282 boolean constrainReorderFlag = options->constrainReorderFlag; 03283 boolean reorderPtrFlag = options->reorderPtrFlag; 03284 int faninConstrainMode = options->faninConstrainMode; 03285 03286 Img_ResetNumberOfImageComputation(Img_Forward_c); 03287 03288 reached = ALLOC(mdd_t *, n); 03289 constraint = ALLOC(mdd_t *, n); 03290 newConstraint = ALLOC(mdd_t *, n); 03291 subFsm = ALLOC(Fsm_Fsm_t *, n); 03292 pi_to = array_alloc(mdd_t *, 0); 03293 to = ALLOC(mdd_t *, n); 03294 array_insert_last(mdd_t **, pi_to, to); 03295 03296 mddManager = Fsm_FsmReadMddManager(fsm); 03297 for (i = 0; i < n; i++) { 03298 subFsm[i] = array_fetch(Fsm_Fsm_t *, subFsmArray, i); 03299 initialStates = Fsm_FsmComputeInitialStates(subFsm[i]); 03300 reached[i] = initialStates; 03301 constraint[i] = mdd_dup(initialStates); 03302 to[i] = mdd_zero(mddManager); 03303 03304 if (printStep && ((depth % printStep) == 0)) { 03305 if (ardcVerbosity > 1) 03306 fprintf(vis_stdout, "--- sub fsm [%d] ---\n", i); 03307 (void)fprintf(vis_stdout, 03308 "BFS step = %d\t|states| = %8g\tBdd size = %8ld\n", depth, 03309 mdd_count_onset(mddManager, reached[i], 03310 subFsm[i]->fsmData.presentStateVars), 03311 (long)mdd_size(reached[i])); 03312 } 03313 } 03314 03315 if (constrainTarget == Fsm_Ardc_Constrain_Initial_c || 03316 constrainTarget == Fsm_Ardc_Constrain_Both_c) { 03317 initial = ALLOC(mdd_t *, n); 03318 for (i = 0; i < n; i++) 03319 initial[i] = Fsm_FsmComputeInitialStates(subFsm[i]); 03320 } 03321 03322 converged = 0; 03323 do { 03324 depth++; 03325 to = ALLOC(mdd_t *, n); 03326 for (i = 0; i < n; i++) { 03327 if (ardcVerbosity > 1) 03328 fprintf(vis_stdout, "--- sub fsm [%d] ---\n", i); 03329 faninConstrainArray = array_alloc(mdd_t *, 0); 03330 fans = array_fetch(array_t *, fanInsIndexArray, i); 03331 ComputeFaninConstrainArray(faninConstrainArray, constraint, 03332 i, fans, decomposeFlag, faninConstrainMode); 03333 dynStatus = bdd_reordering_status(mddManager, &dynMethod); 03334 if (dynStatus != 0 && constrainReorderFlag == 0) 03335 bdd_dynamic_reordering_disable(mddManager); 03336 imageInfo = Fsm_FsmReadOrCreateImageInfo(subFsm[i], 0, 1); 03337 if (constrainTarget != Fsm_Ardc_Constrain_Initial_c) { 03338 int saveStatus = Img_ReadPrintMinimizeStatus(imageInfo); 03339 if (ardcVerbosity > 2) 03340 Img_SetPrintMinimizeStatus(imageInfo, 2); 03341 else if (ardcVerbosity > 0) 03342 Img_SetPrintMinimizeStatus(imageInfo, 1); 03343 else 03344 Img_SetPrintMinimizeStatus(imageInfo, 0); 03345 if (reorderPtrFlag && 03346 abstractPseudoInput != Fsm_Ardc_Abst_Ppi_Before_Image_c) { 03347 tmpReorderPtrFlag = 1; 03348 } else 03349 tmpReorderPtrFlag = 0; 03350 if (ardcVerbosity > 0) 03351 initialTime = util_cpu_time(); 03352 MinimizeTransitionRelationWithFaninConstraint(imageInfo, 03353 faninConstrainArray, constrainMethod, tmpReorderPtrFlag, 03354 TRUE); 03355 if (ardcVerbosity > 0) { 03356 finalTime = util_cpu_time(); 03357 tConstrainOps += finalTime - initialTime; 03358 } 03359 Img_SetPrintMinimizeStatus(imageInfo, saveStatus); 03360 } 03361 if (constrainTarget != Fsm_Ardc_Constrain_Tr_c) { 03362 ComputeConstrainedInitialStates(subFsm[i], faninConstrainArray, 03363 constrainMethod); 03364 } 03365 mdd_array_free(faninConstrainArray); 03366 if (dynStatus != 0 && constrainReorderFlag == 0) { 03367 bdd_dynamic_reordering(mddManager, dynMethod, 03368 BDD_REORDER_VERBOSITY_DEFAULT); 03369 } 03370 if (abstractPseudoInput == Fsm_Ardc_Abst_Ppi_Before_Image_c) { 03371 int saveStatus = Img_ReadPrintMinimizeStatus(imageInfo); 03372 if (ardcVerbosity > 2) 03373 Img_SetPrintMinimizeStatus(imageInfo, 2); 03374 else if (ardcVerbosity > 0) 03375 Img_SetPrintMinimizeStatus(imageInfo, 1); 03376 else 03377 Img_SetPrintMinimizeStatus(imageInfo, 0); 03378 Img_AbstractTransitionRelation(imageInfo, 03379 subFsm[i]->fsmData.pseudoInputBddVars, 03380 subFsm[i]->fsmData.pseudoInputCube, Img_Forward_c); 03381 if (reorderPtrFlag) 03382 Img_ReorderPartitionedTransitionRelation(imageInfo, Img_Forward_c); 03383 Img_SetPrintMinimizeStatus(imageInfo, saveStatus); 03384 } 03385 toCareSet = mdd_not(reached[i]); 03386 array_insert(mdd_t *, toCareSetArray, 0, toCareSet); 03387 if (ardcVerbosity > 0) 03388 initialTime = util_cpu_time(); 03389 to[i] = Fsm_ArdcComputeImage(subFsm[i], constraint[i], 03390 constraint[i], toCareSetArray); 03391 if (Img_ImageInfoObtainMethodType(imageInfo) == Img_Tfm_c || 03392 Img_ImageInfoObtainMethodType(imageInfo) == Img_Hybrid_c) { 03393 Img_TfmFlushCache(imageInfo, FALSE); 03394 } 03395 if (ardcVerbosity > 0) { 03396 finalTime = util_cpu_time(); 03397 tImgComps += finalTime - initialTime; 03398 } 03399 mdd_free(toCareSet); 03400 if (constrainTarget != Fsm_Ardc_Constrain_Initial_c) 03401 Img_RestoreTransitionRelation(imageInfo, Img_Forward_c); 03402 03403 tmp = reached[i]; 03404 reached[i] = mdd_or(reached[i], to[i], 1, 1); 03405 mdd_free(tmp); 03406 if (abstractPseudoInput == Fsm_Ardc_Abst_Ppi_After_Image_c) { 03407 tmp = reached[i]; 03408 reached[i] = QuantifyVariables(reached[i], 03409 subFsm[i]->fsmData.pseudoInputBddVars, 03410 subFsm[i]->fsmData.pseudoInputCube); 03411 mdd_free(tmp); 03412 } 03413 newConstraint[i] = mdd_dup(to[i]); 03414 03415 if (printStep && ((depth % printStep) == 0)) { 03416 (void)fprintf(vis_stdout, 03417 "BFS step = %d\t|states| = %8g\tBdd size = %8ld\n", 03418 depth, mdd_count_onset(mddManager, reached[i], 03419 subFsm[i]->fsmData.presentStateVars), 03420 (long)mdd_size(reached[i])); 03421 } 03422 } 03423 for (i = 0; i < array_n(pi_to); i++) { 03424 old_to = array_fetch(mdd_t **, pi_to, i); 03425 for (j = 0; j < n; j++) { 03426 if (!mdd_equal(old_to[j], to[j])) 03427 break; 03428 } 03429 if (j == n) 03430 break; 03431 } 03432 if (i == array_n(pi_to)) 03433 converged = 0; 03434 else { 03435 converged = 1; 03436 if (ardcVerbosity > 0) { 03437 fprintf(vis_stdout, 03438 "** ardc info : TFBF converged at iteration %d(=%d).\n", 03439 iteration + 1, i); 03440 } 03441 } 03442 iteration++; 03443 if (ardcVerbosity > 0) { 03444 boolean supportCheckFlag = FALSE; 03445 03446 if (projectedInitialFlag || 03447 abstractPseudoInput == Fsm_Ardc_Abst_Ppi_Before_Image_c) { 03448 supportCheckFlag = TRUE; 03449 } 03450 PrintCurrentReachedStates(mddManager, subFsm, reached, 03451 Fsm_Ardc_Traversal_Tfbf_c, 03452 n, iteration, nvars, ardcVerbosity, 03453 supportCheckFlag); 03454 } 03455 03456 /* update constraints */ 03457 for (i = 0; i < n; i++) { 03458 mdd_free(constraint[i]); 03459 constraint[i] = newConstraint[i]; 03460 newConstraint[i] = NIL(mdd_t); 03461 } 03462 03463 if (converged || iteration == maxIteration) { 03464 if (subTo) 03465 *subTo = to; 03466 else { 03467 for (i = 0; i < n; i++) 03468 mdd_free(to[i]); 03469 FREE(to); 03470 } 03471 break; 03472 } 03473 array_insert_last(mdd_t **, pi_to, to); 03474 } while (!converged); 03475 if (ardcVerbosity > 0) { 03476 fprintf(vis_stdout, "TFBF : total iteration %d\n", iteration); 03477 fprintf(vis_stdout, "%d image computations, %d constrain operations\n", 03478 Img_GetNumberOfImageComputation(Img_Forward_c), n * iteration); 03479 fprintf(vis_stdout, 03480 "image computation time = %g, constrain operation time = %g\n", 03481 (double)tImgComps / 1000.0, (double)tConstrainOps / 1000.0); 03482 } 03483 03484 if (constrainTarget == Fsm_Ardc_Constrain_Initial_c || 03485 constrainTarget == Fsm_Ardc_Constrain_Both_c) { 03486 for (i = 0; i < n; i++) { 03487 mdd_free(subFsm[i]->reachabilityInfo.initialStates); 03488 subFsm[i]->reachabilityInfo.initialStates = initial[i]; 03489 } 03490 FREE(initial); 03491 } 03492 03493 if (abstractPseudoInput == Fsm_Ardc_Abst_Ppi_At_End_c) { 03494 for (i = 0; i < n; i++) { 03495 tmp = reached[i]; 03496 reached[i] = QuantifyVariables(reached[i], 03497 subFsm[i]->fsmData.pseudoInputBddVars, 03498 subFsm[i]->fsmData.pseudoInputCube); 03499 mdd_free(tmp); 03500 } 03501 } 03502 03503 /* sets the status of current overapproximate reached states */ 03504 if (converged) 03505 FsmSetReachabilityOverApproxComputationStatus(fsm, Fsm_Ardc_Converged_c); 03506 else 03507 FsmSetReachabilityOverApproxComputationStatus(fsm, Fsm_Ardc_NotConverged_c); 03508 03509 ComputeApproximateReachableStatesArray(mddManager, reachedArray, 03510 reached, subReached, n, decomposeFlag); 03511 if (decomposeFlag) { 03512 for (i = 0; i < n; i++) { 03513 mdd_free(constraint[i]); 03514 } 03515 } else { 03516 for (i = 0; i < n; i++) { 03517 if (subReached == NULL) 03518 mdd_free(reached[i]); 03519 mdd_free(constraint[i]); 03520 } 03521 } 03522 03523 if (subReached) 03524 *subReached = reached; 03525 else 03526 FREE(reached); 03527 FREE(constraint); 03528 FREE(newConstraint); 03529 FREE(subFsm); 03530 for (i = 0; i < array_n(pi_to); i++) { 03531 to = array_fetch(mdd_t **, pi_to, i); 03532 for (j = 0; j < n; j++) 03533 mdd_free(to[j]); 03534 FREE(to); 03535 } 03536 array_free(pi_to); 03537 array_free(toCareSetArray); 03538 03539 return(reachedArray); 03540 } 03541 03542 03559 static array_t * 03560 ArdcTmbmTraversal( 03561 Fsm_Fsm_t *fsm, 03562 int nvars, 03563 array_t *subFsmArray, 03564 array_t *fanInsIndexArray, 03565 array_t *fanOutsIndexArray, 03566 int incrementalFlag, 03567 int verbosityLevel, 03568 int printStep, 03569 int depthValue, 03570 int shellFlag, 03571 int reorderFlag, 03572 int reorderThreshold, 03573 Fsm_RchType_t approxFlag, 03574 Fsm_ArdcOptions_t *options, 03575 boolean lfpFlag) 03576 { 03577 mdd_manager *mddManager; 03578 int i, n = array_n(subFsmArray); 03579 mdd_t **reached, **tfbf_reached; 03580 mdd_t **to, **initial; 03581 Fsm_Fsm_t *subFsm = NIL(Fsm_Fsm_t); 03582 mdd_t *tmp; 03583 array_t *reachedArray; 03584 int saveMaxIteration; 03585 03586 saveMaxIteration = options->maxIteration; 03587 if (options->maxIteration == 0) 03588 options->maxIteration = 10; /* default */ 03589 03590 /* Try TFBF for the presecribed number of steps. */ 03591 reachedArray = ArdcTfbfTraversal(fsm, nvars, subFsmArray, fanInsIndexArray, 03592 &tfbf_reached, &to, 03593 incrementalFlag, verbosityLevel, printStep, 03594 depthValue, shellFlag, reorderFlag, 03595 reorderThreshold, approxFlag, options); 03596 03597 /* If TFBF converged in the allotted number of iterations, clean up and 03598 * return. */ 03599 if (FsmReadReachabilityOverApproxComputationStatus(fsm) >= 03600 Fsm_Ardc_Converged_c) { 03601 for (i = 0; i < n; i++) { 03602 mdd_free(tfbf_reached[i]); 03603 mdd_free(to[i]); 03604 } 03605 FREE(tfbf_reached); 03606 FREE(to); 03607 return(reachedArray); 03608 } 03609 03610 mdd_array_free(reachedArray); 03611 03612 /* Save the initial states of each submachine in "initial"; thenset it 03613 * to the "to" states returned by TFBF. */ 03614 initial = ALLOC(mdd_t *, n); 03615 for (i = 0; i < n; i++) { 03616 subFsm = array_fetch(Fsm_Fsm_t *, subFsmArray, i); 03617 initial[i] = subFsm->reachabilityInfo.initialStates; 03618 subFsm->reachabilityInfo.initialStates = mdd_dup(to[i]); 03619 } 03620 03621 /* Apply either MBM or LMBM starting from the "to" states returned by 03622 * TFBF. */ 03623 options->maxIteration = 0; 03624 reachedArray = ArdcMbmTraversal(fsm, nvars, subFsmArray, 03625 fanInsIndexArray, fanOutsIndexArray, &reached, 03626 incrementalFlag, verbosityLevel, printStep, 03627 depthValue, shellFlag, reorderFlag, reorderThreshold, 03628 approxFlag, options, lfpFlag); 03629 options->maxIteration = saveMaxIteration; 03630 03631 mdd_array_free(reachedArray); 03632 03633 /* Combine the reachability results of TFBF and (L)MBM and restore 03634 * the initial states of the submachines. */ 03635 for (i = 0; i < n; i++) { 03636 tmp = reached[i]; 03637 reached[i] = mdd_or(tfbf_reached[i], reached[i], 1, 1); 03638 mdd_free(tmp); 03639 subFsm = array_fetch(Fsm_Fsm_t *, subFsmArray, i); 03640 mdd_free(subFsm->reachabilityInfo.initialStates); 03641 subFsm->reachabilityInfo.initialStates = initial[i]; 03642 } 03643 03644 /* Build the array of reachable states in either monolithic or decomposed 03645 * form depending on the value of decomposeFlag. */ 03646 reachedArray = array_alloc(mdd_t *, 0); 03647 mddManager = Fsm_FsmReadMddManager(subFsm); 03648 ComputeApproximateReachableStatesArray(mddManager, reachedArray, 03649 reached, NULL, n, 03650 options->decomposeFlag); 03651 if (!options->decomposeFlag) { 03652 for (i = 0; i < n; i++) 03653 mdd_free(reached[i]); 03654 } 03655 03656 /* Clean up. */ 03657 for (i = 0; i < n; i++) { 03658 mdd_free(tfbf_reached[i]); 03659 mdd_free(to[i]); 03660 } 03661 03662 FREE(reached); 03663 FREE(tfbf_reached); 03664 FREE(to); 03665 FREE(initial); 03666 03667 return(reachedArray); 03668 } 03669 03670 03684 static array_t * 03685 ArdcSimpleTraversal(Fsm_Fsm_t *fsm, int nvars, array_t *subFsmArray, 03686 int incrementalFlag, int verbosityLevel, 03687 int printStep, int depthValue, int shellFlag, 03688 int reorderFlag, int reorderThreshold, 03689 Fsm_RchType_t approxFlag, Fsm_ArdcOptions_t *options, 03690 int setFlag) 03691 { 03692 mdd_manager *mddManager; 03693 int i, n = array_n(subFsmArray); 03694 mdd_t **reached; 03695 Fsm_Fsm_t **subFsm; 03696 mdd_t *tmp; 03697 array_t *reachedArray = array_alloc(mdd_t *, 0); 03698 Img_ImageInfo_t *imageInfo = NIL(Img_ImageInfo_t); 03699 boolean decomposeFlag = options->decomposeFlag; 03700 int abstractPseudoInput = options->abstractPseudoInput; 03701 boolean projectedInitialFlag = options->projectedInitialFlag; 03702 int ardcVerbosity = options->verbosity; 03703 03704 reached = ALLOC(mdd_t *, n); 03705 subFsm = ALLOC(Fsm_Fsm_t *, n); 03706 03707 for (i = 0; i < n; i++) 03708 subFsm[i] = array_fetch(Fsm_Fsm_t *, subFsmArray, i); 03709 03710 mddManager = Fsm_FsmReadMddManager(subFsm[0]); 03711 for (i = 0; i < n; i++) { 03712 if (printStep && ardcVerbosity > 1) 03713 fprintf(vis_stdout, "--- sub fsm [%d] ---\n", i); 03714 if (abstractPseudoInput == Fsm_Ardc_Abst_Ppi_Before_Image_c) { 03715 int saveStatus = Img_ReadPrintMinimizeStatus(imageInfo); 03716 if (ardcVerbosity > 2) 03717 Img_SetPrintMinimizeStatus(imageInfo, 2); 03718 else if (ardcVerbosity > 0) 03719 Img_SetPrintMinimizeStatus(imageInfo, 1); 03720 else 03721 Img_SetPrintMinimizeStatus(imageInfo, 0); 03722 imageInfo = Fsm_FsmReadOrCreateImageInfo(subFsm[i], 0, 1); 03723 Img_AbstractTransitionRelation(imageInfo, 03724 subFsm[i]->fsmData.pseudoInputBddVars, 03725 subFsm[i]->fsmData.pseudoInputCube, 03726 Img_Forward_c); 03727 Img_SetPrintMinimizeStatus(imageInfo, saveStatus); 03728 } 03729 reached[i] = Fsm_FsmComputeReachableStates(subFsm[i], 03730 incrementalFlag, verbosityLevel, printStep, depthValue, 03731 shellFlag, reorderFlag, reorderThreshold, 03732 approxFlag, 0, 0, NIL(array_t), FALSE, NIL(array_t)); 03733 if (Img_ImageInfoObtainMethodType(imageInfo) == Img_Tfm_c || 03734 Img_ImageInfoObtainMethodType(imageInfo) == Img_Hybrid_c) { 03735 Img_TfmFlushCache(imageInfo, FALSE); 03736 } 03737 if (abstractPseudoInput == Fsm_Ardc_Abst_Ppi_After_Image_c) { 03738 if (n > 1) { 03739 tmp = reached[i]; 03740 reached[i] = QuantifyVariables(reached[i], 03741 subFsm[i]->fsmData.pseudoInputBddVars, 03742 subFsm[i]->fsmData.pseudoInputCube); 03743 mdd_free(tmp); 03744 } 03745 } 03746 } 03747 03748 if (ardcVerbosity > 0) { 03749 boolean supportCheckFlag = FALSE; 03750 03751 if (projectedInitialFlag || 03752 abstractPseudoInput == Fsm_Ardc_Abst_Ppi_Before_Image_c) { 03753 supportCheckFlag = TRUE; 03754 } 03755 PrintCurrentReachedStates(mddManager, subFsm, reached, 03756 Fsm_Ardc_Traversal_Simple_c, 03757 n, 0, nvars, ardcVerbosity, 03758 supportCheckFlag); 03759 } 03760 03761 if (abstractPseudoInput == Fsm_Ardc_Abst_Ppi_At_End_c) { 03762 for (i = 0; i < n; i++) { 03763 tmp = reached[i]; 03764 reached[i] = QuantifyVariables(reached[i], 03765 subFsm[i]->fsmData.pseudoInputBddVars, 03766 subFsm[i]->fsmData.pseudoInputCube); 03767 mdd_free(tmp); 03768 } 03769 } 03770 03771 /* sets the status of current overapproximate reached states */ 03772 if (setFlag) 03773 FsmSetReachabilityOverApproxComputationStatus(fsm, Fsm_Ardc_Converged_c); 03774 03775 ComputeApproximateReachableStatesArray(mddManager, reachedArray, 03776 reached, NULL, n, decomposeFlag); 03777 03778 FREE(reached); 03779 FREE(subFsm); 03780 03781 return(reachedArray); 03782 } 03783 03784 03798 static void 03799 ComputeFaninConstrainArray(array_t *faninConstrainArray, mdd_t **constraint, 03800 int current, array_t *fans, 03801 int decomposeFlag, int faninConstrainMode) 03802 { 03803 mdd_t *faninConstrain, *tmp; 03804 int i, fanin; 03805 03806 if (decomposeFlag) { 03807 if (faninConstrainMode == 1) { 03808 array_insert_last(mdd_t *, faninConstrainArray, 03809 mdd_dup(constraint[current])); 03810 } 03811 arrayForEachItem(int, fans, i, fanin) { 03812 array_insert_last(mdd_t *, faninConstrainArray, 03813 mdd_dup(constraint[fanin])); 03814 } 03815 } else { 03816 if (faninConstrainMode == 1) 03817 faninConstrain = mdd_dup(constraint[current]); 03818 else 03819 faninConstrain = NIL(mdd_t); 03820 arrayForEachItem(int, fans, i, fanin) { 03821 if (faninConstrain) { 03822 tmp = faninConstrain; 03823 faninConstrain = mdd_and(faninConstrain, constraint[fanin], 1, 1); 03824 mdd_free(tmp); 03825 } else 03826 faninConstrain = mdd_dup(constraint[fanin]); 03827 } 03828 array_insert_last(mdd_t *, faninConstrainArray, faninConstrain); 03829 } 03830 } 03831 03832 03844 static void 03845 MinimizeTransitionRelationWithFaninConstraint(Img_ImageInfo_t *imageInfo, 03846 array_t *faninConstrainArray, 03847 Img_MinimizeType constrainMethod, 03848 boolean reorderPtrFlag, 03849 boolean duplicate) 03850 { 03851 if (duplicate) { 03852 Img_DupTransitionRelation(imageInfo, Img_Forward_c); 03853 Img_ResetTrMinimizedFlag(imageInfo, Img_Forward_c); 03854 } 03855 Img_MinimizeTransitionRelation(imageInfo, faninConstrainArray, 03856 constrainMethod, Img_Forward_c, 03857 reorderPtrFlag); 03858 } 03859 03860 03873 static void 03874 ComputeConstrainedInitialStates(Fsm_Fsm_t *subFsm, 03875 array_t *faninConstrainArray, 03876 Img_MinimizeType constrainMethod) 03877 { 03878 int i; 03879 mdd_t *faninConstrain, *tmp, *constrainedInitial; 03880 03881 constrainedInitial = subFsm->reachabilityInfo.initialStates; 03882 for (i = 0; i < array_n(faninConstrainArray); i++) { 03883 faninConstrain = array_fetch(mdd_t *, faninConstrainArray, i); 03884 tmp = constrainedInitial; 03885 constrainedInitial = Img_MinimizeImage(constrainedInitial, 03886 faninConstrain, constrainMethod, 03887 TRUE); 03888 mdd_free(tmp); 03889 } 03890 subFsm->reachabilityInfo.initialStates = constrainedInitial; 03891 } 03892 03893 03905 static void 03906 ComputeApproximateReachableStatesArray(mdd_manager *mddManager, 03907 array_t *reachedArray, 03908 mdd_t **reached, 03909 mdd_t ***subReached, 03910 int nSubFsms, 03911 int decomposeFlag) 03912 { 03913 int i; 03914 03915 if (decomposeFlag) { 03916 for (i = 0; i < nSubFsms; i++) { 03917 if (subReached) 03918 array_insert_last(mdd_t *, reachedArray, mdd_dup(reached[i])); 03919 else 03920 array_insert_last(mdd_t *, reachedArray, reached[i]); 03921 } 03922 } else { 03923 mdd_t *reachedSet = mdd_one(mddManager); 03924 for (i = 0; i < nSubFsms; i++) { 03925 mdd_t *tmp = reachedSet; 03926 reachedSet = mdd_and(reachedSet, reached[i], 1, 1); 03927 mdd_free(tmp); 03928 } 03929 array_insert_last(mdd_t *, reachedArray, reachedSet); 03930 } 03931 } 03932 03933 03945 static array_t * 03946 ArdcCopyOverApproxReachableStatesFromExact(Fsm_Fsm_t *fsm) 03947 { 03948 array_t *reachableStatesArray; 03949 03950 if (Fsm_FsmReadReachableStates(fsm) == NIL(mdd_t)) 03951 return(NIL(array_t)); 03952 03953 reachableStatesArray = array_alloc(mdd_t *, 0); 03954 array_insert_last(mdd_t *, reachableStatesArray, 03955 mdd_dup(Fsm_FsmReadReachableStates(fsm))); 03956 FsmSetReachabilityOverApproxComputationStatus(fsm, Fsm_Ardc_Exact_c); 03957 fsm->reachabilityInfo.apprReachableStates = reachableStatesArray; 03958 fsm->reachabilityInfo.subPsVars = array_alloc(array_t *, 0); 03959 array_insert_last(array_t *, fsm->reachabilityInfo.subPsVars, 03960 array_dup(fsm->fsmData.presentStateVars)); 03961 return(reachableStatesArray); 03962 } 03963 03964 03976 static void 03977 PrintCurrentReachedStates(mdd_manager *mddManager, Fsm_Fsm_t **subFsm, 03978 mdd_t **reached, Fsm_Ardc_TraversalType_t method, 03979 int nSubFsms, int iteration, int nvars, 03980 int ardcVerbosity, boolean supportCheckFlag) 03981 { 03982 int i; 03983 char string[24]; 03984 double tmpReached; 03985 03986 if (nvars <= EPD_MAX_BIN) { 03987 double numReached = 1.0, tmpReached; 03988 03989 for (i = 0; i < nSubFsms; i++) { 03990 tmpReached = mdd_count_onset(mddManager, reached[i], 03991 subFsm[i]->fsmData.presentStateVars); 03992 if (ardcVerbosity > 1) { 03993 if (ardcVerbosity > 2 && supportCheckFlag) { 03994 assert(mdd_check_support(mddManager, reached[i], 03995 subFsm[i]->fsmData.presentStateVars)); 03996 } 03997 fprintf(vis_stdout, "# of reached for subFsm[%d] = %g\n", 03998 i, tmpReached); 03999 } 04000 numReached *= tmpReached; 04001 } 04002 sprintf(string, "%g", numReached); 04003 } else { 04004 EpDouble epd; 04005 04006 EpdConvert((double)1.0, &epd); 04007 04008 for (i = 0; i < nSubFsms; i++) { 04009 tmpReached = mdd_count_onset(mddManager, reached[i], 04010 subFsm[i]->fsmData.presentStateVars); 04011 if (ardcVerbosity > 1) { 04012 if (ardcVerbosity > 2 && supportCheckFlag) { 04013 assert(mdd_check_support(mddManager, reached[i], 04014 subFsm[i]->fsmData.presentStateVars)); 04015 } 04016 fprintf(vis_stdout, "# of reached for subFsm[%d] = %g\n", 04017 i, tmpReached); 04018 } 04019 EpdMultiply(&epd, tmpReached); 04020 } 04021 EpdGetString(&epd, string); 04022 } 04023 04024 switch (method) { 04025 case Fsm_Ardc_Traversal_Mbm_c : 04026 fprintf(vis_stdout, "MBM : iteration %d, # of reached = %s\n", 04027 iteration, string); 04028 break; 04029 case Fsm_Ardc_Traversal_Rfbf_c : 04030 fprintf(vis_stdout, "RFBF : iteration %d, # of reached = %s\n", 04031 iteration, string); 04032 break; 04033 case Fsm_Ardc_Traversal_Tfbf_c : 04034 fprintf(vis_stdout, "TFBF : iteration %d, # of reached = %s\n", 04035 iteration, string); 04036 break; 04037 case Fsm_Ardc_Traversal_Tmbm_c : 04038 fprintf(vis_stdout, "TMBM : iteration %d, # of reached = %s\n", 04039 iteration, string); 04040 break; 04041 case Fsm_Ardc_Traversal_Lmbm_c : 04042 fprintf(vis_stdout, "LMBM : iteration %d, # of reached = %s\n", 04043 iteration, string); 04044 break; 04045 case Fsm_Ardc_Traversal_Tlmbm_c : 04046 fprintf(vis_stdout, "TLMBM : iteration %d, # of reached = %s\n", 04047 iteration, string); 04048 break; 04049 case Fsm_Ardc_Traversal_Simple_c : 04050 fprintf(vis_stdout, "SIMPLE : # of reached = %s\n", string); 04051 break; 04052 default : 04053 break; 04054 } 04055 } 04056 04057 04069 static void 04070 PrintBddWithName(Fsm_Fsm_t *fsm, array_t *mddIdArr, mdd_t *node) 04071 { 04072 int i, j, size; 04073 mdd_manager *mddManager; 04074 array_t *mvarArray; 04075 mvar_type mv; 04076 int bddId, mddId, varLevel; 04077 bdd_t *varBdd; 04078 04079 if (!node) 04080 return; 04081 04082 mddManager = Fsm_FsmReadMddManager(fsm); 04083 if (!mddIdArr) 04084 mddIdArr = mdd_get_support(mddManager, node); 04085 mvarArray = mdd_ret_mvar_list(mddManager); 04086 04087 size = array_n(mddIdArr); 04088 for (i = 0; i < size; i++) { 04089 mddId = array_fetch(int, mddIdArr, i); 04090 mv = array_fetch(mvar_type, mvarArray, mddId); 04091 for (j = 0; j < mv.encode_length; j++) { 04092 bddId = mdd_ret_bvar_id(&mv, j); 04093 varBdd = bdd_get_variable(mddManager, bddId); 04094 varLevel = bdd_top_var_level(mddManager, varBdd); 04095 if (mv.encode_length == 1) 04096 fprintf(vis_stdout, "%s %d\n", mv.name, varLevel); 04097 else 04098 fprintf(vis_stdout, "%s[%d] %d\n", mv.name, j, varLevel); 04099 bdd_free(varBdd); 04100 } 04101 } 04102 bdd_print_minterm(node); 04103 } 04104 04105 04117 static void 04118 ArdcReadGroup(Ntk_Network_t *network, FILE *groupFile, 04119 array_t *latchNameArray, array_t *groupIndexArray) 04120 { 04121 char line[ARDC_MAX_LINE_LEN]; 04122 char *latchName, *name, *group; 04123 int groupIndex = 0; 04124 04125 while (fgets(line, ARDC_MAX_LINE_LEN, groupFile)) { 04126 if (strlen(line) == 0) 04127 continue; 04128 if (line[0] == '#') 04129 continue; 04130 if (line[strlen(line) - 1] == '\n') 04131 line[strlen(line) - 1] = '\0'; 04132 group = strtok(line, " "); 04133 if (strncmp(group, "GROUP[", 6) == 0) 04134 sscanf(group, "GROUP[%d]:", &groupIndex); 04135 else { 04136 latchName = util_strsav(group); 04137 array_insert_last(char *, latchNameArray, latchName); 04138 array_insert_last(int, groupIndexArray, groupIndex); 04139 } 04140 while ((name = strtok(NIL(char), " \t")) != NIL(char)) { 04141 latchName = util_strsav(name); 04142 array_insert_last(char *, latchNameArray, latchName); 04143 array_insert_last(int, groupIndexArray, groupIndex); 04144 } 04145 } 04146 } 04147 04148 04160 static void 04161 ArdcWriteOneGroup(Part_Subsystem_t *partitionSubsystem, FILE *groupFile, int i) 04162 { 04163 st_generator *stGen; 04164 st_table *vertexNameTable; 04165 char *latchName; 04166 04167 fprintf(groupFile, "GROUP[%d]:", i); 04168 vertexNameTable = Part_PartitionSubsystemReadVertexTable(partitionSubsystem); 04169 st_foreach_item(vertexNameTable, stGen, &latchName, NIL(char *)) { 04170 fprintf(groupFile, " %s", latchName); 04171 } 04172 fprintf(groupFile, "\n"); 04173 } 04174 04175 04187 static void 04188 ArdcPrintOneGroup(Part_Subsystem_t *partitionSubsystem, int i, int nLatches, 04189 array_t *fanIns, array_t *fanOuts) 04190 { 04191 int j, k; 04192 st_generator *stGen; 04193 st_table *vertexNameTable; 04194 char *latchName; 04195 04196 fprintf(vis_stdout, "SUB-FSM [%d]\n", i); 04197 fprintf(vis_stdout, "== latches(%d) :", nLatches); 04198 vertexNameTable = Part_PartitionSubsystemReadVertexTable(partitionSubsystem); 04199 st_foreach_item(vertexNameTable, stGen, &latchName, NIL(char *)) { 04200 fprintf(vis_stdout, " %s", latchName); 04201 } 04202 fprintf(vis_stdout, "\n"); 04203 fprintf(vis_stdout, "== fanins(%d) :", array_n(fanIns)); 04204 for (j = 0; j < array_n(fanIns); j++) { 04205 k = array_fetch(int, fanIns, j); 04206 fprintf(vis_stdout, " %d", k); 04207 } 04208 fprintf(vis_stdout, "\n"); 04209 fprintf(vis_stdout, "== fanouts(%d) :", array_n(fanOuts)); 04210 for (j = 0; j < array_n(fanOuts); j++) { 04211 k = array_fetch(int, fanOuts, j); 04212 fprintf(vis_stdout, " %d", k); 04213 } 04214 fprintf(vis_stdout, "\n"); 04215 } 04216 04217 04229 static int 04230 GetArdcSetIntValue(char *string, int l, int u, int defaultValue) 04231 { 04232 char *flagValue; 04233 int tmp; 04234 int value = defaultValue; 04235 04236 flagValue = Cmd_FlagReadByName(string); 04237 if (flagValue != NIL(char)) { 04238 sscanf(flagValue, "%d", &tmp); 04239 if (tmp >= l && (tmp <= u || u == 0)) 04240 value = tmp; 04241 else { 04242 fprintf(vis_stderr, 04243 "** ardc error : invalid value %d for %s[%d-%d]. **\n", tmp, string, 04244 l, u); 04245 } 04246 } 04247 04248 return(value); 04249 } 04250 04251 04263 static void 04264 ArdcEpdCountOnsetOfOverApproximateReachableStates(Fsm_Fsm_t *fsm, EpDouble *epd) 04265 { 04266 mdd_t *reached; 04267 array_t *psVars, *reachedArray; 04268 mdd_manager *mddManager = Fsm_FsmReadMddManager(fsm); 04269 double tmpReached; 04270 int i; 04271 04272 EpdMakeZero(epd, 0); 04273 04274 if (!Fsm_FsmReadCurrentOverApproximateReachableStates(fsm)) 04275 return; 04276 04277 EpdConvert((double)1.0, epd); 04278 reachedArray = Fsm_FsmReadCurrentOverApproximateReachableStates(fsm); 04279 arrayForEachItem(mdd_t *, reachedArray, i, reached) { 04280 psVars = array_fetch(array_t *, fsm->reachabilityInfo.subPsVars, i); 04281 tmpReached = mdd_count_onset(mddManager, reached, psVars); 04282 EpdMultiply(epd, tmpReached); 04283 } 04284 } 04285 04286 04300 static mdd_t * 04301 QuantifyVariables(mdd_t *state, array_t *smoothArray, mdd_t *smoothCube) 04302 { 04303 if (smoothCube) 04304 return(bdd_smooth_with_cube(state, smoothCube)); 04305 else 04306 return(bdd_smooth(state, smoothArray)); 04307 } 04308 04309 04321 static void 04322 UpdateMbmEventSchedule(Fsm_Fsm_t **subFsm, array_t *fanOutIndices, 04323 int *traverse, int lfpFlag) 04324 { 04325 int i, fanout; 04326 04327 arrayForEachItem(int, fanOutIndices, i, fanout) { 04328 if (lfpFlag) { 04329 if (!subFsm[fanout]->reachabilityInfo.reachableStates || 04330 !bdd_is_tautology(subFsm[fanout]->reachabilityInfo.reachableStates, 04331 1)) { 04332 traverse[fanout] = 1; 04333 } 04334 } else 04335 traverse[fanout] = 1; 04336 } 04337 } 04338 04339 04351 static void 04352 PrintTfmStatistics(array_t *subFsmArray) 04353 { 04354 int i; 04355 Img_ImageInfo_t *imageInfo; 04356 Fsm_Fsm_t *subFsm; 04357 double tInserts, tLookups, tHits, tEntries; 04358 double inserts, lookups, hits, entries; 04359 int nSlots, tSlots, maxChainLength; 04360 float avgDepth, tAvgDepth, avgDecomp, tAvgDecomp; 04361 int tRecurs, tLeaves, tTurns, tDecomps, minDecomp; 04362 int nRecurs, nLeaves, nTurns; 04363 int nDecomps, topDecomp, maxDecomp, tMaxDecomp; 04364 int maxDepth, tMaxDepth; 04365 int flag, globalCache; 04366 04367 tInserts = tLookups = tHits = tEntries = 0.0; 04368 tSlots = 0; 04369 tRecurs = tLeaves = tTurns = tDecomps = 0; 04370 tAvgDepth = tAvgDecomp = 0.0; 04371 tMaxDecomp = tMaxDepth = 0; 04372 minDecomp = 10000000; /* arbitrarily large number */ 04373 04374 globalCache = Img_TfmCheckGlobalCache(0); 04375 if (globalCache) { 04376 flag = Img_TfmGetCacheStatistics(NIL(Img_ImageInfo_t), 0, &inserts, 04377 &lookups, &hits, &entries, &nSlots, 04378 &maxChainLength); 04379 tInserts = inserts; 04380 tLookups = lookups; 04381 tHits = hits; 04382 tEntries = entries; 04383 tSlots = nSlots; 04384 } 04385 04386 for (i = 0; i < array_n(subFsmArray); i++) { 04387 subFsm = array_fetch(Fsm_Fsm_t *, subFsmArray, i); 04388 imageInfo = Fsm_FsmReadOrCreateImageInfo(subFsm, 0, 1); 04389 04390 if (!globalCache) { 04391 flag = Img_TfmGetCacheStatistics(imageInfo, 0, &inserts, &lookups, &hits, 04392 &entries, &nSlots, &maxChainLength); 04393 if (flag) { 04394 tInserts += inserts; 04395 tLookups += lookups; 04396 tHits += hits; 04397 tEntries += entries; 04398 tSlots += nSlots; 04399 } 04400 } 04401 04402 flag = Img_TfmGetRecursionStatistics(imageInfo, 0, &nRecurs, &nLeaves, 04403 &nTurns, &avgDepth, &maxDepth, &nDecomps, 04404 &topDecomp, &maxDecomp, &avgDecomp); 04405 if (flag) { 04406 tAvgDepth = (tAvgDepth * (float)tLeaves + avgDepth * (float)nLeaves) / 04407 (float)(tLeaves + nLeaves); 04408 tRecurs += nRecurs; 04409 tLeaves += nLeaves; 04410 tTurns += nTurns; 04411 tAvgDecomp = (tAvgDecomp * (float)tDecomps + 04412 avgDecomp * (float)nDecomps) / (float)(tDecomps + nDecomps); 04413 tDecomps += nDecomps; 04414 if (topDecomp < minDecomp) 04415 minDecomp = topDecomp; 04416 if (maxDecomp > tMaxDecomp) 04417 tMaxDecomp = maxDecomp; 04418 if (maxDepth > tMaxDepth) 04419 tMaxDepth = maxDepth; 04420 } 04421 } 04422 04423 if (tInserts != 0.0) { 04424 if (globalCache) { 04425 fprintf(vis_stdout, 04426 "** global cache statistics of transition function **\n"); 04427 } else 04428 fprintf(vis_stdout, "** cache statistics of transition function **\n"); 04429 fprintf(vis_stdout, "# insertions = %g\n", tInserts); 04430 fprintf(vis_stdout, "# lookups = %g\n", tLookups); 04431 fprintf(vis_stdout, "# hits = %g (%.2f%%)\n", tHits, 04432 tHits / tLookups * 100.0); 04433 fprintf(vis_stdout, "# misses = %g (%.2f%%)\n", tLookups - tHits, 04434 (tLookups - tHits) / tLookups * 100.0); 04435 fprintf(vis_stdout, "# entries = %g\n", tEntries); 04436 if (tSlots > 0) { 04437 fprintf(vis_stdout, "# slots = %d\n", tSlots); 04438 fprintf(vis_stdout, "maxChainLength = %d\n", maxChainLength); 04439 } 04440 } 04441 04442 if (tRecurs != 0) { 04443 fprintf(vis_stdout, "** recursion statistics of transition function **\n"); 04444 fprintf(vis_stdout, "# recursions = %d\n", tRecurs); 04445 fprintf(vis_stdout, "# leaves = %d\n", tLeaves); 04446 fprintf(vis_stdout, "# turns = %d\n", tTurns); 04447 fprintf(vis_stdout, "# average recursion depth = %g (max = %d)\n", 04448 tAvgDepth, tMaxDepth); 04449 fprintf(vis_stdout, 04450 "# decompositions = %d (top = %d, max = %d, average = %g)\n", 04451 tDecomps, minDecomp, tMaxDecomp, tAvgDecomp); 04452 } 04453 }