VIS
|
00001 00017 #include "amcInt.h" 00018 #include "mcInt.h" 00019 00020 static char rcsid[] UNUSED = "$Id: amcAmc.c,v 1.57 2005/04/16 04:22:41 fabio Exp $"; 00021 00022 /*---------------------------------------------------------------------------*/ 00023 /* Constant declarations */ 00024 /*---------------------------------------------------------------------------*/ 00025 00026 00027 /*---------------------------------------------------------------------------*/ 00028 /* Type declarations */ 00029 /*---------------------------------------------------------------------------*/ 00030 00031 00032 /*---------------------------------------------------------------------------*/ 00033 /* Structure declarations */ 00034 /*---------------------------------------------------------------------------*/ 00035 00036 00037 /*---------------------------------------------------------------------------*/ 00038 /* Variable declarations */ 00039 /*---------------------------------------------------------------------------*/ 00040 00041 00042 /*---------------------------------------------------------------------------*/ 00043 /* Macro declarations */ 00044 /*---------------------------------------------------------------------------*/ 00045 00046 00049 /*---------------------------------------------------------------------------*/ 00050 /* Static function prototypes */ 00051 /*---------------------------------------------------------------------------*/ 00052 static int stringCompare(const void *s1, const void *s2); 00053 00057 /*---------------------------------------------------------------------------*/ 00058 /* Definition of exported functions */ 00059 /*---------------------------------------------------------------------------*/ 00060 00093 void 00094 Amc_AmcEvaluateFormula( 00095 Ntk_Network_t *network, 00096 Ctlp_Formula_t *formula, 00097 int verbosity) 00098 { 00099 Amc_Info_t *amcInfo; 00100 int levelOfLattice; 00101 char *flagValue; 00102 00103 long initialTime = 0; 00104 long finalTime; 00105 00106 00107 /* 00108 * If the partition was not created, get out. We are assuming we were able to 00109 * construct BDD for each combinational outputs. 00110 */ 00111 00112 graph_t *partition = Part_NetworkReadPartition(network); 00113 if (partition == NIL(graph_t)) { 00114 error_append("** amc error: Network has no partition. Cannot apply approximate model checking."); 00115 return; 00116 } 00117 00118 00119 /* 00120 * Initialize data structures. 00121 */ 00122 amcInfo = Amc_AmcInfoInitialize(network, formula, Amc_Default_c, verbosity); 00123 00124 00125 00126 /* 00127 * Check every possible environment variables that user may have set. 00128 * And give user some assurance by reporting the flag values. 00129 * Explanation of possible environment variables are discussed in the 00130 * man page of the package. 00131 */ 00132 amcInfo->isMBM = 0; 00133 00134 flagValue = Cmd_FlagReadByName("amc_prove_false"); 00135 if (flagValue == NIL(char)){ 00136 amcInfo->lowerBound = 0; 00137 fprintf(vis_stdout, "\n#AMC: Proving whether the formula is true.\n"); 00138 } 00139 else { 00140 amcInfo->lowerBound = 1; 00141 fprintf(vis_stdout, "\n#AMC: Proving whether the formula is false.\n"); 00142 } 00143 00144 if(verbosity) { 00145 flagValue = Cmd_FlagReadByName("amc_grouping_method"); 00146 if (flagValue == NIL(char)){ 00147 amcInfo->groupingMethod = 0; 00148 fprintf(vis_stdout, "\n#AMC: No grouping method has been set."); 00149 } 00150 else { 00151 amcInfo->groupingMethod = 1; 00152 fprintf(vis_stdout, "\n#AMC: Using latch dependency method for grouping latches into subsystems."); 00153 } 00154 } 00155 00156 00157 00158 /* 00159 * The lattice of approximation algorithm. 00160 */ 00161 00162 levelOfLattice = array_n(amcInfo->subSystemArray); 00163 amcInfo->currentLevel = 1; 00164 00165 while(levelOfLattice >= amcInfo->currentLevel) { 00166 if(verbosity) { 00167 (void)fprintf(vis_stdout, "\n\n##AMC: Entering level %d(%d) of the lattice of approximations\n", 00168 amcInfo->currentLevel, levelOfLattice); 00169 fflush(vis_stdout); 00170 } 00171 00172 00173 initialTime = util_cpu_time(); 00174 00175 if( (!(*amcInfo->amcBoundProc)(amcInfo, formula, verbosity)) && !(amcInfo->isVerified) ) { 00176 00177 /* Automatically switches to lattice of lowerbound approximations */ 00178 if(verbosity) 00179 (void)fprintf(vis_stdout, "Abandoning upper bound approximations.\n"); 00180 00181 /* Free all */ 00182 (*amcInfo->amcFreeProc)(amcInfo); 00183 00184 amcInfo = Amc_AmcInfoInitialize(network, formula, Amc_Default_c, verbosity); 00185 amcInfo->lowerBound = TRUE; 00186 amcInfo->currentLevel = 0; 00187 00188 } 00189 else if(amcInfo->isVerified) { 00190 finalTime = util_cpu_time(); 00191 if(verbosity == Amc_VerbosityVomit_c) { 00192 (void) fprintf(vis_stdout, "\n%-20s%10ld\n", "analysis time =", 00193 (finalTime - initialTime) / 1000); 00194 } 00195 00196 if(amcInfo->amcAnswer == Amc_Verified_True_c) { 00197 (void) fprintf(vis_stdout, "\n# AMC: Verified formula TRUE at level %d of %d : ", 00198 amcInfo->currentLevel, levelOfLattice); 00199 }else if(amcInfo->amcAnswer == Amc_Verified_False_c) { 00200 (void) fprintf(vis_stdout, "\n# AMC: Verified formula FALSE at level %d of %d : ", 00201 amcInfo->currentLevel, levelOfLattice); 00202 }else{ 00203 fprintf(vis_stdout, "\n# AMC: formula unknown --- "); 00204 Ctlp_FormulaPrint( vis_stdout, Ctlp_FormulaReadOriginalFormula( formula ) ); 00205 (void) fprintf(vis_stdout, "\n# AMC: Verified formula UNKNOWN at level %d of %d : ", 00206 amcInfo->currentLevel, levelOfLattice); 00207 } 00208 (void) fprintf(vis_stdout, "\n# AMC: "); 00209 Ctlp_FormulaPrint( vis_stdout, Ctlp_FormulaReadOriginalFormula( formula ) ); 00210 AmcPrintOptimalSystem(vis_stdout, amcInfo); 00211 (*amcInfo->amcFreeProc)(amcInfo); 00212 return; 00213 } /* end of else if(amcInfo->isVerified) */ 00214 00215 amcInfo->currentLevel++; 00216 } /* end of while(levelOfLattice >= amcInfo->currentLevel) */ 00217 00218 finalTime = util_cpu_time(); 00219 if(verbosity == Amc_VerbosityVomit_c) { 00220 (void) fprintf(vis_stdout, "\n%-20s%10ld\n", "analysis time =", 00221 (finalTime - initialTime) / 1000); 00222 } 00223 00224 /* 00225 ** Now, spec was not verified becase there was an error in computation. 00226 */ 00227 (void) fprintf(vis_stdout, "\n# AMC: The spec was not able to be verified.\n# AMC: "); 00228 Ctlp_FormulaPrint( vis_stdout, Ctlp_FormulaReadOriginalFormula( formula ) ); 00229 (*amcInfo->amcFreeProc)(amcInfo); 00230 00231 } 00232 00233 00251 Amc_Info_t * 00252 Amc_AmcInfoInitialize( 00253 Ntk_Network_t *network, 00254 Ctlp_Formula_t *formula, 00255 Amc_MethodType methodType, 00256 int verbosity) 00257 { 00258 Amc_Info_t *amcInfo; 00259 char *userSpecifiedMethod; 00260 00261 amcInfo = ALLOC(Amc_Info_t, 1); 00262 amcInfo->network = network; 00263 00264 /* 00265 * AmcCreateSubsystems creates fsm for each subsystem and returns subSystemArray. 00266 */ 00267 amcInfo->subSystemArray = AmcCreateSubsystemArray(network, formula); 00268 00269 #ifdef AMC_DEBUG 00270 AmcCheckSupportAndOutputFunctions(amcInfo->subSystemArray); 00271 #endif 00272 00273 /* 00274 * Initialize optimalSystem, isVerified; 00275 */ 00276 amcInfo->optimalSystem = NIL(Amc_SubsystemInfo_t); 00277 amcInfo->isVerified = 0; 00278 amcInfo->amcAnswer = Amc_Verified_Unknown_c; 00279 00280 /* 00281 * If methodType is default, use user-specified method. 00282 */ 00283 if (methodType == Amc_Default_c) { 00284 userSpecifiedMethod = Cmd_FlagReadByName("amc_method"); 00285 if (userSpecifiedMethod == NIL(char)) { 00286 methodType = Amc_Block_c; 00287 } 00288 else { 00289 if (strcmp(userSpecifiedMethod, "block") == 0) { 00290 methodType = Amc_Block_c; 00291 } 00292 else if (strcmp(userSpecifiedMethod, "variable") == 0) { 00293 methodType = Amc_Variable_c; 00294 } 00295 else { 00296 (void) fprintf(vis_stderr, "** amc error: Unrecognized amc_method %s: using Block method.\n", 00297 userSpecifiedMethod); 00298 methodType = Amc_Block_c; 00299 } 00300 } 00301 } 00302 00303 amcInfo->methodType = methodType; 00304 00305 00306 /* 00307 * Every subsystem shares identical initial states. 00308 * We do not abstract the state space. Only the transition relation is over or 00309 * under approximated. 00310 */ 00311 { 00312 mdd_t *sampleInitialStates; 00313 Amc_SubsystemInfo_t *sampleSystem; 00314 00315 /* 00316 * Fsm routines always returns duplicate copy. 00317 */ 00318 00319 sampleSystem = array_fetch(Amc_SubsystemInfo_t *, amcInfo->subSystemArray, 0); 00320 sampleInitialStates = Fsm_FsmComputeInitialStates(sampleSystem->fsm); 00321 amcInfo->initialStates = sampleInitialStates; 00322 } 00323 00324 00325 /* 00326 * Fill in the rest of amcInfo according to methodType. 00327 */ 00328 switch(methodType) { 00329 case Amc_Block_c: 00330 amcInfo->methodData = NIL(void); 00331 amcInfo->amcBoundProc = AmcBlockTearingProc; 00332 amcInfo->amcFreeProc = AmcFreeBlock; 00333 break; 00334 /* 00335 ;;The variable tearing method has not been implemented yet;; 00336 case Amc_Variable_c: 00337 amcInfo->methodData = AmcInfoInitializeVariable(amcInfo); 00338 amcInfo->amcUpperBoundProc = AmcUpperBoundProcVariable; 00339 amcInfo->amcLowerBoundProc = AmcLowerBoundProcVariable; 00340 amcInfo->amcFreeProc = AmcFreeVariable; 00341 break; 00342 */ 00343 default: 00344 fail("Invalid methodtype when initalizing amc method"); 00345 } 00346 00347 amcInfo->currentLevel = 0; 00348 00349 return(amcInfo); 00350 } 00351 00352 00383 mdd_t * 00384 Amc_AmcExistentialQuantifySubsystem( 00385 Amc_SubsystemInfo_t *subSystem, 00386 array_t *quantifyVars, 00387 Amc_QuantificationMode quantificationMode) 00388 { 00389 Fsm_Fsm_t *subSystemFsm = AmcSubsystemReadFsm(subSystem); 00390 Ntk_Network_t *network = Fsm_FsmReadNetwork(subSystemFsm); 00391 mdd_manager *mddManager = Ntk_NetworkReadMddManager(network); 00392 graph_t *partition = Part_NetworkReadPartition(network); 00393 00394 mdd_t *result; 00395 00396 array_t *transitionRelationArray = Amc_AmcSubsystemReadRelationArray(subSystem); 00397 00398 if( transitionRelationArray == NIL(array_t) ) { 00399 /* Build the transition relation of this subsystem. */ 00400 st_table *vertexTable = AmcSubsystemReadVertexTable(subSystem); 00401 st_generator *stGen; 00402 char *latchName; 00403 00404 transitionRelationArray = array_alloc(mdd_t *, 0); 00405 st_foreach_item(vertexTable, stGen, &latchName, NIL(char *)) { 00406 00407 Ntk_Node_t *latch = Ntk_NetworkFindNodeByName(network, latchName); 00408 int functionMddId = Ntk_NodeReadMddId(Ntk_NodeReadShadow(latch)); 00409 00410 char *nameLatchDataInput = Ntk_NodeReadName(Ntk_LatchReadDataInput(latch)); 00411 vertex_t *ptrVertex = Part_PartitionFindVertexByName(partition, nameLatchDataInput); 00412 00413 Mvf_Function_t *nextStateFunction; 00414 mdd_t *transitionRelation; 00415 nextStateFunction = Part_VertexReadFunction(ptrVertex); 00416 transitionRelation = Mvf_FunctionBuildRelationWithVariable(nextStateFunction, 00417 functionMddId); 00418 #ifdef AMC_DEBUG 00419 { 00420 int y, mddId; array_t *supportOfRelation; 00421 fprintf(vis_stdout, "\nThe transition relation of the output function of the node : %s", latchName); 00422 supportOfRelation = mdd_get_support(mddManager, transitionRelation); 00423 arrayForEachItem(int, supportOfRelation, y, mddId) { 00424 Ntk_Node_t *supportNode = Ntk_NetworkFindNodeByMddId(network, mddId); 00425 fprintf(vis_stdout, "\n\tThe node in the support : %s", 00426 Ntk_NodeReadName(supportNode)); 00427 } 00428 } 00429 #endif 00430 00431 if( nextStateFunction == NIL(Mvf_Function_t) ) { 00432 error_append("** amc error: Build partition before running approximate model checker."); 00433 return NIL(mdd_t); 00434 } 00435 00436 array_insert_last(mdd_t *, transitionRelationArray, transitionRelation); 00437 } /* end of st_foreach_item */ 00438 00439 /* Cache the transition relation of the subsystem. */ 00440 Amc_AmcSubsystemSetRelationArray(subSystem, transitionRelationArray); 00441 00442 } /* end of transition relation construction. */ 00443 00444 00445 /* 00446 * Notice : The present and next state variable of a subsystem is identical 00447 * to that of the original system. The subsystem carries the subset of the 00448 * output functions of the original system. 00449 */ 00450 if( quantificationMode == Amc_User_c ) { 00451 /* result = Img_MultiwayLinearAndSmooth(mddManager, transitionRelationArray, quantifyVars, 00452 NIL(array_t)); */ 00453 if( AmcSubsystemReadNextStateVarSmoothen(subSystem) == NIL(mdd_t) ) { 00454 result = Fsm_MddMultiwayAndSmooth(mddManager, transitionRelationArray, quantifyVars); 00455 AmcSubsystemSetNextStateVarSmoothen(subSystem, result); 00456 } 00457 else { 00458 result = AmcSubsystemReadNextStateVarSmoothen(subSystem); 00459 } 00460 } 00461 else if( quantificationMode == Amc_PresentVars_c ) { 00462 array_t *presentVars = Fsm_FsmReadPresentStateVars(subSystemFsm); 00463 result = Fsm_MddMultiwayAndSmooth(mddManager, transitionRelationArray, presentVars); 00464 } 00465 else if( quantificationMode == Amc_NextVars_c ) { 00466 array_t *nextVars = Fsm_FsmReadNextStateVars(subSystemFsm); 00467 result = Fsm_MddMultiwayAndSmooth(mddManager, transitionRelationArray, nextVars); 00468 } 00469 else if( quantificationMode == Amc_InputVars_c ) { 00470 array_t *inputVars = Fsm_FsmReadInputVars(subSystemFsm); 00471 result = Fsm_MddMultiwayAndSmooth(mddManager, transitionRelationArray, inputVars); 00472 } 00473 else { 00474 error_append("** amc error: Invalid quantification mode."); 00475 return NIL(mdd_t); 00476 } 00477 00478 00479 return(result); 00480 00481 } 00482 00517 array_t * 00518 Amc_AmcExistentialQuantifySubsystemArray( 00519 array_t *subSystemArray, 00520 Amc_SubsystemInfo_t *currentSystem, 00521 array_t *quantifyVars, 00522 Amc_QuantificationMode quantificationMode) 00523 { 00524 int i; 00525 Amc_SubsystemInfo_t *subSystem; 00526 mdd_t *quantifiedSystemMdd; 00527 array_t *quantifiedSystemMddArray = array_alloc(mdd_t *, 0); 00528 00529 if( (quantificationMode == Amc_User_c) && (quantifyVars == NIL(array_t)) ) { 00530 error_append("** amc error: Subsystem has no output functions."); 00531 return NIL(array_t); 00532 } 00533 00534 arrayForEachItem(Amc_SubsystemInfo_t *, subSystemArray, i, subSystem) { 00535 if( (!subSystem->takenIntoOptimal) && (i != currentSystem->takenIntoOptimal) ) { 00536 00537 quantifiedSystemMdd = 00538 Amc_AmcExistentialQuantifySubsystem(subSystem, quantifyVars, 00539 quantificationMode); 00540 array_insert_last(mdd_t *, quantifiedSystemMddArray, quantifiedSystemMdd); 00541 } 00542 } 00543 00544 return(quantifiedSystemMddArray); 00545 00546 } 00547 00548 00558 Fsm_Fsm_t * 00559 Amc_AmcSubsystemReadFsm( 00560 Amc_SubsystemInfo_t *system) 00561 { 00562 return AmcSubsystemReadFsm(system); 00563 } /* End of Amc_AmcSubsystemReadFsm */ 00564 00574 void 00575 Amc_AmcSubsystemSetFsm( 00576 Amc_SubsystemInfo_t *system, 00577 Fsm_Fsm_t *info) 00578 { 00579 AmcSubsystemSetFsm(system, info); 00580 } /* End of Amc_AmcSubsystemReadFsm */ 00581 00582 00593 array_t * 00594 Amc_AmcSubsystemReadRelationArray( 00595 Amc_SubsystemInfo_t *system) 00596 { 00597 return AmcSubsystemReadRelationArray(system); 00598 } /* End of Amc_AmcSubsystemReadTransitionRelation */ 00599 00610 void 00611 Amc_AmcSubsystemSetRelationArray( 00612 Amc_SubsystemInfo_t *system, 00613 array_t *info) 00614 { 00615 AmcSubsystemSetRelationArray(system, info); 00616 } /* End of Amc_AmcSubsystemSetTransitionRelation */ 00617 00618 00632 mdd_t * 00633 Amc_AmcSubsystemReadNextStateVarSmoothen( 00634 Amc_SubsystemInfo_t *system) 00635 { 00636 return AmcSubsystemReadNextStateVarSmoothen(system); 00637 } /* End of Amc_AmcSubsystemReadNextStateVarSmooth */ 00638 00649 void 00650 Amc_AmcSubsystemSetNextStateVarSmoothen( 00651 Amc_SubsystemInfo_t *system, 00652 mdd_t *info) 00653 { 00654 AmcSubsystemSetNextStateVarSmoothen(system, info); 00655 } /* End of Amc_AmcSubsystemSetNextStateVarSmooth */ 00656 00666 mdd_t * 00667 Amc_AmcSubsystemReadSatisfy( 00668 Amc_SubsystemInfo_t *system) 00669 { 00670 return AmcSubsystemReadSatisfy(system); 00671 } /* End of Amc_AmcSubsystemReadSatisfy */ 00672 00687 void 00688 Amc_AmcSubsystemSetSatisfy( 00689 Amc_SubsystemInfo_t *system, 00690 mdd_t *data) 00691 { 00692 AmcSubsystemSetSatisfy(system, data); 00693 } /* End of Amc_AmcSubsystemSetSatisfy */ 00694 00708 st_table * 00709 Amc_AmcSubsystemReadVertexTable( 00710 Amc_SubsystemInfo_t *system) 00711 { 00712 return AmcSubsystemReadVertexTable(system); 00713 } /* End of Amc_AmcSubsystemReadVertexTable */ 00714 00724 void 00725 Amc_AmcSubsystemSetVertexTable( 00726 Amc_SubsystemInfo_t *system, 00727 st_table *data) 00728 { 00729 AmcSubsystemSetVertexTable(system, data); 00730 } /* End of Amc_AmcSubsystemSetVertexTable */ 00731 00746 st_table * 00747 Amc_AmcSubsystemReadFanInTable( 00748 Amc_SubsystemInfo_t *system) 00749 { 00750 return AmcSubsystemReadFanInTable(system); 00751 } /* End of Amc_AmcSubsystemReadFanInTable */ 00752 00762 void 00763 Amc_AmcSubsystemSetFanInTable( 00764 Amc_SubsystemInfo_t *system, 00765 st_table *data) 00766 { 00767 AmcSubsystemSetFanInTable(system, data); 00768 } /* End of Amc_AmcSubsystemSetFanInTable */ 00769 00784 st_table * 00785 Amc_AmcSubsystemReadFanOutTable( 00786 Amc_SubsystemInfo_t *system) 00787 { 00788 return AmcSubsystemReadFanOutTable(system); 00789 } /* End of Amc_AmcSubsystemReadFanOutTable */ 00790 00800 void 00801 Amc_AmcSubsystemSetFanOutTable( 00802 Amc_SubsystemInfo_t *system, 00803 st_table *data) 00804 { 00805 AmcSubsystemSetFanOutTable(system, data); 00806 } /* End of Amc_AmcSubsystemSetFanOutTable */ 00807 00808 00821 char * 00822 Amc_AmcSubsystemReadMethodSpecificData( 00823 Amc_SubsystemInfo_t *system) 00824 { 00825 return AmcSubsystemReadMethodSpecificData(system); 00826 } /* End of Amc_AmcSubsystemReadMethodSpecificData */ 00827 00837 void 00838 Amc_AmcSubsystemSetMethodSpecificData( 00839 Amc_SubsystemInfo_t *system, 00840 char *data) 00841 { 00842 AmcSubsystemSetMethodSpecificData(system, data); 00843 } /* End of Amc_AmcSubsystemSetMethodSpecificData */ 00844 00845 00846 00856 mdd_t * 00857 Amc_AmcReadInitialStates( 00858 Amc_Info_t *system) 00859 { 00860 return AmcReadInitialStates(system); 00861 } /* End of Amc_AmcReadInitialStates */ 00862 00872 void 00873 Amc_AmcSetInitialStates( 00874 Amc_Info_t *system, 00875 mdd_t *data) 00876 { 00877 AmcSetInitialStates(system, data); 00878 } /* End of Amc_AmcSetInitialStates */ 00879 00889 Amc_SubsystemInfo_t * 00890 Amc_AmcReadOptimalSystem( 00891 Amc_Info_t *system) 00892 { 00893 return AmcReadOptimalSystem(system); 00894 } /* End of Amc_AmcReadOptimalSystem */ 00895 00905 void 00906 Amc_AmcSetOptimalSystem( 00907 Amc_Info_t *system, 00908 Amc_SubsystemInfo_t *data) 00909 { 00910 AmcSetOptimalSystem(system, data); 00911 } /* End of Amc_AmcSetOptimalSystem */ 00912 00922 void * 00923 Amc_AmcReadMethodData( 00924 Amc_Info_t *system) 00925 { 00926 return AmcReadMethodData(system); 00927 } /* End of Amc_AmcReadMethodData */ 00928 00938 void 00939 Amc_AmcSetMethodData( 00940 Amc_Info_t *system, 00941 void *data) 00942 { 00943 AmcSetMethodData(system, data); 00944 } /* End of Amc_AmcSetMethodData */ 00945 00946 00947 00957 Amc_SubsystemInfo_t * 00958 Amc_AmcSubsystemAllocate(void) 00959 { 00960 Amc_SubsystemInfo_t *result; 00961 00962 result = ALLOC(Amc_SubsystemInfo_t, 1); 00963 00964 return result; 00965 } /* End of Amc_SubsystemAllocate */ 00966 00967 00979 Amc_SubsystemInfo_t * 00980 Amc_AmcSubsystemCreate( 00981 Fsm_Fsm_t *fsm, 00982 mdd_t *satisfyStates, 00983 st_table *vertexTable, 00984 st_table *fanInTable, 00985 st_table *fanOutTable) 00986 { 00987 Amc_SubsystemInfo_t *result; 00988 00989 result = ALLOC(Amc_SubsystemInfo_t, 1); 00990 result->fsm = fsm; 00991 result->relationArray = NIL(array_t); 00992 result->nextStateVarSmoothen = NIL(mdd_t); 00993 result->satisfyStates = satisfyStates; 00994 result->vertexTable = vertexTable; 00995 result->fanInTable = fanInTable; 00996 result->fanOutTable = fanOutTable; 00997 result->takenIntoOptimal = 0; /* Initialize to 0 */ 00998 result->methodSpecificData = NIL(char); 00999 01000 return result; 01001 } 01002 01012 Amc_SubsystemInfo_t * 01013 Amc_AmcSubsystemDuplicate( 01014 Ntk_Network_t *network, 01015 Amc_SubsystemInfo_t *subSystem) 01016 { 01017 Fsm_Fsm_t *fsm; 01018 mdd_t *satisfyStates = NIL(mdd_t); 01019 st_table *vertexTable = NIL(st_table); 01020 st_table *fanInTable = NIL(st_table); 01021 st_table *fanOutTable = NIL(st_table); 01022 graph_t *partition = Part_NetworkReadPartition(network); 01023 01024 if(subSystem->satisfyStates != NIL(mdd_t)) { 01025 satisfyStates = mdd_dup(subSystem->satisfyStates); 01026 } 01027 if(subSystem->vertexTable != NIL(st_table)) { 01028 vertexTable = st_copy(subSystem->vertexTable); 01029 } 01030 if(subSystem->fanInTable != NIL(st_table)) { 01031 fanInTable = st_copy(subSystem->fanInTable); 01032 } 01033 if(subSystem->fanOutTable != NIL(st_table)) { 01034 fanOutTable = st_copy(subSystem->fanOutTable); 01035 } 01036 01037 fsm = Fsm_FsmCreateSubsystemFromNetwork(network, partition, vertexTable, 01038 FALSE, 0); 01039 01040 return(Amc_AmcSubsystemCreate(fsm, satisfyStates, vertexTable, fanInTable, fanOutTable)); 01041 } 01042 01043 01044 01057 void 01058 Amc_AmcSubsystemFree( 01059 Amc_SubsystemInfo_t *subSystem) 01060 { 01061 st_table *vertexTable; 01062 st_table *fanInTable, *fanOutTable; 01063 01064 /* Do not free partition associated to this fsm */ 01065 if (AmcSubsystemReadFsm(subSystem) != NIL(Fsm_Fsm_t)) { 01066 Fsm_FsmSubsystemFree(AmcSubsystemReadFsm(subSystem)); 01067 } 01068 01069 if (AmcSubsystemReadRelationArray(subSystem) != NIL(array_t)) { 01070 array_t *transitionRelationArray = AmcSubsystemReadRelationArray(subSystem); 01071 mdd_t *transitionRelation; 01072 int i; 01073 arrayForEachItem(mdd_t *, transitionRelationArray, i, transitionRelation) { 01074 mdd_free(transitionRelation); 01075 } 01076 array_free(transitionRelationArray); 01077 } 01078 01079 if (AmcSubsystemReadNextStateVarSmoothen(subSystem) != NIL(mdd_t)) { 01080 mdd_free(AmcSubsystemReadNextStateVarSmoothen(subSystem)); 01081 } 01082 01083 if (AmcSubsystemReadSatisfy(subSystem) != NIL(mdd_t)) { 01084 mdd_free(AmcSubsystemReadSatisfy(subSystem)); 01085 } 01086 01087 /* Do not free vertex!! */ 01088 vertexTable = AmcSubsystemReadVertexTable(subSystem); 01089 if (vertexTable != NIL(st_table)) { 01090 st_free_table(vertexTable); 01091 } 01092 01093 fanInTable = AmcSubsystemReadFanInTable(subSystem); 01094 if (fanInTable != NIL(st_table)) { 01095 st_free_table(fanInTable); 01096 } 01097 01098 fanOutTable = AmcSubsystemReadFanOutTable(subSystem); 01099 if (fanOutTable != NIL(st_table)) { 01100 st_free_table(fanOutTable); 01101 } 01102 01103 01104 FREE(subSystem); 01105 } 01106 01118 void 01119 Amc_AmcSubsystemFreeAlsoPartition( 01120 Amc_SubsystemInfo_t *subSystem) 01121 { 01122 st_table *vertexTable; 01123 st_table *fanInTable, *fanOutTable; 01124 01125 /* Do not free partition associated to this fsm */ 01126 if (AmcSubsystemReadFsm(subSystem) != NIL(Fsm_Fsm_t)) { 01127 Fsm_FsmFree(AmcSubsystemReadFsm(subSystem)); 01128 } 01129 01130 if (AmcSubsystemReadRelationArray(subSystem) != NIL(array_t)) { 01131 array_t *transitionRelationArray = AmcSubsystemReadRelationArray(subSystem); 01132 mdd_t *transitionRelation; 01133 int i; 01134 arrayForEachItem(mdd_t *, transitionRelationArray, i, transitionRelation) { 01135 mdd_free(transitionRelation); 01136 } 01137 array_free(transitionRelationArray); 01138 } 01139 01140 if (AmcSubsystemReadNextStateVarSmoothen(subSystem) != NIL(mdd_t)) { 01141 mdd_free(AmcSubsystemReadNextStateVarSmoothen(subSystem)); 01142 } 01143 01144 if (AmcSubsystemReadSatisfy(subSystem) != NIL(mdd_t)) { 01145 mdd_free(AmcSubsystemReadSatisfy(subSystem)); 01146 } 01147 01148 /* Do not free vertex!! */ 01149 vertexTable = AmcSubsystemReadVertexTable(subSystem); 01150 if (vertexTable != NIL(st_table)) { 01151 st_free_table(vertexTable); 01152 } 01153 01154 fanInTable = AmcSubsystemReadFanInTable(subSystem); 01155 if (fanInTable != NIL(st_table)) { 01156 st_free_table(fanInTable); 01157 } 01158 01159 fanOutTable = AmcSubsystemReadFanOutTable(subSystem); 01160 if (fanOutTable != NIL(st_table)) { 01161 st_free_table(fanOutTable); 01162 } 01163 01164 01165 FREE(subSystem); 01166 } 01167 01168 01169 01170 01186 Amc_SubsystemInfo_t * 01187 Amc_CombineSubsystems( 01188 Ntk_Network_t *network, 01189 Amc_SubsystemInfo_t *subSystem1, 01190 Amc_SubsystemInfo_t *subSystem2) 01191 { 01192 Amc_SubsystemInfo_t *subSystemInfo; 01193 Amc_SubsystemInfo_t *subSystem; 01194 st_table *vertexTable, *vertexTable1, *vertexTable2; 01195 st_table *fanInTable = NIL(st_table); 01196 st_table *fanOutTable = NIL(st_table); 01197 st_table *fanInTable1, *fanInTable2; 01198 st_table *fanOutTable1, *fanOutTable2; 01199 Ntk_Node_t *latch; 01200 graph_t *partition = Part_NetworkReadPartition(network); 01201 Fsm_Fsm_t *fsm; 01202 lsGen gen; 01203 st_generator *stGen; 01204 01205 /* If two subsystem are identical return error */ 01206 if(subSystem1 == subSystem2) { 01207 error_append("** amc error: illegal subsystem combination"); 01208 return NIL(Amc_SubsystemInfo_t); 01209 } 01210 /* If two subsystem are NIL return error */ 01211 if( (subSystem1 == NIL(Amc_SubsystemInfo_t)) && 01212 (subSystem2 == NIL(Amc_SubsystemInfo_t)) ) { 01213 error_append("** amc error: illegal subsystem combination"); 01214 return NIL(Amc_SubsystemInfo_t); 01215 } 01216 01217 /* If either of two subsystem is NIL return copy of the other */ 01218 if(subSystem1 == NIL(Amc_SubsystemInfo_t)) { 01219 return Amc_AmcSubsystemDuplicate(network, subSystem2); 01220 } 01221 if(subSystem2 == NIL(Amc_SubsystemInfo_t)) { 01222 return Amc_AmcSubsystemDuplicate(network, subSystem1); 01223 } 01224 01225 vertexTable = st_init_table(strcmp, st_strhash); 01226 vertexTable1 = AmcSubsystemReadVertexTable(subSystem1); 01227 vertexTable2 = AmcSubsystemReadVertexTable(subSystem2); 01228 01229 Ntk_NetworkForEachLatch(network, gen, latch) { 01230 char *latchName = Ntk_NodeReadName(latch); 01231 if( st_lookup(vertexTable1, latchName, (char **)0) || 01232 st_lookup(vertexTable2, latchName, (char **)0) ) { 01233 01234 st_insert(vertexTable, latchName, (char *)0); 01235 01236 } 01237 } /* end of Ntk_NetworkForEachLatch */ 01238 01239 01240 fanInTable1 = AmcSubsystemReadFanInTable(subSystem1); 01241 fanInTable2 = AmcSubsystemReadFanInTable(subSystem2); 01242 if( (fanInTable1 != NIL(st_table)) && (fanInTable2 != NIL(st_table)) ) { 01243 01244 fanInTable = st_init_table(st_ptrcmp, st_ptrhash); 01245 01246 st_foreach_item(fanInTable1, stGen, &subSystem, NIL(char *)) { 01247 st_insert(fanInTable, (char *)subSystem, (char *)0); 01248 } 01249 st_foreach_item(fanInTable2, stGen, &subSystem, NIL(char *)) { 01250 st_insert(fanInTable, (char *)subSystem, (char *)0); 01251 } 01252 } 01253 01254 01255 fanOutTable1 = AmcSubsystemReadFanOutTable(subSystem1); 01256 fanOutTable2 = AmcSubsystemReadFanOutTable(subSystem2); 01257 01258 if( (fanOutTable1 != NIL(st_table)) && (fanOutTable2 != NIL(st_table)) ) { 01259 01260 fanOutTable = st_init_table(st_ptrcmp, st_ptrhash); 01261 01262 st_foreach_item(fanInTable1, stGen, &subSystem, NIL(char *)) { 01263 st_insert(fanOutTable, subSystem, (char *)0); 01264 } 01265 st_foreach_item(fanInTable2, stGen, &subSystem, NIL(char *)) { 01266 st_insert(fanOutTable, subSystem, (char *)0); 01267 } 01268 } 01269 01270 01271 fsm = Fsm_FsmCreateSubsystemFromNetwork(network, partition, vertexTable, 01272 FALSE, 0); 01273 01274 subSystemInfo = Amc_AmcSubsystemCreate(fsm, NIL(mdd_t), vertexTable, 01275 fanInTable, fanOutTable); 01276 01277 /* Does not free tables */ 01278 01279 return(subSystemInfo); 01280 } 01281 01282 #ifdef AMC_DEBUG_ 01283 01295 Img_ImageInfo_t * 01296 Amc_AmcReadOrCreateImageInfo( 01297 Fsm_Fsm_t *fsm) 01298 { 01299 Img_ImageInfo_t *imageInfo; 01300 if( Fsm_FsmReadImageInfo(fsm) == NIL(Img_ImageInfo_t)) { 01301 array_t *dummyInputVars = array_alloc(int, 0); 01302 imageInfo = Img_ImageInfoInitialize(Fsm_FsmReadPartition(fsm), 01303 Fsm_FsmReadNextStateFunctions(fsm), 01304 Fsm_FsmReadPresentStateVars(fsm), 01305 Fsm_FsmReadNextStateVars(fsm), 01306 dummyInputVars, 01307 Fsm_FsmReadNetwork(fsm), 01308 Img_Default_c, Img_Both_c); 01309 Fsm_FsmSetImageInfo(fsm, imageInfo); 01310 array_free(dummyInputVars); 01311 } 01312 return (imageInfo); 01313 } 01314 #endif 01315 01327 mdd_t * 01328 Amc_AmcEvaluateCTLFormula( 01329 Amc_SubsystemInfo_t *subSystem, 01330 array_t *subSystemArray, 01331 Ctlp_Formula_t *ctlFormula, 01332 mdd_t *fairStates, 01333 Fsm_Fairness_t *fairCondition, 01334 mdd_t *modelCareStates, 01335 boolean lowerBound, 01336 array_t *quantifyVars, 01337 Mc_VerbosityLevel verbosity, 01338 Mc_DcLevel dcLevel ) 01339 { 01340 Fsm_Fsm_t *modelFsm = Amc_AmcSubsystemReadFsm(subSystem); 01341 01342 mdd_t *leftMdd = NIL(mdd_t); 01343 mdd_t *rightMdd = NIL(mdd_t); 01344 mdd_t *result = NIL(mdd_t); 01345 mdd_t *tmpResult = NIL(mdd_t); 01346 01347 mdd_t *ctlFormulaStates = Ctlp_FormulaObtainStates(ctlFormula ); 01348 mdd_manager *mddMgr = Fsm_FsmReadMddManager(modelFsm); 01349 mdd_t *careStates = NIL(mdd_t); 01350 01351 01352 if (ctlFormulaStates) { 01353 return ctlFormulaStates; 01354 } 01355 01356 { 01357 Ctlp_Formula_t *leftChild = Ctlp_FormulaReadLeftChild(ctlFormula); 01358 if (leftChild) { 01359 leftMdd = Amc_AmcEvaluateCTLFormula(subSystem, subSystemArray, leftChild, fairStates, fairCondition, 01360 modelCareStates, lowerBound, quantifyVars, verbosity, dcLevel); 01361 if (!leftMdd) 01362 return NIL(mdd_t); 01363 } 01364 } 01365 01366 { 01367 Ctlp_Formula_t *rightChild = Ctlp_FormulaReadRightChild(ctlFormula); 01368 if (rightChild) { 01369 rightMdd = Amc_AmcEvaluateCTLFormula(subSystem, subSystemArray, rightChild, fairStates, fairCondition, 01370 modelCareStates, lowerBound, quantifyVars, verbosity, dcLevel); 01371 if (!rightMdd ) 01372 return NIL(mdd_t); 01373 } 01374 } 01375 01376 careStates = (modelCareStates != NIL(mdd_t)) ? mdd_dup(modelCareStates) : mdd_one(mddMgr); 01377 switch ( Ctlp_FormulaReadType( ctlFormula ) ) { 01378 01379 case Ctlp_ID_c : tmpResult = AmcModelCheckAtomicFormula( modelFsm, ctlFormula ); 01380 01381 /* #AMC : Obtain lowerbound of the constraint set. */ 01382 if(0 && lowerBound) { /*Chao: this is not correct! consider !EF(!p) */ 01383 array_t *quantifyPresentVars = array_fetch(array_t *, quantifyVars, 0); 01384 int numOfPresentQuantifyVars = array_n(quantifyPresentVars); 01385 /* 01386 * Currently VIS does not allow primary input as the variable of 01387 * the atomic propositions. 01388 */ 01389 if(numOfPresentQuantifyVars > 0) { 01390 result = mdd_consensus(mddMgr, tmpResult, quantifyPresentVars); 01391 mdd_free(tmpResult); 01392 } 01393 else 01394 result = tmpResult; 01395 } 01396 else 01397 result = tmpResult; 01398 01399 break; 01400 01401 case Ctlp_TRUE_c : result = mdd_one( mddMgr ); break; 01402 case Ctlp_FALSE_c : result = mdd_zero( mddMgr ); break; 01403 01404 case Ctlp_NOT_c : result = mdd_not( leftMdd ); break; 01405 case Ctlp_EQ_c : result = mdd_xnor( leftMdd, rightMdd ); break; 01406 case Ctlp_XOR_c : result = mdd_xor( leftMdd, rightMdd ); break; 01407 case Ctlp_THEN_c : result = mdd_or( leftMdd, rightMdd, 0, 1 ); break; 01408 case Ctlp_AND_c: result = mdd_and( leftMdd, rightMdd, 1, 1 ); break; 01409 case Ctlp_OR_c: result = mdd_or( leftMdd, rightMdd, 1, 1 ); break; 01410 01411 case Ctlp_EX_c: 01412 result = Amc_AmcEvaluateEXFormula( modelFsm, subSystemArray, subSystem, leftMdd, fairStates, 01413 careStates, lowerBound, quantifyVars, verbosity, dcLevel ); 01414 break; 01415 01416 case Ctlp_EU_c: { 01417 array_t *onionRings = array_alloc( mdd_t *, 0 ); 01418 result = Amc_AmcEvaluateEUFormula( modelFsm, subSystemArray, subSystem, leftMdd, rightMdd, fairStates, 01419 careStates, onionRings, lowerBound, quantifyVars, verbosity, dcLevel ); 01420 Ctlp_FormulaSetDbgInfo( ctlFormula, (void *) onionRings, McFormulaFreeDebugData); 01421 break; 01422 } 01423 01424 case Ctlp_EG_c: { 01425 array_t *arrayOfOnionRings = array_alloc( array_t *, 0 ); 01426 result = Amc_AmcEvaluateEGFormula( modelFsm, subSystemArray, subSystem, leftMdd, 01427 fairStates, fairCondition, careStates, 01428 arrayOfOnionRings, lowerBound, quantifyVars, verbosity, dcLevel ); 01429 Ctlp_FormulaSetDbgInfo( ctlFormula, (void *) arrayOfOnionRings, McFormulaFreeDebugData); 01430 break; 01431 } 01432 01433 default: fail("Encountered unknown type of CTL formula\n"); 01434 } 01435 01436 01437 Ctlp_FormulaSetStates( ctlFormula, result ); 01438 01439 mdd_free( careStates ); 01440 return result; 01441 } 01442 01473 mdd_t * 01474 Amc_AmcEvaluateEXFormula( 01475 Fsm_Fsm_t *modelFsm, 01476 array_t *subSystemArray, 01477 Amc_SubsystemInfo_t *subSystem, 01478 mdd_t *targetMdd, 01479 mdd_t *fairStates, 01480 mdd_t *careStates, 01481 boolean lowerBound, 01482 array_t *quantifyVars, 01483 Mc_VerbosityLevel verbosity, 01484 Mc_DcLevel dcLevel ) 01485 { 01486 /* 01487 * The care set consists of the passed careStates 01488 */ 01489 mdd_t *toCareSet = mdd_dup( careStates ); 01490 01491 mdd_t *fromLowerBound; 01492 mdd_t *fromUpperBound; 01493 mdd_t *result = NIL(mdd_t); 01494 mdd_t *tmpResult; 01495 mdd_manager *mddManager = Fsm_FsmReadMddManager( modelFsm ); 01496 array_t *quantifyPresentVars = array_fetch(array_t *, quantifyVars, 0); 01497 01498 Img_ImageInfo_t * imageInfo; 01499 01500 assert(quantifyPresentVars != NIL(array_t)); 01501 01502 imageInfo = Fsm_FsmReadOrCreateImageInfo(modelFsm, 1, 1); 01503 01504 if ( dcLevel == McDcLevelRchFrontier_c ) { 01505 /* 01506 * The lower bound is the conjunction of the fair states, 01507 * the target states, and the care states. 01508 */ 01509 mdd_t *tmpMdd = mdd_and( targetMdd, fairStates, 1, 1 ); 01510 fromLowerBound = mdd_and( tmpMdd, careStates, 1, 1 ); 01511 mdd_free( tmpMdd ); 01512 /* 01513 * The upper bound is the OR of the lower bound with the 01514 * complement of the care states. 01515 */ 01516 fromUpperBound = mdd_or( fromLowerBound, careStates, 1, 0 ); 01517 } 01518 else { 01519 /* 01520 * The lower bound is the conjunction of the fair states, 01521 * and the target states. 01522 */ 01523 fromLowerBound = mdd_and( targetMdd, fairStates, 1, 1 ); 01524 /* 01525 * The upper bound is the same as the lower bound. 01526 */ 01527 fromUpperBound = mdd_dup( fromLowerBound ); 01528 } 01529 01530 01531 /*************************************************************************** 01532 * compute C1(s) = 01533 * C(s) for upper-bound EX computation 01534 * ( \forall (s_R) C(s) ) for lower-bound EX computation 01535 ***************************************************************************/ 01536 if (lowerBound) { 01537 mdd_t *mdd1, *mdd2; 01538 mdd1 = fromLowerBound; 01539 mdd2 = fromUpperBound; 01540 if (array_n(quantifyPresentVars) > 0) { 01541 fromLowerBound = mdd_consensus(mddManager, fromLowerBound, 01542 quantifyPresentVars); 01543 } else { 01544 fromLowerBound = mdd_dup(fromLowerBound); 01545 } 01546 if (mdd_equal(mdd1, mdd2)) { 01547 fromUpperBound = mdd_dup(fromLowerBound); 01548 }else { 01549 if (array_n(quantifyPresentVars) > 0) { 01550 fromUpperBound = mdd_consensus(mddManager, fromUpperBound, 01551 quantifyPresentVars); 01552 } else { 01553 fromUpperBound = mdd_dup(fromUpperBound); 01554 } 01555 } 01556 mdd_free(mdd1); 01557 mdd_free(mdd2); 01558 } 01559 01560 /*************************************************************************** 01561 * Compute \exist (t,x) ( T_A(s,x,t_A) * C1(t) ), where 01562 * C1(t) = C(t) for upper-bound EX 01563 * C1(t) = (\forall (t_R) C(t) ) for lower-bound EX 01564 ***************************************************************************/ 01565 tmpResult = Img_ImageInfoComputeBwdWithDomainVars( imageInfo, 01566 fromLowerBound, 01567 fromUpperBound, 01568 toCareSet ); 01569 01570 /*************************************************************************** 01571 * Compute the final result 01572 * \exist (s_R) (tmpResult(s)) for upper-bound EX 01573 * \forall (s_R) (tmpResult(s)) for lower-bound EX 01574 **************************************************************************/ 01575 if (lowerBound) { 01576 if (array_n(quantifyPresentVars) > 0) { 01577 result = mdd_consensus(mddManager, tmpResult, quantifyPresentVars); 01578 } else { 01579 result = mdd_dup(tmpResult); 01580 } 01581 }else { 01582 result = mdd_dup(tmpResult); 01583 /* result = mdd_smooth(mddManager, tmpResult, quantifyPresentVars);*/ 01584 } 01585 mdd_free(tmpResult); 01586 01587 mdd_free( fromLowerBound ); 01588 mdd_free( fromUpperBound ); 01589 mdd_free( toCareSet ); 01590 01591 if ( verbosity == McVerbosityMax_c ) { 01592 static int refCount = 0; 01593 mdd_manager *mddMgr = Fsm_FsmReadMddManager( modelFsm ); 01594 array_t *psVars = Fsm_FsmReadPresentStateVars( modelFsm ); 01595 mdd_t *tmpMdd = careStates ? mdd_and( result, careStates, 1, 1 ) : mdd_dup( result ); 01596 fprintf(vis_stdout, "--EX called %d (bdd_size - %d)\n", ++refCount, mdd_size( result ) ); 01597 fprintf(vis_stdout, "--There are %.0f care states satisfying EX formula\n", 01598 mdd_count_onset( mddMgr, tmpMdd, psVars ) ); 01599 mdd_free(tmpMdd); 01600 } 01601 01602 return result; 01603 } 01604 01605 #if 0 01606 /* this is the original (buggy) version */ 01607 mdd_t * 01608 Amc_AmcEvaluateEXFormula_Old( 01609 Fsm_Fsm_t *modelFsm, 01610 array_t *subSystemArray, 01611 Amc_SubsystemInfo_t *subSystem, 01612 mdd_t *targetMdd, 01613 mdd_t *fairStates, 01614 mdd_t *careStates, 01615 boolean lowerBound, 01616 array_t *quantifyVars, 01617 Mc_VerbosityLevel verbosity, 01618 Mc_DcLevel dcLevel ) 01619 { 01620 /* 01621 * The care set consists of the passed careStates 01622 */ 01623 mdd_t *toCareSet = mdd_dup( careStates ); 01624 01625 mdd_t *fromLowerBound; 01626 mdd_t *fromUpperBound; 01627 mdd_t *result = NIL(mdd_t); 01628 mdd_t *tmpResult; 01629 01630 Img_ImageInfo_t * imageInfo; 01631 01632 imageInfo = Fsm_FsmReadOrCreateImageInfo(modelFsm, 1, 1); 01633 01634 /* 01635 * this condition will never be true; we didnt find it to be 01636 * especially effective, are avoiding using it for now. later 01637 * we may add a McDcLevelMax+1 field which will allow us to use it 01638 * 01639 */ 01640 if ( dcLevel > McDcLevelRchFrontier_c ) { 01641 /* 01642 * The lower bound is the conjunction of the fair states, 01643 * the target states, and the care states. 01644 */ 01645 mdd_t *tmpMdd = mdd_and( targetMdd, fairStates, 1, 1 ); 01646 fromLowerBound = mdd_and( tmpMdd, careStates, 1, 1 ); 01647 mdd_free( tmpMdd ); 01648 /* 01649 * The upper bound is the OR of the lower bound with the 01650 * complement of the care states. 01651 */ 01652 fromUpperBound = mdd_or( fromLowerBound, careStates, 1, 0 ); 01653 } 01654 else { 01655 /* 01656 * The lower bound is the conjunction of the fair states, 01657 * and the target states. 01658 */ 01659 fromLowerBound = mdd_and( targetMdd, fairStates, 1, 1 ); 01660 /* 01661 * The upper bound is the same as the lower bound. 01662 */ 01663 fromUpperBound = mdd_dup( fromLowerBound ); 01664 } 01665 01666 /* #AMC : */ 01667 #ifdef AMC_DEBUG 01668 if(lowerBound) { 01669 /* 01670 * Sanity check. The set to compute a preimage from should only contain the present 01671 * state variables of the subsystem. 01672 */ 01673 { 01674 mdd_manager *mddManager = Fsm_FsmReadMddManager( modelFsm ); 01675 Ntk_Network_t *network = Fsm_FsmReadNetwork(modelFsm); 01676 array_t *supportArray = mdd_get_support(mddManager, fromLowerBound); 01677 st_table *vertexTable = Amc_AmcSubsystemReadVertexTable(subSystem); 01678 int i, varId; 01679 01680 fprintf(vis_stdout, "\n#AMC : Sanity check of the support of the constraint set"); 01681 arrayForEachItem(int, supportArray, i, varId) { 01682 Ntk_Node_t *node = Ntk_NetworkFindNodeByMddId(network, varId); 01683 char *latchName = Ntk_NodeReadName(node); 01684 fprintf(vis_stdout, "\n# fromLowerBound -- Node : %s", latchName); 01685 } 01686 01687 arrayForEachItem(int, supportArray, i, varId) { 01688 char *latchName = Ntk_NodeReadName(Ntk_NetworkFindNodeByMddId(network, varId)); 01689 if( !st_lookup(vertexTable, latchName, (char **)0 )) { 01690 fprintf(vis_stdout, "\n** amc error : Whoops!! Something's wrong in lowerbound routine."); 01691 fflush(vis_stdout); 01692 } 01693 } /* end of arrayForEachItem */ 01694 } 01695 } /* end of if(lowerBound) */ 01696 #endif 01697 01698 tmpResult = Img_ImageInfoComputeBwdWithDomainVars( imageInfo, 01699 fromLowerBound, 01700 fromUpperBound, 01701 toCareSet ); 01702 #ifdef AMC_DEBUG 01703 { 01704 Ntk_Network_t *network = Fsm_FsmReadNetwork(modelFsm); 01705 mdd_manager *mddManager = Fsm_FsmReadMddManager( modelFsm ); 01706 array_t *supportArray = mdd_get_support(mddManager, tmpResult); 01707 int i, varId; 01708 01709 fprintf(vis_stdout, "\n#AMC : Sanity check of the support of the preimage"); 01710 arrayForEachItem(int, supportArray, i, varId) { 01711 Ntk_Node_t *node = Ntk_NetworkFindNodeByMddId(network, varId); 01712 char *latchName = Ntk_NodeReadName(node); 01713 fprintf(vis_stdout, "\n## The preimage contains the node : %s", latchName); 01714 if( Ntk_NodeTestIsLatch(node) ) 01715 fprintf(vis_stdout, "\n## The node is a latch"); 01716 else 01717 fprintf(vis_stdout, "\n## The node is not a latch"); 01718 01719 } /* end of arrayForEachItem */ 01720 } 01721 #endif 01722 01723 /* #AMC : */ 01724 if(lowerBound) { 01725 mdd_manager *mddManager = Fsm_FsmReadMddManager( modelFsm ); 01726 array_t *quantifyNextVars = array_fetch(array_t *, quantifyVars, 1); 01727 array_t *exQuantifiedSystemMddArray; 01728 01729 /* 01730 * Existential abstraction of next state variables from subsystems that are 01731 * not currently in consideration. Each subsystem has disjoint next state 01732 * functions, hence we distribute existential abstraction over subsystems. 01733 */ 01734 01735 exQuantifiedSystemMddArray = 01736 Amc_AmcExistentialQuantifySubsystemArray(subSystemArray, subSystem, 01737 quantifyNextVars, Amc_User_c); 01738 01739 /* 01740 * Universal abstraction of present state and input variables from 01741 * subsystems that are not currently in consideration. 01742 */ 01743 { 01744 array_t *quantifyPresentVars = array_fetch(array_t *, quantifyVars, 0); 01745 array_t *quantifyInputVars = array_fetch(array_t *, quantifyVars, 2); 01746 array_t *consensusVarArray = array_join(quantifyPresentVars, 01747 quantifyInputVars); 01748 mdd_t *interResult = mdd_one( mddManager ); 01749 mdd_t *subMdd; 01750 int i; 01751 01752 array_insert_last(mdd_t *, exQuantifiedSystemMddArray, tmpResult); 01753 arrayForEachItem(mdd_t *, exQuantifiedSystemMddArray, i, subMdd) { 01754 mdd_t *cResult = mdd_consensus(mddManager, subMdd, consensusVarArray); 01755 result = mdd_and(cResult, interResult, 1, 1); 01756 mdd_free(cResult); mdd_free(interResult); 01757 interResult = result; 01758 01759 if( mdd_is_tautology(result, 0) ) break; 01760 } 01761 01762 mdd_free(tmpResult); 01763 /* Do not free Mdds. These are cached. */ 01764 array_free(exQuantifiedSystemMddArray); 01765 array_free(consensusVarArray); 01766 } 01767 01768 01769 } /* end of if(lowerBound) */ 01770 else { 01771 result = tmpResult; 01772 } /* end of #AMC insertion */ 01773 01774 mdd_free( fromLowerBound ); 01775 mdd_free( fromUpperBound ); 01776 mdd_free( toCareSet ); 01777 01778 if ( verbosity == McVerbosityMax_c ) { 01779 static int refCount = 0; 01780 mdd_manager *mddMgr = Fsm_FsmReadMddManager( modelFsm ); 01781 array_t *psVars = Fsm_FsmReadPresentStateVars( modelFsm ); 01782 mdd_t *tmpMdd = careStates ? mdd_and( result, careStates, 1, 1 ) : mdd_dup( result ); 01783 fprintf(vis_stdout, "--EX called %d (bdd_size - %d)\n", ++refCount, mdd_size( result ) ); 01784 fprintf(vis_stdout, "--There are %.0f care states satisfying EX formula\n", 01785 mdd_count_onset( mddMgr, tmpMdd, psVars ) ); 01786 mdd_free(tmpMdd); 01787 } 01788 01789 return result; 01790 } 01791 #endif 01792 01804 mdd_t * 01805 Amc_AmcEvaluateEUFormula( 01806 Fsm_Fsm_t *modelFsm, 01807 array_t *subSystemArray, 01808 Amc_SubsystemInfo_t *subSystem, 01809 mdd_t *invariantMdd, 01810 mdd_t *targetMdd, 01811 mdd_t *fairStates, 01812 mdd_t *careStates, 01813 array_t *onionRings, 01814 boolean lowerBound, 01815 array_t *quantifyVars, 01816 Mc_VerbosityLevel verbosity, 01817 Mc_DcLevel dcLevel ) 01818 { 01819 mdd_t *aMdd; 01820 mdd_t *bMdd; 01821 mdd_t *cMdd; 01822 mdd_t *resultMdd = mdd_and( targetMdd, fairStates, 1, 1 ); 01823 mdd_t *ringMdd = mdd_dup( resultMdd ); 01824 01825 while (TRUE) { 01826 01827 if ( onionRings ) { 01828 array_insert_last( mdd_t *, onionRings, mdd_dup( resultMdd ) ); 01829 } 01830 01831 /* 01832 * When trying to use dont cares to the hilt, 01833 * use a bdd between succ iterations -> ringMdd 01834 */ 01835 aMdd = Amc_AmcEvaluateEXFormula( modelFsm, subSystemArray, subSystem, ringMdd, fairStates, careStates, 01836 lowerBound, quantifyVars, verbosity, dcLevel ); 01837 mdd_free( ringMdd ); 01838 bMdd = mdd_and( aMdd, invariantMdd, 1, 1 ); 01839 cMdd = mdd_or( resultMdd, bMdd, 1, 1 ); 01840 01841 mdd_free( aMdd ); 01842 mdd_free( bMdd ); 01843 01844 if ( mdd_equal_mod_care_set( cMdd, resultMdd, careStates ) ) { 01845 mdd_free( cMdd ); 01846 break; 01847 } 01848 01849 if ( dcLevel >= McDcLevelRchFrontier_c ) { 01850 mdd_t *tmpMdd = mdd_and( resultMdd, cMdd, 0, 1 ); 01851 ringMdd = bdd_between( tmpMdd, cMdd ); 01852 if ( verbosity == McVerbosityMax_c ) { 01853 fprintf(vis_stdout, "-- EU |A(n+1)-A(n)| = %d\t|A(n+1)| = %d\t|between-dc| = %d\n", 01854 mdd_size( tmpMdd ), mdd_size( resultMdd ), mdd_size( ringMdd ) ); 01855 } 01856 mdd_free( tmpMdd ); 01857 } 01858 else { 01859 ringMdd = mdd_dup( cMdd ); 01860 if ( verbosity == McVerbosityMax_c ) { 01861 fprintf(vis_stdout, "-- EU |ringMdd| = %d\n", mdd_size( ringMdd ) ); 01862 } 01863 } 01864 01865 mdd_free( resultMdd ); 01866 resultMdd = cMdd; 01867 01868 } 01869 01870 if ( ( verbosity == McVerbosityMax_c ) ) { 01871 static int refCount=0; 01872 mdd_manager *mddMgr = Fsm_FsmReadMddManager( modelFsm ); 01873 array_t *psVars = Fsm_FsmReadPresentStateVars( modelFsm ); 01874 mdd_t *tmpMdd = careStates ? mdd_and( resultMdd, careStates, 1, 1 ) : mdd_dup( resultMdd ); 01875 fprintf(vis_stdout, "--EU called %d (bdd_size - %d)\n", ++refCount, mdd_size( resultMdd ) ); 01876 fprintf(vis_stdout, "--There are %.0f care states satisfying EU formula\n", 01877 mdd_count_onset( mddMgr, tmpMdd, psVars ) ); 01878 mdd_free(tmpMdd); 01879 } 01880 01881 return resultMdd; 01882 } 01883 01894 mdd_t * 01895 Amc_AmcEvaluateEGFormula( 01896 Fsm_Fsm_t *modelFsm, 01897 array_t *subSystemArray, 01898 Amc_SubsystemInfo_t *subSystem, 01899 mdd_t *invariantMdd, 01900 mdd_t *fairStates, 01901 Fsm_Fairness_t *modelFairness, 01902 mdd_t *careStates, 01903 array_t *onionRingsArrayForDbg, 01904 boolean lowerBound, 01905 array_t *quantifyVars, 01906 Mc_VerbosityLevel verbosity, 01907 Mc_DcLevel dcLevel ) 01908 { 01909 int i; 01910 array_t *onionRings = NIL(array_t); 01911 array_t *tmpOnionRingsArrayForDbg = NIL(array_t); 01912 mdd_manager *mddManager = Fsm_FsmReadMddManager( modelFsm ); 01913 mdd_t *mddOne = mdd_one( mddManager ); 01914 mdd_t *Zmdd; 01915 01916 01917 array_t *buchiFairness = array_alloc( mdd_t *, 0 ); 01918 if (modelFairness) { 01919 if ( !Fsm_FairnessTestIsBuchi( modelFairness ) ) { 01920 (void) fprintf(vis_stdout, "#** mc error: non Buchi fairness constraints not supported\n"); 01921 return NIL(mdd_t); 01922 } 01923 else { 01924 int j; 01925 int numBuchi = Fsm_FairnessReadNumConjunctsOfDisjunct( modelFairness, 0 ); 01926 array_t *careStatesArray = array_alloc(mdd_t *, 0); 01927 01928 array_insert(mdd_t *, careStatesArray, 0, careStates); 01929 for( j = 0 ; j < numBuchi; j++ ) { 01930 mdd_t *tmpMdd = Fsm_FairnessObtainFinallyInfMdd(modelFairness, 01931 0, j, careStatesArray, 01932 dcLevel); 01933 array_insert_last( mdd_t *, buchiFairness, tmpMdd ); 01934 } 01935 array_free(careStatesArray); 01936 } 01937 } 01938 else { 01939 array_insert_last( mdd_t *, buchiFairness, mdd_one(mddManager) ); 01940 } 01941 01942 if ( onionRingsArrayForDbg !=NIL(array_t) ) { 01943 tmpOnionRingsArrayForDbg = array_alloc( array_t *, 0 ); 01944 } 01945 01946 01947 Zmdd = mdd_dup( invariantMdd ); 01948 while (TRUE) { 01949 01950 mdd_t *ZprimeMdd = mdd_dup(Zmdd); 01951 mdd_t *conjunctsMdd = NIL(mdd_t); 01952 mdd_t *AAmdd = mdd_dup(Zmdd); 01953 01954 for ( i = 0 ; i < array_n( buchiFairness ) ; i++ ) { 01955 01956 mdd_t *aMdd, *bMdd, *cMdd; 01957 mdd_t *FiMdd = array_fetch( mdd_t *, buchiFairness, i ); 01958 01959 if ( tmpOnionRingsArrayForDbg ) { 01960 onionRings = array_alloc( mdd_t *, 0 ); 01961 array_insert_last( array_t *, tmpOnionRingsArrayForDbg, onionRings ); 01962 } 01963 01964 /* aMdd = mdd_and( FiMdd, Zmdd, 1, 1); */ 01965 aMdd = mdd_and( FiMdd, AAmdd, 1, 1); 01966 01967 bMdd = Amc_AmcEvaluateEUFormula( modelFsm, subSystemArray, subSystem, AAmdd, aMdd, mddOne, careStates, 01968 onionRings, lowerBound, quantifyVars, verbosity, dcLevel ); 01969 mdd_free(aMdd); 01970 cMdd = Amc_AmcEvaluateEXFormula( modelFsm, subSystemArray, subSystem, bMdd, mddOne, careStates, 01971 lowerBound, quantifyVars, verbosity, dcLevel ); 01972 mdd_free(bMdd); 01973 01974 if ( conjunctsMdd == NIL(mdd_t) ) { 01975 conjunctsMdd = mdd_dup( cMdd ); 01976 mdd_free( AAmdd ); AAmdd = mdd_and( conjunctsMdd, invariantMdd,1 ,1 ); 01977 } 01978 else { 01979 mdd_t *tmpMdd = mdd_and( cMdd, conjunctsMdd, 1, 1 ); 01980 mdd_free( conjunctsMdd ); 01981 conjunctsMdd = tmpMdd; 01982 mdd_free( AAmdd ); AAmdd = mdd_and( conjunctsMdd, invariantMdd,1 ,1 ); 01983 } 01984 mdd_free( cMdd ); 01985 } 01986 mdd_free(AAmdd); 01987 01988 mdd_free(ZprimeMdd); 01989 ZprimeMdd = mdd_and( invariantMdd, conjunctsMdd, 1, 1 ); 01990 mdd_free( conjunctsMdd ); 01991 01992 if ( mdd_equal_mod_care_set( ZprimeMdd, Zmdd, careStates ) ) { 01993 mdd_free( ZprimeMdd ); 01994 break; 01995 } 01996 01997 mdd_free( Zmdd ); 01998 Zmdd = ZprimeMdd; 01999 02000 if ( tmpOnionRingsArrayForDbg ) { 02001 arrayForEachItem(array_t *, tmpOnionRingsArrayForDbg, i, onionRings ) { 02002 mdd_array_free( onionRings ); 02003 } 02004 array_free( tmpOnionRingsArrayForDbg ); 02005 tmpOnionRingsArrayForDbg = array_alloc( array_t *, 0 ); 02006 } 02007 } 02008 02009 if ( onionRingsArrayForDbg != NIL(array_t) ) { 02010 arrayForEachItem(array_t *, tmpOnionRingsArrayForDbg, i, onionRings ) { 02011 array_insert_last( array_t *, onionRingsArrayForDbg, onionRings ); 02012 } 02013 array_free( tmpOnionRingsArrayForDbg ); 02014 } 02015 02016 if ( ( verbosity == McVerbositySome_c ) || ( verbosity == McVerbosityMax_c ) ) { 02017 { 02018 for ( i = 0 ; i < array_n( onionRingsArrayForDbg ); i++ ) { 02019 int j; 02020 mdd_t *Fi = array_fetch( mdd_t *, buchiFairness, i ); 02021 array_t *onionRings = array_fetch( array_t *, onionRingsArrayForDbg, i ); 02022 for( j = 0 ; j < array_n( onionRings ) ; j++ ) { 02023 mdd_t *ring = array_fetch( mdd_t *, onionRings, j ); 02024 if ( j == 0 ) { 02025 if ( ! mdd_lequal( ring, Fi, 1, 1 ) ) { 02026 fprintf( vis_stderr, "Problem w/ dbg - inner most ring not in Fi\n"); 02027 } 02028 } 02029 if ( ! mdd_lequal( ring, Zmdd, 1, 1 ) ) { 02030 fprintf( vis_stderr, "Problem w/ dbg - onion ring fails invariant\n"); 02031 } 02032 } 02033 } 02034 } 02035 02036 { 02037 mdd_t *tmpMdd = careStates ? mdd_and( Zmdd, careStates, 1, 1 ) : mdd_dup( Zmdd ); 02038 fprintf(vis_stdout, "--There are %.0f states satisfying EG formula\n", 02039 mdd_count_onset( Fsm_FsmReadMddManager( modelFsm ), tmpMdd, 02040 Fsm_FsmReadPresentStateVars( modelFsm ) ) ); 02041 mdd_free( tmpMdd ); 02042 } 02043 } 02044 02045 mdd_array_free( buchiFairness ); 02046 mdd_free( mddOne ); 02047 02048 return Zmdd; 02049 } 02050 02051 02052 /*---------------------------------------------------------------------------*/ 02053 /* Definition of internal functions */ 02054 /*---------------------------------------------------------------------------*/ 02055 02072 array_t * 02073 AmcCreateSubsystemArray( 02074 Ntk_Network_t *network, 02075 Ctlp_Formula_t *formula) 02076 { 02077 array_t *partitionArray, *subSystemArray; 02078 Part_Subsystem_t *partitionSubsystem; 02079 Part_SubsystemInfo_t *subsystemInfo; 02080 st_table *vertexTable; 02081 array_t *fanInIndexArray, *fanOutIndexArray; 02082 st_table *fanInSystemTable, *fanOutSystemTable; 02083 Amc_SubsystemInfo_t *subSystem; 02084 graph_t *partition = Part_NetworkReadPartition(network); 02085 int i, j; 02086 int fanInIndex, fanOutIndex, numOfVertex; 02087 Amc_SubsystemInfo_t *fanInSubsystem, *fanOutSubsystem; 02088 char *flagValue, *numberOfVertexInGroup; 02089 array_t *ctlArray; 02090 02091 /* Obtain the size of the subsystem */ 02092 numberOfVertexInGroup = Cmd_FlagReadByName("amc_sizeof_group"); 02093 if(numberOfVertexInGroup != NIL(char)){ 02094 numOfVertex = atoi(numberOfVertexInGroup); 02095 } 02096 else{ 02097 /* default value */ 02098 numOfVertex = 8; 02099 } 02100 02101 /* 02102 * Obtain subsystem partitioned as submachines. 02103 */ 02104 flagValue = Cmd_FlagReadByName("amc_grouping_method"); 02105 if( (flagValue != NIL(char)) && 02106 (strcmp(flagValue, "latch_dependency")) == 0){ 02107 02108 subsystemInfo = Part_PartitionSubsystemInfoInit(network); 02109 Part_PartitionSubsystemInfoSetBound(subsystemInfo, numOfVertex); 02110 partitionArray = Part_PartCreateSubsystems(subsystemInfo, NIL(array_t), 02111 NIL(array_t)); 02112 02113 Part_PartitionSubsystemInfoFree(subsystemInfo); 02114 02115 } 02116 else{ 02117 /* 02118 * Latches which have dependency relation with given formulae 02119 * are computed and grouped into sub-systems. 02120 */ 02121 lsGen gen; 02122 Ntk_Node_t *node; 02123 char *name; 02124 array_t *arrayOfDataInputName; 02125 lsList latchInputList = lsCreate(); 02126 02127 if (latchInputList == (lsList)0){ 02128 return NIL(array_t); 02129 } 02130 02131 ctlArray = array_alloc(Ctlp_Formula_t *, 1); 02132 array_insert(Ctlp_Formula_t *, ctlArray, 0, formula); 02133 02134 if (!Part_PartitionGetLatchInputListFromCTL(network, ctlArray, 02135 NIL(array_t), 02136 latchInputList)) { 02137 array_free(ctlArray); 02138 return NIL(array_t); 02139 } 02140 arrayOfDataInputName = array_alloc(Ntk_Node_t *, lsLength(latchInputList)); 02141 lsForEachItem(latchInputList, gen, node){ 02142 name = Ntk_NodeReadName(node); 02143 array_insert_last(char *, arrayOfDataInputName, name); 02144 } 02145 lsDestroy(latchInputList, (void (*)(lsGeneric))0); 02146 array_sort(arrayOfDataInputName, stringCompare); 02147 02148 partitionArray = Part_PartGroupVeriticesBasedOnHierarchy(network, 02149 arrayOfDataInputName); 02150 array_free(arrayOfDataInputName); 02151 array_free(ctlArray); 02152 } 02153 02154 subSystemArray = array_alloc(Amc_SubsystemInfo_t *, array_n(partitionArray)); 02155 02156 02157 /* 02158 * For each partitioned submachines build an FSM. 02159 */ 02160 arrayForEachItem(Part_Subsystem_t *, partitionArray, i, partitionSubsystem) { 02161 Fsm_Fsm_t *fsm; 02162 02163 vertexTable = Part_PartitionSubsystemReadVertexTable(partitionSubsystem); 02164 fanInIndexArray = Part_PartitionSubsystemReadFanIn(partitionSubsystem); 02165 fanOutIndexArray = Part_PartitionSubsystemReadFanOut(partitionSubsystem); 02166 02167 FREE(partitionSubsystem); 02168 02169 fsm = Fsm_FsmCreateSubsystemFromNetwork(network, partition, vertexTable, 02170 FALSE, 0); 02171 02172 subSystem = Amc_AmcSubsystemCreate(fsm, NIL(mdd_t), vertexTable, 02173 /* NIL(st_table), NIL(st_table) ); */ 02174 (st_table *)fanInIndexArray, 02175 (st_table *)fanOutIndexArray); 02176 array_insert_last(Amc_SubsystemInfo_t *, subSystemArray, subSystem); 02177 } /* end of arrayForEachItem(partitionArray) */ 02178 02179 array_free(partitionArray); 02180 02181 /* 02182 * Convert fanInIndexTable to fanInSystemTable 02183 * Convert fanOutIndexTable to fanOutSystemTable 02184 */ 02185 arrayForEachItem(Amc_SubsystemInfo_t *, subSystemArray, i, subSystem) { 02186 02187 fanInIndexArray = (array_t *) AmcSubsystemReadFanInTable(subSystem); 02188 fanInSystemTable = st_init_table(st_ptrcmp, st_ptrhash); 02189 02190 if( fanInIndexArray != NIL(array_t) ) { 02191 arrayForEachItem(int, fanInIndexArray, j, fanInIndex) { 02192 02193 fanInSubsystem = array_fetch(Amc_SubsystemInfo_t *, subSystemArray, 02194 fanInIndex); 02195 st_insert(fanInSystemTable, (char *)fanInSubsystem, NIL(char)); 02196 02197 } 02198 array_free(fanInIndexArray); 02199 } 02200 02201 AmcSubsystemSetFanInTable(subSystem, fanInSystemTable); 02202 02203 02204 fanOutIndexArray = (array_t *) AmcSubsystemReadFanOutTable(subSystem); 02205 fanOutSystemTable = st_init_table(st_ptrcmp, st_ptrhash); 02206 02207 if( fanOutIndexArray != NIL(array_t) ) { 02208 arrayForEachItem(int, fanOutIndexArray, j, fanOutIndex) { 02209 02210 fanOutSubsystem = array_fetch(Amc_SubsystemInfo_t *, subSystemArray, 02211 fanOutIndex); 02212 st_insert(fanOutSystemTable, (char *)fanOutSubsystem, NIL(char)); 02213 02214 } 02215 array_free(fanOutIndexArray); 02216 } 02217 02218 AmcSubsystemSetFanOutTable(subSystem, fanOutSystemTable); 02219 02220 } 02221 02222 02223 return subSystemArray; 02224 } 02225 02236 void 02237 AmcPrintOptimalSystem( 02238 FILE *fp, 02239 Amc_Info_t *amcInfo) 02240 { 02241 int i; 02242 Amc_SubsystemInfo_t *subSystem; 02243 02244 fprintf(fp, "\nSubsystems in optimal path : "); 02245 02246 arrayForEachItem(Amc_SubsystemInfo_t *, amcInfo->subSystemArray, i, subSystem) { 02247 02248 if(subSystem->takenIntoOptimal) 02249 fprintf(fp, " %d ", i); 02250 02251 } 02252 02253 } 02254 02255 #ifdef AMC_DEBUG 02256 02265 void 02266 AmcCheckSupportAndOutputFunctions( 02267 array_t *subSystemArray) 02268 { 02269 int i; 02270 Amc_SubsystemInfo_t *subSystem; 02271 arrayForEachItem(Amc_SubsystemInfo_t *, subSystemArray, i, subSystem) { 02272 Fsm_Fsm_t *subSystemFsm = AmcSubsystemReadFsm(subSystem); 02273 Ntk_Network_t *network = Fsm_FsmReadNetwork(subSystemFsm); 02274 mdd_manager *mddManager = Ntk_NetworkReadMddManager(network); 02275 graph_t *partition = Part_NetworkReadPartition(network); 02276 02277 st_table *vertexTable = AmcSubsystemReadVertexTable(subSystem); 02278 st_generator *stGen; 02279 char *latchName; 02280 02281 st_foreach_item(vertexTable, stGen, &latchName, NIL(char *)) { 02282 02283 Ntk_Node_t *latch = Ntk_NetworkFindNodeByName(network, latchName); 02284 int functionMddId = Ntk_NodeReadMddId(Ntk_NodeReadShadow(latch)); 02285 02286 char *nameLatchDataInput = Ntk_NodeReadName(Ntk_LatchReadDataInput(latch)); 02287 vertex_t *ptrVertex = Part_PartitionFindVertexByName(partition, nameLatchDataInput); 02288 Mvf_Function_t *nextStateFunction; 02289 st_table *supportTable; 02290 02291 nextStateFunction = Part_VertexReadFunction(ptrVertex); 02292 supportTable = AmcCreateFunctionSupportTable(nextStateFunction); 02293 02294 /* print the name of the latch vars and its mddId in this subsystem*/ 02295 fprintf(vis_stdout, "\nSubsystem %d : Has latch : %s MddId : %d", 02296 i, latchName, Ntk_NodeReadMddId(latch)); 02297 fprintf(vis_stdout, "\n\tIts corresponding next state var : %s MddId : %d", 02298 Ntk_NodeReadName(Ntk_NodeReadShadow(latch)), 02299 Ntk_NodeReadMddId(Ntk_NodeReadShadow(latch)) ); 02300 02301 /* print the name of the output function and its mddId */ 02302 { 02303 int outputMddId = Ntk_NodeReadMddId(Ntk_LatchReadDataInput(latch)); 02304 fprintf(vis_stdout, "\n\tIts output function Output Function : %s MddId : %d", 02305 nameLatchDataInput, outputMddId); 02306 } 02307 02308 /* print the support of its output function */ 02309 { 02310 st_generator *stGen2; 02311 long supportId; 02312 st_foreach_item(supportTable, stGen2, (char **)&supportId, NIL(char *)) { 02313 Ntk_Node_t *supportNode = Ntk_NetworkFindNodeByMddId(network, (int) supportId); 02314 char *supportName = Ntk_NodeReadName(supportNode); 02315 fprintf(vis_stdout, "\n\tOutput function's support : %s MddId : %d", 02316 supportName, (int) supportId); 02317 fflush(vis_stdout); 02318 } 02319 } 02320 02321 02322 } /* end of st_foreach_item */ 02323 02324 } /* end of ArrayForEachItem */ 02325 02326 02327 /* Print the name of the present state vars and its mddId */ 02328 /* Print the name of the next state vars and its mddId */ 02329 /* Print the input vars */ 02330 { 02331 Amc_SubsystemInfo_t *subSystem = array_fetch(Amc_SubsystemInfo_t *, subSystemArray, 0); 02332 Fsm_Fsm_t *subSystemFsm = AmcSubsystemReadFsm(subSystem); 02333 Ntk_Network_t *network = Fsm_FsmReadNetwork(subSystemFsm); 02334 lsGen gen; Ntk_Node_t *inputNode; 02335 Ntk_NetworkForEachPrimaryInput(network, gen, inputNode) { 02336 fprintf(vis_stdout, "\nPrimary Input : %s MddId : %d", 02337 Ntk_NodeReadName(inputNode), Ntk_NodeReadMddId(inputNode)); 02338 } 02339 } 02340 02341 /* Print the pseudo input vars */ 02342 { 02343 Amc_SubsystemInfo_t *subSystem = array_fetch(Amc_SubsystemInfo_t *, subSystemArray, 0); 02344 Fsm_Fsm_t *subSystemFsm = AmcSubsystemReadFsm(subSystem); 02345 Ntk_Network_t *network = Fsm_FsmReadNetwork(subSystemFsm); 02346 lsGen gen; Ntk_Node_t *inputNode; 02347 Ntk_NetworkForEachPseudoInput(network, gen, inputNode) { 02348 fprintf(vis_stdout, "\nPseudo Input : %s MddId : %d", 02349 Ntk_NodeReadName(inputNode), Ntk_NodeReadMddId(inputNode)); 02350 fflush(vis_stdout); 02351 } 02352 } 02353 02354 } 02355 02365 st_table * 02366 AmcCreateFunctionSupportTable( 02367 Mvf_Function_t *mvf) 02368 { 02369 mdd_manager *mddManager; /* Manager for the MDDs */ 02370 array_t *support; 02371 st_table *mddSupport = st_init_table(st_numcmp, st_numhash); 02372 int numComponents = Mvf_FunctionReadNumComponents(mvf); 02373 int j, k; 02374 mdd_t *unit; 02375 02376 assert(numComponents!= 0); 02377 02378 mddManager = Mvf_FunctionReadMddManager(mvf); 02379 02380 /* 02381 * compute the support of an mdd as the union of supports of every 02382 * function component 02383 */ 02384 for(j = 0; j < numComponents; j++) { 02385 unit = Mvf_FunctionReadComponent(mvf, j); 02386 support = mdd_get_support(mddManager, unit); 02387 02388 /* For every element of its support */ 02389 for(k = 0; k < array_n(support); k++) { 02390 st_insert(mddSupport, (char *)(long)array_fetch(int, support, k), (char *)0); 02391 } /* End of for */ 02392 array_free(support); 02393 } /* End of for */ 02394 02395 return mddSupport; 02396 } /* End of */ 02397 #endif 02398 02399 02410 mdd_t * 02411 AmcModelCheckAtomicFormula( 02412 Fsm_Fsm_t *modelFsm, 02413 Ctlp_Formula_t *ctlFormula) 02414 { 02415 mdd_t * resultMdd; 02416 mdd_t *tmpMdd; 02417 Ntk_Network_t *network = Fsm_FsmReadNetwork( modelFsm ); 02418 char *nodeNameString = Ctlp_FormulaReadVariableName( ctlFormula ); 02419 char *nodeValueString = Ctlp_FormulaReadValueName( ctlFormula ); 02420 Ntk_Node_t *node = Ntk_NetworkFindNodeByName( network, nodeNameString ); 02421 02422 Var_Variable_t *nodeVar; 02423 int nodeValue; 02424 02425 graph_t *modelPartition; 02426 vertex_t *partitionVertex; 02427 Mvf_Function_t *MVF; 02428 02429 nodeVar = Ntk_NodeReadVariable( node ); 02430 if ( Var_VariableTestIsSymbolic( nodeVar ) ){ 02431 nodeValue = Var_VariableReadIndexFromSymbolicValue( nodeVar, nodeValueString ); 02432 } 02433 else { 02434 nodeValue = atoi( nodeValueString ); 02435 } 02436 02437 modelPartition = Part_NetworkReadPartition( network ); 02438 if ( !( partitionVertex = Part_PartitionFindVertexByName( modelPartition, 02439 nodeNameString ) )) { 02440 lsGen tmpGen; 02441 Ntk_Node_t *tmpNode; 02442 array_t *mvfArray; 02443 array_t *tmpRoots = array_alloc( Ntk_Node_t *, 0 ); 02444 st_table *tmpLeaves = st_init_table( st_ptrcmp, st_ptrhash ); 02445 array_insert_last( Ntk_Node_t *, tmpRoots, node ); 02446 02447 Ntk_NetworkForEachCombInput( network, tmpGen, tmpNode ) { 02448 st_insert( tmpLeaves, (char *) tmpNode, (char *) NTM_UNUSED ); 02449 } 02450 02451 mvfArray = Ntm_NetworkBuildMvfs( network, tmpRoots, tmpLeaves, 02452 NIL(mdd_t) ); 02453 MVF = array_fetch( Mvf_Function_t *, mvfArray, 0 ); 02454 array_free( tmpRoots ); 02455 st_free_table( tmpLeaves ); 02456 array_free( mvfArray ); 02457 02458 tmpMdd = Mvf_FunctionReadComponent( MVF, nodeValue ); 02459 resultMdd = mdd_dup( tmpMdd ); 02460 Mvf_FunctionFree( MVF ); 02461 return resultMdd; 02462 } 02463 else { 02464 MVF = Part_VertexReadFunction( partitionVertex ); 02465 tmpMdd = Mvf_FunctionReadComponent( MVF, nodeValue ); 02466 resultMdd = mdd_dup( tmpMdd ); 02467 return resultMdd; 02468 } 02469 } 02470 02471 02472 /*---------------------------------------------------------------------------*/ 02473 /* Definition of static functions */ 02474 /*---------------------------------------------------------------------------*/ 02482 static int 02483 stringCompare( 02484 const void * s1, 02485 const void * s2) 02486 { 02487 return(strcmp(*(char **)s1, *(char **)s2)); 02488 }