VIS
|
00001 00032 #include "mcInt.h" 00033 #include "mdd.h" 00034 #include "cmd.h" 00035 #include "fsm.h" 00036 #include "img.h" 00037 #include "sat.h" 00038 #include "baig.h" 00039 #include <errno.h> 00040 00041 static char rcsid[] UNUSED = "$Id: mcUtil.c,v 1.113 2009/04/11 18:26:10 fabio Exp $"; 00042 00043 /*---------------------------------------------------------------------------*/ 00044 /* Macro declarations */ 00045 /*---------------------------------------------------------------------------*/ 00046 00047 00050 /*---------------------------------------------------------------------------*/ 00051 /* Static function prototypes */ 00052 /*---------------------------------------------------------------------------*/ 00053 00054 static void PrintNodes(array_t *mddIdArray, Ntk_Network_t *network); 00055 static array_t * SortMddIds(array_t *mddIdArray, Ntk_Network_t *network); 00056 static void PrintDeck(array_t *mddValues, array_t *mddIdArray, Ntk_Network_t *network); 00057 static int cmp(const void * s1, const void * s2); 00058 static boolean AtomicFormulaCheckSemantics(Ctlp_Formula_t *formula, Ntk_Network_t *network, boolean inputsAllowed); 00059 static void NodeTableAddCtlFormulaNodes(Ntk_Network_t *network, Ctlp_Formula_t *formula, st_table * nodesTable); 00060 static void NodeTableAddLtlFormulaNodes(Ntk_Network_t *network, Ctlsp_Formula_t *formula, st_table * nodesTable); 00061 static boolean MintermCheckWellFormed(mdd_t *aMinterm, array_t *aSupport, mdd_manager *mddMgr); 00062 static boolean SetCheckSupport(mdd_t *aMinterm, array_t *aSupport, mdd_manager *mddMgr); 00063 static mdd_t * Mc_ComputeRangeOfPseudoInputs(Ntk_Network_t *network); 00064 static array_t *Mc_BuildBackwardRingsWithInvariants(mdd_t *S, mdd_t *T, mdd_t *invariants, Fsm_Fsm_t *fsm); 00065 00069 /*---------------------------------------------------------------------------*/ 00070 /* Definition of exported functions */ 00071 /*---------------------------------------------------------------------------*/ 00072 00086 int 00087 Mc_FsmComputeStatesReachingToSet( 00088 Fsm_Fsm_t *modelFsm, 00089 mdd_t *targetStates, 00090 array_t *careStatesArray, 00091 mdd_t *specialStates, 00092 array_t *onionRings, 00093 Mc_VerbosityLevel verbosity, 00094 Mc_DcLevel dcLevel) 00095 { 00096 mdd_t *fromUpperBound; 00097 mdd_t *toCareSet; 00098 array_t *toCareSetArray = array_alloc(mdd_t *, 0); 00099 mdd_t *image; 00100 Img_ImageInfo_t *imageInfo = Fsm_FsmReadOrCreateImageInfo(modelFsm, 1, 0); 00101 00102 mdd_t *reachingStates = mdd_dup( targetStates ); 00103 mdd_t *fromLowerBound = mdd_dup( targetStates ); 00104 00105 /* Iterate until fromLowerBound is empty. */ 00106 while (mdd_is_tautology(fromLowerBound, 0) == 0){ 00107 /* fromLowerBound is the "onion shell" of states just examined. */ 00108 array_insert_last(mdd_t*, onionRings, 00109 mdd_dup(fromLowerBound)); 00110 if ( !mdd_lequal( fromLowerBound, specialStates, 1, 0 ) ) { 00111 mdd_free( fromLowerBound ); 00112 mdd_free( reachingStates ); 00113 return TRUE; 00114 } 00115 00116 /* fromUpperBound is the set of all states reaching targets thus far. */ 00117 fromUpperBound = mdd_dup( reachingStates ); 00118 00119 /* toCareSet is the set of all states not reached so far. */ 00120 toCareSet = mdd_not(reachingStates); 00121 array_insert(mdd_t *, toCareSetArray, 0, toCareSet); 00122 00123 /* 00124 * Pre-Image of some set between lower and upper, where we care 00125 * about the image only on unreaching states. 00126 */ 00127 image = Img_ImageInfoComputePreImageWithDomainVars(imageInfo, 00128 fromLowerBound, fromUpperBound, toCareSetArray); 00129 mdd_free(toCareSet); 00130 mdd_free(fromLowerBound); 00131 00132 /* New set of reaching states is old set plus new image. */ 00133 mdd_free( reachingStates ); 00134 reachingStates = mdd_or(fromUpperBound, image, 1, 1); 00135 mdd_free(image); 00136 00137 /* 00138 * New lower bound is the states just reached (note not on 00139 * fromUpperBound). 00140 */ 00141 fromLowerBound = mdd_and(reachingStates, fromUpperBound, 1, 0); 00142 00143 mdd_free(fromUpperBound); 00144 } 00145 mdd_array_free( onionRings ); 00146 mdd_free( reachingStates ); 00147 mdd_free(fromLowerBound); 00148 array_free(toCareSetArray); 00149 00150 return FALSE; 00151 } 00152 00166 int 00167 Mc_FsmComputeStatesReachableFromSet( 00168 Fsm_Fsm_t *modelFsm, 00169 mdd_t *initialStates, 00170 array_t *careStatesArray, 00171 mdd_t *specialStates, 00172 array_t *onionRings, 00173 Mc_VerbosityLevel verbosity, 00174 Mc_DcLevel dcLevel) 00175 { 00176 boolean reachable=FALSE; 00177 mdd_t *fromUpperBound; 00178 mdd_t *toCareSet; 00179 array_t *toCareSetArray = array_alloc(mdd_t *, 0); 00180 mdd_t *image; 00181 Img_ImageInfo_t *imageInfo = Fsm_FsmReadOrCreateImageInfo(modelFsm, 0, 1); 00182 00183 mdd_t *reachableStates = mdd_dup( initialStates ); 00184 mdd_t *fromLowerBound = mdd_dup( initialStates ); 00185 00186 /* Iterate until fromLowerBound is empty. */ 00187 while (mdd_is_tautology(fromLowerBound, 0) == 0){ 00188 /* fromLowerBound is the "onion shell" of states just reached. */ 00189 array_insert_last(mdd_t*, onionRings, 00190 mdd_dup(fromLowerBound)); 00191 if (!mdd_lequal( fromLowerBound, specialStates, 1, 0 ) ) { 00192 mdd_free( fromLowerBound ); 00193 mdd_free( reachableStates ); 00194 return TRUE; 00195 } 00196 00197 /* fromUpperBound is the set of all states reached thus far. */ 00198 fromUpperBound = mdd_dup( reachableStates ); 00199 00200 /* toCareSet is the set of all states not reached so far. */ 00201 toCareSet = mdd_not(reachableStates); 00202 array_insert(mdd_t *, toCareSetArray, 0, toCareSet); 00203 00204 /* 00205 * Image of some set between lower and upper, where we care 00206 * about the image only on unreached states. 00207 */ 00208 image = Img_ImageInfoComputeImageWithDomainVars(imageInfo, 00209 fromLowerBound, fromUpperBound, toCareSetArray); 00210 mdd_free(toCareSet); 00211 mdd_free(fromLowerBound); 00212 00213 /* New set of reachable states is old set plus new image. */ 00214 mdd_free( reachableStates ); 00215 reachableStates = mdd_or(fromUpperBound, image, 1, 1); 00216 mdd_free(image); 00217 00218 /* 00219 * New lower bound is the states just reached (note not on 00220 * fromUpperBound). 00221 */ 00222 fromLowerBound = mdd_and(reachableStates, fromUpperBound, 1, 0); 00223 mdd_free(fromUpperBound); 00224 } 00225 mdd_array_free( onionRings ); 00226 mdd_free( reachableStates ); 00227 mdd_free(fromLowerBound); 00228 array_free(toCareSetArray); 00229 00230 return reachable; 00231 00232 } 00233 00248 boolean 00249 Mc_FormulaStaticSemanticCheckOnNetwork( 00250 Ctlp_Formula_t *formula, 00251 Ntk_Network_t *network, 00252 boolean inputsAllowed 00253 ) 00254 { 00255 boolean lCheck; 00256 boolean rCheck; 00257 Ctlp_Formula_t *leftChild; 00258 Ctlp_Formula_t *rightChild; 00259 00260 if(formula == NIL(Ctlp_Formula_t)){ 00261 return TRUE; 00262 } 00263 00264 if(Ctlp_FormulaReadType(formula) == Ctlp_ID_c){ 00265 return AtomicFormulaCheckSemantics(formula, network, inputsAllowed); 00266 } 00267 00268 leftChild = Ctlp_FormulaReadLeftChild(formula); 00269 rightChild = Ctlp_FormulaReadRightChild(formula); 00270 00271 lCheck = Mc_FormulaStaticSemanticCheckOnNetwork(leftChild, network, 00272 inputsAllowed); 00273 if(!lCheck) 00274 return FALSE; 00275 00276 rCheck = Mc_FormulaStaticSemanticCheckOnNetwork(rightChild, network, 00277 inputsAllowed); 00278 if (!rCheck) 00279 return FALSE; 00280 00281 return TRUE; 00282 } 00283 00304 array_t * 00305 Mc_BuildPathToCore( 00306 mdd_t *aState, 00307 array_t *onionRings, 00308 Fsm_Fsm_t *modelFsm, 00309 Mc_PathLengthType PathLengthType) 00310 { 00311 int i; /* index into the onionRings */ 00312 int startingPoint; 00313 mdd_t *currentState; 00314 Img_ImageInfo_t * imageInfo = Fsm_FsmReadOrCreateImageInfo(modelFsm, 0, 1); 00315 array_t *pathToCore; 00316 mdd_manager *mddMgr = Fsm_FsmReadMddManager(modelFsm); 00317 array_t *toCareSetArray; 00318 00319 if(Fsm_FsmReadUniQuantifyInputCube(modelFsm)) { 00320 return(Mc_BuildPathToCoreFAFW( 00321 aState, onionRings, modelFsm, PathLengthType)); 00322 } 00323 00324 pathToCore = array_alloc( mdd_t * , 0 ); 00325 toCareSetArray = array_alloc(mdd_t *, 0); 00326 array_insert_last(mdd_t *, toCareSetArray, mdd_one(mddMgr)); 00327 00328 if ( PathLengthType == McGreaterZero_c ) 00329 startingPoint = 1; 00330 else if ( PathLengthType == McGreaterOrEqualZero_c ) 00331 startingPoint = 0; 00332 else 00333 fail("Called Mc_BuildPathToCore with ill formed PathLengthType\n"); 00334 00335 /* RB: How do you guarantee that aState is in one of the onion rings [1,n]?*/ 00336 00337 /*Find the lowest ring that holds aState*/ 00338 for ( i = startingPoint ; i < array_n( onionRings ); i++ ) { 00339 mdd_t *ring = array_fetch( mdd_t *, onionRings, i ); 00340 if ( McStateTestMembership( aState, ring ) ) 00341 break; 00342 } 00343 if ( i == array_n( onionRings ) ) 00344 return NIL(array_t); 00345 00346 currentState = mdd_dup( aState ); 00347 array_insert_last( mdd_t *, pathToCore, currentState ); 00348 00349 /* until we get to ring 0, keep finding successors for currentState */ 00350 while( i > 0 ) { 00351 mdd_t *currentStateSuccs; 00352 mdd_t *innerRing; 00353 mdd_t *currentStateSuccsInInnerRing; 00354 mdd_t *witnessSuccState; 00355 00356 i--; 00357 00358 currentStateSuccs = 00359 Img_ImageInfoComputeImageWithDomainVars(imageInfo, currentState, 00360 currentState, toCareSetArray); 00361 currentStateSuccsInInnerRing = mdd_zero(mddMgr); 00362 00363 /* find the highest ring that contains a successor, starting with i */ 00364 while(mdd_is_tautology(currentStateSuccsInInnerRing, 0)){ 00365 assert(i >= 0); 00366 if(i < 0) return NIL(array_t); 00367 00368 innerRing = array_fetch( mdd_t *, onionRings, i ); 00369 mdd_free(currentStateSuccsInInnerRing); 00370 currentStateSuccsInInnerRing = mdd_and(currentStateSuccs, innerRing, 00371 1, 1 ); 00372 i--; 00373 } 00374 00375 i++; 00376 00377 witnessSuccState = Mc_ComputeACloseState(currentStateSuccsInInnerRing, 00378 currentState, 00379 modelFsm ); 00380 array_insert_last( mdd_t *, pathToCore, witnessSuccState ); 00381 currentState = witnessSuccState; 00382 00383 mdd_free( currentStateSuccs ); 00384 mdd_free( currentStateSuccsInInnerRing ); 00385 00386 /* next, see if we cannot move a few more rings down. We have to do this, 00387 * since a nontrivial path is not guaranteed to exist from a node in ring i 00388 * to a node in a lower ring. In fact a state in ring i may also be in 00389 * ring 0. */ 00390 { 00391 boolean contained = TRUE; 00392 while(contained && i > 0){ 00393 i--; 00394 innerRing = array_fetch( mdd_t *, onionRings, i ); 00395 contained = mdd_lequal(witnessSuccState, innerRing, 1, 1); 00396 } 00397 /* i is highest ring not containing witnessSuccState, or i = 0 */ 00398 00399 if(!contained){ 00400 i++; 00401 } 00402 /* i is lowest ring containing witnessSuccState */ 00403 } 00404 } 00405 00406 mdd_array_free(toCareSetArray); 00407 00408 return pathToCore; 00409 } 00410 00421 array_t * 00422 Mc_BuildForwardRings( 00423 mdd_t *S, 00424 Fsm_Fsm_t *fsm, 00425 array_t *onionRings) 00426 { 00427 mdd_t *nextStates; 00428 mdd_t *states, *nStates, *oneMdd; 00429 array_t *toCareSetArray, *forwardRings; 00430 int i; 00431 mdd_manager *mddMgr = Fsm_FsmReadMddManager(fsm); 00432 00433 states = mdd_zero(mddMgr); 00434 oneMdd = mdd_one(mddMgr); 00435 for(i=0; i<array_n(onionRings); i++) { 00436 mdd_t *ring = array_fetch( mdd_t *, onionRings, i ); 00437 nStates = mdd_or(ring, states, 1, 1); 00438 mdd_free(states); 00439 states = nStates; 00440 } 00441 forwardRings = array_alloc(mdd_t *, 0); 00442 toCareSetArray = array_alloc(mdd_t *, 0); 00443 array_insert(mdd_t *, toCareSetArray, 0, oneMdd); 00444 nextStates = Mc_FsmEvaluateESFormula(fsm, states, S, 00445 NIL(mdd_t), oneMdd, toCareSetArray, 00446 MC_NO_EARLY_TERMINATION, NIL(array_t), 00447 Mc_None_c, forwardRings, 00448 McVerbosityNone_c, McDcLevelNone_c, 00449 NIL(boolean)); 00450 mdd_free(nextStates); 00451 mdd_free(states); 00452 mdd_array_free(toCareSetArray); 00453 00454 return(forwardRings); 00455 } 00456 00467 array_t * 00468 Mc_BuildForwardRingsWithInvariants(mdd_t *S, 00469 mdd_t *T, 00470 mdd_t *invariants, 00471 Fsm_Fsm_t *fsm) 00472 { 00473 mdd_t *oneMdd, *nextStates, *fairStates; 00474 array_t *toCareSetArray, *forwardRings; 00475 mdd_manager *mddMgr = Fsm_FsmReadMddManager(fsm); 00476 00477 oneMdd = mdd_one(mddMgr); 00478 forwardRings = array_alloc(mdd_t *, 0); 00479 toCareSetArray = array_alloc(mdd_t *, 0); 00480 array_insert(mdd_t *, toCareSetArray, 0, oneMdd); 00481 fairStates = Fsm_FsmReadFairnessStates(fsm); 00482 if(fairStates == 0) fairStates = oneMdd; 00483 nextStates = McEvaluateESFormulaWithGivenTRWithTarget(fsm, invariants, S, T, 00484 NIL(mdd_t), fairStates, toCareSetArray, 00485 MC_NO_EARLY_TERMINATION, 00486 forwardRings, McVerbosityNone_c, 00487 McDcLevelNone_c, NIL(boolean)); 00488 mdd_free(nextStates); 00489 mdd_array_free(toCareSetArray); 00490 00491 return(forwardRings); 00492 } 00493 00504 static array_t * 00505 Mc_BuildBackwardRingsWithInvariants( 00506 mdd_t *S, 00507 mdd_t *T, 00508 mdd_t *invariants, 00509 Fsm_Fsm_t *fsm) 00510 { 00511 mdd_t *oneMdd, *nextStates, *fairStates; 00512 array_t *toCareSetArray, *backwardRings; 00513 mdd_manager *mddMgr = Fsm_FsmReadMddManager(fsm); 00514 00515 oneMdd = mdd_one(mddMgr); 00516 backwardRings = array_alloc(mdd_t *, 0); 00517 toCareSetArray = array_alloc(mdd_t *, 0); 00518 array_insert(mdd_t *, toCareSetArray, 0, oneMdd); 00519 fairStates = Fsm_FsmReadFairnessStates(fsm); 00520 if(fairStates == 0) fairStates = oneMdd; 00521 nextStates = McEvaluateEUFormulaWithGivenTR(fsm, invariants, T, 00522 NIL(mdd_t), fairStates, toCareSetArray, 00523 MC_NO_EARLY_TERMINATION, 00524 backwardRings, McVerbosityNone_c, 00525 McDcLevelNone_c, NIL(boolean)); 00526 mdd_free(nextStates); 00527 mdd_array_free(toCareSetArray); 00528 00529 return(backwardRings); 00530 } 00531 00557 array_t * 00558 Mc_BuildPathFromCore( 00559 mdd_t *aStates, 00560 array_t *onionRings, 00561 Fsm_Fsm_t *modelFsm, 00562 Mc_PathLengthType PathLengthType) 00563 { 00564 int i, j; 00565 int startingPoint; 00566 mdd_t *currentState, *aState; 00567 Img_ImageInfo_t * imageInfo = Fsm_FsmReadOrCreateImageInfo(modelFsm, 1, 0); 00568 array_t *pathToCore; 00569 mdd_manager *mddMgr = Fsm_FsmReadMddManager(modelFsm); 00570 array_t *toCareSetArray; 00571 array_t *pathFromCore; 00572 mdd_t *currentStatePreds, *currentStatePredsInInnerRing; 00573 mdd_t *innerRing = NIL(mdd_t), *witnessPredState; 00574 boolean shortestDist = 00575 (Fsm_FsmReadReachabilityOnionRingsMode(modelFsm) == Fsm_Rch_Bfs_c); 00576 00577 00578 if(Fsm_FsmReadUniQuantifyInputCube(modelFsm)) { 00579 pathFromCore = Mc_BuildPathFromCoreFAFW( 00580 aStates, onionRings, 00581 modelFsm, PathLengthType); 00582 return(pathFromCore); 00583 } 00584 aState = Mc_ComputeAState(aStates, modelFsm); 00585 00586 pathToCore = array_alloc( mdd_t * , 0 ); 00587 toCareSetArray = NIL(array_t); 00588 00589 if ( PathLengthType == McGreaterZero_c ) { 00590 startingPoint = 1; 00591 } 00592 else if ( PathLengthType == McGreaterOrEqualZero_c ) { 00593 startingPoint = 0; 00594 } 00595 else { 00596 fail("Called Mc_BuildPathFromCore with ill formed PathLengthType\n"); 00597 } 00598 00599 /* check that the state occurs in an onion ring. */ 00600 for ( i = startingPoint ; i < array_n( onionRings ); i++ ) { 00601 mdd_t *ring = array_fetch( mdd_t *, onionRings, i ); 00602 if ( McStateTestMembership( aState, ring ) ) 00603 break; 00604 } 00605 if ( i == array_n( onionRings ) ) { 00606 mdd_free(aState); 00607 return NIL(array_t); 00608 } 00609 00610 /* insert the state in the path to the core */ 00611 currentState = aState; 00612 array_insert_last( mdd_t *, pathToCore, currentState ); 00613 00614 /* initialize */ 00615 toCareSetArray = array_alloc(mdd_t *, 0); 00616 array_insert_last(mdd_t *, toCareSetArray, mdd_one(mddMgr)); 00617 00618 /* loop until a path is found to the core */ 00619 while( i-- > 0 ) { 00620 if (shortestDist) { 00621 /* a predecessor is guaranteed to be in the previous ring */ 00622 mdd_array_free(toCareSetArray); 00623 toCareSetArray = array_alloc(mdd_t *, 0); 00624 innerRing = array_fetch( mdd_t *, onionRings, i ); 00625 array_insert(mdd_t *, toCareSetArray, 0, mdd_dup(innerRing)); 00626 currentStatePreds = Img_ImageInfoComputePreImageWithDomainVars( 00627 imageInfo, currentState, 00628 currentState, toCareSetArray); 00629 } else { 00630 /* compute the predecessors */ 00631 currentStatePreds = Img_ImageInfoComputePreImageWithDomainVars( 00632 imageInfo, currentState, 00633 currentState, toCareSetArray ); 00634 /* search for a predecessor in the earliest onion ring */ 00635 for (j = 0; j <= i; j++) { 00636 innerRing = array_fetch( mdd_t *, onionRings, j ); 00637 if (!mdd_lequal(currentStatePreds, innerRing, 1, 0)) { 00638 i = j; 00639 break; 00640 } 00641 } 00642 } 00643 /* compute the set of predecessors in the chosen ring. */ 00644 currentStatePredsInInnerRing = mdd_and(currentStatePreds, innerRing, 1, 1); 00645 mdd_free( currentStatePreds ); 00646 /* find a state in the predecessor */ 00647 witnessPredState = Mc_ComputeACloseState(currentStatePredsInInnerRing, 00648 currentState, modelFsm); 00649 mdd_free( currentStatePredsInInnerRing ); 00650 /* insert predecessor in the path */ 00651 array_insert_last( mdd_t *, pathToCore, witnessPredState ); 00652 currentState = witnessPredState; 00653 } 00654 00655 mdd_array_free(toCareSetArray); 00656 00657 /* flip the path to a path from the core */ 00658 { 00659 int i; 00660 pathFromCore = array_alloc( mdd_t *, 0 ); 00661 00662 for( i=0; i < array_n( pathToCore ); i++ ) { 00663 mdd_t *tmpMdd = array_fetch(mdd_t *, pathToCore, 00664 (array_n(pathToCore) - (i+1))); 00665 array_insert_last( mdd_t *, pathFromCore, tmpMdd ); 00666 } 00667 array_free( pathToCore ); 00668 return pathFromCore; 00669 } 00670 } 00671 00682 array_t * 00683 Mc_BuildPathToCoreFAFW( 00684 mdd_t *aStates, 00685 array_t *onionRings, 00686 Fsm_Fsm_t *modelFsm, 00687 Mc_PathLengthType PathLengthType) 00688 { 00689 int i, startingPoint; 00690 array_t *pathFromCore, *pathToCore; 00691 array_t *reachableOnionRings; 00692 mdd_t *currentStates; 00693 00694 if ( PathLengthType == McGreaterZero_c ) { 00695 startingPoint = 1; 00696 } 00697 else if ( PathLengthType == McGreaterOrEqualZero_c ) { 00698 startingPoint = 0; 00699 } 00700 else { 00701 fail("Called Mc_BuildPathToCore with ill formed PathLengthType\n"); 00702 } 00703 00704 for ( i = startingPoint ; i < array_n( onionRings ); i++ ) { 00705 mdd_t *ring = array_fetch( mdd_t *, onionRings, i ); 00706 if ( McStateTestMembership( aStates, ring ) ) 00707 break; 00708 } 00709 if(i==0) { 00710 pathToCore = array_alloc( mdd_t * , 0 ); 00711 array_insert_last( mdd_t *, pathToCore, mdd_dup(aStates) ); 00712 return pathToCore; 00713 } 00714 00715 reachableOnionRings = Mc_BuildForwardRings(aStates, modelFsm, onionRings); 00716 currentStates = array_fetch(mdd_t *, onionRings, 0); 00717 pathFromCore = Mc_BuildPathFromCoreFAFW( 00718 currentStates, 00719 reachableOnionRings, modelFsm, PathLengthType); 00720 mdd_array_free(reachableOnionRings); 00721 00722 return(pathFromCore); 00723 } 00724 00725 00736 array_t * 00737 Mc_BuildPathFromCoreFAFWGeneral( 00738 mdd_t *T, 00739 array_t *rings, 00740 Fsm_Fsm_t *modelFsm, 00741 Mc_PathLengthType PathLengthType) 00742 { 00743 mdd_manager *mgr = Fsm_FsmReadMddManager(modelFsm); 00744 mdd_t *S, *H, *nH, *ring; 00745 int i; 00746 array_t *L; 00747 array_t *pathFromCore; 00748 array_t *npathFromCore; 00749 00750 H = mdd_zero(mgr); 00751 for(i=0; i<array_n(rings); i++) { 00752 ring = array_fetch(mdd_t *, rings, i); 00753 nH = mdd_or(ring, H, 1, 1); 00754 mdd_free(H); 00755 H = nH; 00756 } 00757 00758 nH = mdd_and(H, T, 1, 1); 00759 T = nH; 00760 00761 L = Mc_BuildFAFWLayer(modelFsm, mdd_dup(T), mdd_dup(H)); 00762 00763 if ( PathLengthType == McGreaterZero_c ) { 00764 S = mdd_dup(array_fetch(mdd_t *, rings, 1)); 00765 } 00766 else if( PathLengthType == McGreaterOrEqualZero_c ) { 00767 S = mdd_dup(array_fetch(mdd_t *, rings, 0)); 00768 } 00769 else { 00770 fail("Called Mc_BuildPathFromCoreFAFW with ill formed PathLengthType\n"); 00771 } 00772 pathFromCore = 00773 MC_BuildCounterExampleFAFWGeneral(modelFsm, mdd_dup(S), mdd_dup(T), H, L); 00774 00775 if(PathLengthType == McGreaterZero_c ) { 00776 S = array_fetch(mdd_t *, rings, 0); 00777 npathFromCore = array_alloc(mdd_t *, 0); 00778 array_insert_last(mdd_t *, npathFromCore, mdd_dup(S)); 00779 for(i=0; i<array_n(pathFromCore); i++) { 00780 S = array_fetch(mdd_t *, pathFromCore, i); 00781 array_insert_last(mdd_t *, npathFromCore, S); 00782 } 00783 array_free(pathFromCore); 00784 pathFromCore = npathFromCore; 00785 } 00786 mdd_free(T); 00787 return(pathFromCore); 00788 } 00789 00790 00801 array_t * 00802 MC_BuildCounterExampleFAFWGeneral( 00803 Fsm_Fsm_t *modelFsm, 00804 mdd_t *I, 00805 mdd_t *T, 00806 mdd_t *H, 00807 array_t *L) 00808 { 00809 mdd_t *oneMdd, *zeroMdd; 00810 mdd_t *T_I, *P, *Li, *Q_Li, *Q_T, *nLi; 00811 mdd_t *ring, *ring_Q, *Q; 00812 mdd_t *layer, *Lm, *nLayer; 00813 mdd_t *extCube; 00814 mdd_t *invariantStates, *nInvariantStates; 00815 int m, q, free, i; 00816 array_t *path, *R; 00817 array_t *careStatesArray; 00818 Img_ImageInfo_t *imageInfo = Fsm_FsmReadOrCreateImageInfo(modelFsm, 1, 0); 00819 mdd_manager *mgr = Fsm_FsmReadMddManager(modelFsm); 00820 00821 oneMdd = mdd_one(mgr); 00822 zeroMdd = mdd_zero(mgr); 00823 path = array_alloc(mdd_t *, 0); 00824 00825 T_I = mdd_and(T, I, 1, 1); 00826 if(!mdd_equal(T_I, zeroMdd)) { 00827 mdd_free(oneMdd); 00828 mdd_free(zeroMdd); 00829 P = Mc_ComputeACloseState(T_I, T, modelFsm); 00830 mdd_free(T_I); 00831 array_insert_last(mdd_t *, path, P); 00832 return(path); 00833 } 00834 mdd_free(T_I); 00835 00836 extCube = Fsm_FsmReadExtQuantifyInputCube(modelFsm); 00837 invariantStates = mdd_zero(mgr); 00838 layer = NULL; 00839 Lm = NULL; 00840 for(m=0; m<array_n(L); m++) { 00841 layer = array_fetch(mdd_t *, L, m); 00842 nLayer = bdd_smooth_with_cube(layer, extCube); 00843 nInvariantStates = mdd_or(invariantStates, nLayer, 1, 1); 00844 mdd_free(nLayer); 00845 mdd_free(invariantStates); 00846 invariantStates = nInvariantStates; 00847 Lm = mdd_and(I, layer, 1, 1); 00848 if(!mdd_equal(Lm, zeroMdd)) { 00849 break; 00850 } 00851 mdd_free(Lm); 00852 } 00853 00854 R = Mc_BuildBackwardRingsWithInvariants(Lm, T, invariantStates, modelFsm); 00855 00856 imageInfo = Fsm_FsmReadOrCreateImageInfoFAFW(modelFsm, 0, 1); 00857 Img_ForwardImageInfoConjoinWithWinningStrategy(imageInfo, layer); 00862 i = m; 00863 Q = mdd_and(I, Lm, 1, 1); 00864 ring_Q = NULL; 00865 for(q=0; q<array_n(R); q++) { 00866 ring = array_fetch(mdd_t *, R, q); 00867 ring_Q = mdd_and(ring, Q, 1, 1); 00868 if(!mdd_equal(ring_Q, zeroMdd)) { 00869 break; 00870 } 00871 mdd_free(ring_Q); 00872 } 00873 mdd_free(Q); 00874 P = Mc_ComputeACloseState(ring_Q, T, modelFsm); 00875 mdd_free(ring_Q); 00876 00877 free = 0; 00878 careStatesArray = array_alloc(mdd_t *, 0); 00879 array_insert_last(mdd_t *, careStatesArray, oneMdd); 00880 while(1) { 00881 Q = Img_ImageInfoComputeImageWithDomainVars( 00882 imageInfo, P, P, careStatesArray); 00883 Q_T = mdd_and(Q, P, 1, 0); 00884 mdd_free(Q); 00885 Q = Q_T; 00886 00887 if(i>0) { 00888 Li = array_fetch(mdd_t *, L, i-1); 00889 nLi = bdd_smooth_with_cube(Li, extCube); 00890 Q_Li = mdd_and(Q, nLi, 1, 1); 00891 mdd_free(nLi); 00892 if(!mdd_equal(Q_Li, zeroMdd)) { 00893 i--; 00894 mdd_free(Q); 00895 Q = Q_Li; 00896 free = 1; 00897 imageInfo = Fsm_FsmReadOrCreateImageInfoFAFW(modelFsm, 0, 1); 00898 Img_ForwardImageInfoRecoverFromWinningStrategy(imageInfo); 00899 Img_ForwardImageInfoConjoinWithWinningStrategy(imageInfo, layer); 00904 } 00905 } 00906 00907 ring_Q = NULL; 00908 for(q=0; q<array_n(R); q++) { 00909 ring = array_fetch(mdd_t *, R, q); 00910 ring_Q = mdd_and(ring, Q, 1, 1); 00911 if(!mdd_equal(ring_Q, zeroMdd)) { 00912 break; 00913 } 00914 mdd_free(ring_Q); 00915 } 00916 mdd_free(Q); 00917 00918 if(q >= array_n(R)) { 00919 imageInfo = Fsm_FsmReadOrCreateImageInfoFAFW(modelFsm, 0, 1); 00920 Img_ForwardImageInfoRecoverFromWinningStrategy(imageInfo); 00924 continue; 00925 } 00926 00927 Q = Mc_ComputeACloseState(ring_Q, T, modelFsm); 00928 mdd_free(ring_Q); 00929 00930 if(free == 0) { 00931 array_insert_last(mdd_t *, path, (mdd_t *)((long)P+1)); 00932 } 00933 else if(free ==1) { 00934 array_insert_last(mdd_t *, path, P); 00935 free = 0; 00936 } 00937 00938 Q_T = mdd_and(Q, T, 1, 1); 00939 if(!mdd_equal(Q_T, zeroMdd)) { 00940 array_insert_last(mdd_t *, path, (mdd_t *)((long)Q+1)); 00941 mdd_free(Q_T); 00942 break; 00943 } 00944 mdd_free(Q_T); 00945 00946 P = Q; 00947 } 00948 00949 array_free(careStatesArray); 00950 mdd_free(oneMdd); 00951 mdd_free(zeroMdd); 00952 00953 imageInfo = Fsm_FsmReadOrCreateImageInfoFAFW(modelFsm, 0, 1); 00954 Img_ForwardImageInfoRecoverFromWinningStrategy(imageInfo); 00958 return(path); 00959 } 00960 00971 array_t * 00972 Mc_BuildFAFWLayer(Fsm_Fsm_t *modelFsm, mdd_t *T, mdd_t *H) 00973 { 00974 mdd_manager *mgr = Fsm_FsmReadMddManager(modelFsm); 00975 Img_ImageInfo_t *imageInfo = Fsm_FsmReadOrCreateImageInfo(modelFsm, 1, 0); 00976 mdd_t *zeroMdd, *oneMdd; 00977 mdd_t *S, *nH, *EX_S, *extCube, *S_new; 00978 array_t *L; 00979 array_t *careStatesArray; 00980 00981 zeroMdd = mdd_zero(mgr); 00982 oneMdd = mdd_one(mgr); 00983 L = array_alloc(mdd_t *, 0); 00984 00985 extCube = Fsm_FsmReadExtQuantifyInputCube(modelFsm); 00986 careStatesArray = array_alloc(mdd_t *, 0); 00987 array_insert_last(mdd_t *, careStatesArray, oneMdd); 00988 while(!mdd_equal(H, zeroMdd)) { 00989 Fsm_FsmSetUseUnquantifiedFlag(modelFsm, 1); 00990 S = Mc_FsmEvaluateAUFormula(modelFsm, H, T, 00991 NIL(mdd_t), oneMdd, careStatesArray, 00992 MC_NO_EARLY_TERMINATION, NIL(array_t), 00993 Mc_None_c, 0, McVerbosityNone_c, 00994 McDcLevelNone_c, NIL(boolean)); 00995 Fsm_FsmSetUseUnquantifiedFlag(modelFsm, 0); 00996 array_insert_last(mdd_t *, L, S); 00997 00998 S_new = bdd_smooth_with_cube(S, extCube); 00999 mdd_free(S); 01000 nH = mdd_and(H, S_new, 1, 0); 01001 01002 if(mdd_equal(H, nH)) { 01003 mdd_free(nH); 01004 mdd_free(S_new); 01005 break; 01006 } 01007 mdd_free(H); 01008 H = nH; 01009 mdd_free(T); 01010 EX_S = Img_ImageInfoComputePreImageWithDomainVars( 01011 imageInfo, S_new, S_new, careStatesArray); 01012 mdd_free(S_new); 01013 T = mdd_and(EX_S, H, 1, 1); 01014 } 01015 array_free(careStatesArray); 01016 mdd_free(zeroMdd); 01017 mdd_free(oneMdd); 01018 mdd_free(T); 01019 mdd_free(H); 01020 01021 return(L); 01022 } 01023 01034 array_t * 01035 Mc_BuildPathFromCoreFAFW( 01036 mdd_t *Ts, 01037 array_t *rings, 01038 Fsm_Fsm_t *modelFsm, 01039 Mc_PathLengthType PathLengthType) 01040 { 01041 int startingPoint, prevFlag; 01042 int i, p, dist, forced; 01043 bdd_t *T, *S, *H, *nH, *Hp, *S1, *Swin; 01044 bdd_t *ring, *oneMdd, *zeroMdd; 01045 array_t *C, *newC, *AUrings, *segment; 01046 array_t *R, *ESrings; 01047 array_t *careStatesArray; 01048 array_t *pathFromCore; 01049 bdd_t *T_wedge_ring, *S1_wedge_ring, *Hp_wedge_S1; 01050 bdd_t *T_wedge_S, *C_T_wedge_S, *ESresult, *EX_T; 01051 bdd_t *EX_T_wedge_ring, *Hp_wedge_EX_T, *lastR; 01052 bdd_t *C_T_wedge_ring, *new_, *extCube; 01053 bdd_t *bundle, *single, *preSingle; 01054 Img_ImageInfo_t *imageInfo; 01055 mdd_manager *mgr = Fsm_FsmReadMddManager(modelFsm); 01056 01057 if(Fsm_FsmReadFAFWFlag(modelFsm) == 2) { 01058 pathFromCore = Mc_BuildPathFromCoreFAFWGeneral( 01059 Ts, rings, 01060 modelFsm, PathLengthType); 01061 return(pathFromCore); 01062 } 01063 01064 T = mdd_dup(Ts); 01065 imageInfo = Fsm_FsmReadOrCreateImageInfo(modelFsm, 1, 0); 01066 if ( PathLengthType == McGreaterZero_c ) { 01067 startingPoint = 1; 01068 } 01069 else if( PathLengthType == McGreaterOrEqualZero_c ) { 01070 startingPoint = 0; 01071 } 01072 else { 01073 fail("Called Mc_BuildPathFromCoreFAFW with ill formed PathLengthType\n"); 01074 } 01075 01076 oneMdd = mdd_one(mgr); 01077 zeroMdd = mdd_zero(mgr); 01078 S = mdd_dup(array_fetch(mdd_t *, rings, startingPoint)); 01079 prevFlag = 0; 01081 H = mdd_zero(mgr); 01082 for(i=startingPoint; i<array_n(rings); i++) { 01083 ring = array_fetch(mdd_t *, rings, i); 01084 new_ = mdd_and(ring, H, 1, 0); 01085 mdd_free(ring); 01086 nH = mdd_or(new_, H, 1, 1); 01087 mdd_free(H); 01088 H = nH; 01089 array_insert(mdd_t *, rings, i, new_); 01090 } 01091 01092 C = array_alloc(mdd_t *, 0); 01093 T_wedge_S = mdd_and(T, S, 1, 1); 01094 if(!mdd_equal(T_wedge_S, zeroMdd)) { 01095 if(startingPoint == 1) { 01096 mdd_free(T); 01097 T = array_fetch(mdd_t *, rings, 0); 01098 array_insert_last(mdd_t *, C, bdd_dup(T)); 01099 } 01100 C_T_wedge_S = bdd_closest_cube(T_wedge_S, S, &dist); 01101 array_insert_last(mdd_t *, C, C_T_wedge_S); 01102 mdd_free(S); 01103 mdd_free(oneMdd); 01104 mdd_free(zeroMdd); 01105 mdd_free(H); 01106 mdd_free(T_wedge_S); 01107 01108 return(C); 01109 } 01110 mdd_free(T_wedge_S); 01111 01112 T_wedge_ring = NULL; 01113 for(p=startingPoint; p<array_n(rings); p++) { 01114 ring = array_fetch(mdd_t *, rings, p); 01115 T_wedge_ring = mdd_and(T, ring, 1, 1); 01116 if(!mdd_equal(T_wedge_ring, zeroMdd)) { 01117 break; 01118 } 01119 mdd_free(T_wedge_ring); 01120 } 01121 mdd_free(T); 01122 01123 C_T_wedge_ring = bdd_closest_cube(T_wedge_ring, S, &dist); 01124 mdd_free(T_wedge_ring); 01125 array_insert_last(mdd_t *, C, C_T_wedge_ring); 01126 T = C_T_wedge_ring; 01127 01128 extCube = Fsm_FsmReadExtQuantifyInputCube(modelFsm); 01129 careStatesArray = array_alloc(mdd_t *, 0); 01130 array_insert_last(mdd_t *, careStatesArray, oneMdd); 01131 while(1) { 01132 if(prevFlag == 0) { /* free segement */ 01133 prevFlag = 1; /* force segment */ 01134 01135 for(i=array_n(rings)-1; i>p; i--) { 01136 ring = array_fetch(mdd_t *, rings, i); 01137 nH = mdd_and(H, ring, 1, 0); 01138 mdd_free(H); 01139 H = nH; 01140 } 01141 01142 AUrings = array_alloc(mdd_t *, 0); 01143 Fsm_FsmSetUseUnquantifiedFlag(modelFsm, 1); 01144 Swin = Mc_FsmEvaluateAUFormula(modelFsm, H, T, 01145 NIL(mdd_t), oneMdd, careStatesArray, 01146 MC_NO_EARLY_TERMINATION, NIL(array_t), 01147 Mc_None_c, AUrings, McVerbosityNone_c, 01148 McDcLevelNone_c, NIL(boolean)); 01149 Fsm_FsmSetUseUnquantifiedFlag(modelFsm, 0); 01150 01151 01152 S1 = bdd_smooth_with_cube(Swin, extCube); 01153 mdd_array_free(AUrings); 01154 if(mdd_equal(S1, T)) { 01155 mdd_free(S1); 01156 mdd_free(Swin); 01157 continue; 01158 } 01159 01160 for(i=p-1; i>=startingPoint; i--) { 01161 ring = array_fetch(mdd_t *, rings, i); 01162 S1_wedge_ring = mdd_and(S1, ring, 1, 1); 01163 if(mdd_equal(S1_wedge_ring, zeroMdd)) { 01164 mdd_free(S1_wedge_ring); 01165 break; 01166 } 01167 mdd_free(S1_wedge_ring); 01168 } 01169 p = i+1; 01170 Hp = array_fetch(mdd_t *, rings, p); 01171 01172 ESrings = array_alloc(mdd_t *, 0); 01173 Hp_wedge_S1 = mdd_and(Hp, S1, 1, 1); 01174 01175 ESresult = McEvaluateESFormulaWithGivenTRFAFW( modelFsm, S1, Hp_wedge_S1, 01176 NIL(mdd_t), oneMdd, careStatesArray, 01177 MC_NO_EARLY_TERMINATION, ESrings, 01178 McVerbosityNone_c, McDcLevelNone_c, 01179 NIL(boolean), Swin); 01180 mdd_free(ESresult); 01181 mdd_free(Hp_wedge_S1); 01182 mdd_free(S1); 01183 R = ESrings; 01184 if(array_n(R) <= 1) { 01185 mdd_array_free(R); 01186 mdd_free(Swin); 01187 continue; 01188 } 01189 } 01190 else { /* force segment */ 01191 Swin = 0; 01192 prevFlag = 0; /* free segment */ 01193 EX_T = Img_ImageInfoComputePreImageWithDomainVars( 01194 imageInfo, T, T, careStatesArray); 01195 01196 for(i=p-1; i>=startingPoint; i--) { 01197 ring = array_fetch(mdd_t *, rings, i); 01198 EX_T_wedge_ring = mdd_and(EX_T, ring, 1, 1); 01199 if(mdd_equal(EX_T_wedge_ring, zeroMdd)) { 01200 mdd_free(EX_T_wedge_ring); 01201 break; 01202 } 01203 mdd_free(EX_T_wedge_ring); 01204 } 01205 p = i+1; 01206 01207 Hp = array_fetch(mdd_t *, rings, p); 01208 R = array_alloc(mdd_t *, 0); 01209 Hp_wedge_EX_T = mdd_and(Hp, EX_T, 1, 1); 01210 array_insert_last(mdd_t *, R, Hp_wedge_EX_T); 01212 array_insert_last(mdd_t *, R, mdd_dup(T)); 01213 mdd_free(EX_T); 01214 } 01215 01216 lastR = array_fetch(mdd_t *, R, 0); 01217 segment = Mc_BuildShortestPathFAFW(Swin, lastR, T, R, mgr, modelFsm, prevFlag); 01218 if(Swin) { 01219 mdd_free(Swin); 01220 Swin = 0; 01221 } 01222 mdd_array_free(R); 01223 01224 newC = array_join(C, segment); 01225 array_free(C); 01226 C = newC; 01227 01228 T = array_fetch(mdd_t *, segment, array_n(segment)-1); 01229 if((long)T %2) T = (mdd_t *)((long)T - 1); 01231 array_free(segment); 01232 01233 T_wedge_S = mdd_and(T, S, 1, 1); 01234 if(!mdd_equal(T_wedge_S, zeroMdd)) { 01235 mdd_free(T_wedge_S); 01237 mdd_free(S); 01238 mdd_free(H); 01239 break; 01240 } 01241 mdd_free(T_wedge_S); 01242 01243 startingPoint = 0; 01244 mdd_free(S); 01245 S = mdd_dup(array_fetch(mdd_t *, rings, startingPoint)); 01246 01247 } 01248 01249 array_free(careStatesArray); 01250 mdd_free(oneMdd); 01251 mdd_free(zeroMdd); 01252 01253 { 01254 int i; 01255 pathFromCore = array_alloc( mdd_t *, 0 ); 01256 01257 if(startingPoint == 1) { 01258 T = array_fetch(mdd_t *, rings, 0); 01259 array_insert_last(mdd_t *, pathFromCore, bdd_dup(T)); 01260 } 01261 01262 preSingle = NULL; 01263 for( i=0; i < array_n( C ); i++ ) { 01264 bundle = array_fetch(mdd_t *, C, (array_n(C) - (i+1))); 01265 forced = 0; 01266 if((long)bundle%2) { 01267 bundle = (mdd_t *)((long)bundle -1); 01268 forced++; 01269 } 01270 if(i==0) 01271 single = Mc_ComputeAState(bundle, modelFsm); 01272 else 01273 single = Mc_ComputeACloseState(bundle, preSingle, modelFsm); 01274 array_insert_last( mdd_t *, pathFromCore, 01275 (mdd_t *)((long)(single) + forced) ); 01276 preSingle = single; 01277 } 01278 McNormalizeBddPointer(C); 01279 mdd_array_free(C); 01280 return pathFromCore; 01281 } 01282 } 01283 01298 array_t * 01299 Mc_BuildShortestPathFAFW(mdd_t *win, 01300 mdd_t *S, 01301 mdd_t *T, 01302 array_t *rings, 01303 mdd_manager *mgr, 01304 Fsm_Fsm_t *fsm, 01305 int prevFlag) 01306 { 01307 int q, dist; 01308 mdd_t *zeroMdd, *oneMdd; 01309 mdd_t *inputCube; 01310 mdd_t *ring, *ring_wedge_T, *Cn, *Cs; 01311 mdd_t *K, *realK, *range; 01312 mdd_t *preimage_of_Cn; 01313 array_t *C, *stateVars, *inputVars; 01314 array_t *toCareSetArray; 01315 Img_ImageInfo_t *imageInfo; 01316 01317 imageInfo = Fsm_FsmReadOrCreateImageInfo(fsm, 1, 0); 01318 stateVars = Fsm_FsmReadPresentStateVars(fsm); 01319 inputVars = Fsm_FsmReadInputVars(fsm); 01320 inputCube = mdd_id_array_to_bdd_cube(mgr, inputVars); 01321 zeroMdd = mdd_zero(mgr); 01322 oneMdd = mdd_one(mgr); 01323 ring_wedge_T = NULL; 01324 for (q = 0; q < array_n(rings); q++){ 01325 ring = array_fetch(mdd_t *, rings, q); 01326 ring_wedge_T = mdd_and(T, ring, 1, 1); 01327 if(!mdd_equal(ring_wedge_T, zeroMdd)) 01328 break; 01329 mdd_free(ring_wedge_T); 01330 ring_wedge_T = 0; 01331 } 01332 if(ring_wedge_T) { 01333 mdd_free(ring_wedge_T); 01334 } 01335 else { 01336 fprintf(stdout, "We cannot find T\n"); 01337 } 01338 01339 C = array_alloc(mdd_t *, 0); 01340 Cn = (T); 01341 toCareSetArray = array_alloc(mdd_t *, 0); 01342 array_insert(mdd_t *, toCareSetArray, 0, oneMdd); 01343 range = mdd_range_mdd(mgr, stateVars); 01344 while(q > 0) { 01345 preimage_of_Cn = Img_ImageInfoComputePreImageWithDomainVars( 01346 imageInfo, Cn, Cn, toCareSetArray); 01347 01348 K = NULL; 01349 for (q = 0; q < array_n(rings); q++){ 01350 ring = array_fetch(mdd_t *, rings, q); 01351 K = mdd_and(preimage_of_Cn, ring, 1, 1); 01352 if(!mdd_equal(K, zeroMdd)) 01353 break; 01354 mdd_free(K); 01355 K = 0; 01356 } 01357 01358 mdd_free(preimage_of_Cn); 01359 realK = mdd_and(K, range, 1, 1); 01360 mdd_free(K); 01361 Cs = bdd_closest_cube(realK, Cn, &dist); 01362 mdd_free(realK); 01363 01364 01365 Cn = bdd_smooth_with_cube(Cs, inputCube); 01366 mdd_free(Cs); 01367 if(!prevFlag) 01368 array_insert_last(mdd_t *, C, Cn); 01369 else 01370 array_insert_last(mdd_t *, C, (mdd_t *)((long)Cn+1)); 01371 } 01372 array_free(toCareSetArray); 01373 mdd_free(zeroMdd); 01374 mdd_free(oneMdd); 01375 mdd_free(range); 01376 mdd_free(inputCube); 01377 return(C); 01378 } 01379 01380 01381 01396 array_t * 01397 Mc_CompletePath( 01398 mdd_t *aState, 01399 mdd_t *bState, 01400 mdd_t *invariantStates, 01401 Fsm_Fsm_t *modelFsm, 01402 array_t *careSetArray, 01403 Mc_VerbosityLevel verbosity, 01404 Mc_DcLevel dcLevel, 01405 Mc_FwdBwdAnalysis dirn) 01406 { 01407 01408 if ( dirn == McFwd_c ) { 01409 return McCompletePathFwd(aState, bState, invariantStates, modelFsm, 01410 careSetArray, verbosity, dcLevel ); 01411 } 01412 else { 01413 return McCompletePathBwd(aState, bState, invariantStates, modelFsm, 01414 careSetArray, verbosity, dcLevel ); 01415 } 01416 } 01417 01429 mdd_t * 01430 Mc_ComputeAMinterm( 01431 mdd_t *aSet, 01432 array_t *Support, 01433 mdd_manager *mddMgr) 01434 { 01435 /* check that support of set is contained in Support */ 01436 assert( SetCheckSupport( aSet, Support, mddMgr )); 01437 assert(!mdd_is_tautology(aSet, 0)); 01438 01439 if(bdd_get_package_name() == CUDD){ 01440 mdd_t *range; /* range of Support */ 01441 mdd_t *legalSet; /* aSet without the don't cares */ 01442 array_t *bddSupport; /* Support in terms of bdd vars */ 01443 mdd_t *minterm; /* a random minterm */ 01444 01445 range = mdd_range_mdd(mddMgr, Support); 01446 legalSet = bdd_intersects(aSet, range); 01447 mdd_free(range); 01448 bddSupport = mdd_id_array_to_bdd_array(mddMgr, Support); 01449 minterm = bdd_pick_one_minterm(legalSet, bddSupport); 01450 01451 assert(MintermCheckWellFormed(minterm, Support, mddMgr)); 01452 assert(mdd_count_onset(mddMgr, minterm, Support) == 1); 01453 assert(mdd_lequal(minterm,legalSet,1,1)); 01454 01455 mdd_array_free(bddSupport); 01456 mdd_free(legalSet); 01457 01458 return minterm; 01459 }else{ 01460 int i, j; 01461 mdd_t *aSetDup; 01462 mdd_t *resultMdd; 01463 array_t *resultMddArray = array_alloc( mdd_t *, 0 ); 01464 01465 aSetDup = mdd_dup( aSet ); 01466 for( i = 0 ; i < array_n( Support ); i++ ) { 01467 01468 int aSupportVar = array_fetch( int, Support, i ); 01469 01470 for( j = 0 ;;) { 01471 mdd_t *faceMdd, *tmpMdd; 01472 array_t *tmpArray = array_alloc( int, 0 ); 01473 array_insert_last( int, tmpArray, j ); 01474 01475 /* this call will crash if have run through range of mvar */ 01476 faceMdd = mdd_literal( mddMgr, aSupportVar, tmpArray ); 01477 array_free( tmpArray ); 01478 tmpMdd = mdd_and( faceMdd, aSetDup, 1, 1 ); 01479 01480 if ( !mdd_is_tautology( tmpMdd, 0 ) ) { 01481 array_insert_last( mdd_t *, resultMddArray, faceMdd ); 01482 mdd_free( aSetDup ); 01483 aSetDup = tmpMdd; 01484 break; 01485 } 01486 mdd_free( faceMdd ); 01487 mdd_free( tmpMdd ); 01488 j++; 01489 } 01490 } 01491 mdd_free( aSetDup ); 01492 01493 resultMdd = mdd_one( mddMgr ); 01494 for ( i = 0 ; i < array_n( resultMddArray ); i++ ) { 01495 mdd_t *faceMdd = array_fetch( mdd_t *, resultMddArray, i ); 01496 mdd_t *tmpMdd = mdd_and( faceMdd, resultMdd, 1, 1 ); 01497 mdd_free( resultMdd ); mdd_free( faceMdd ); 01498 resultMdd = tmpMdd; 01499 } 01500 array_free( resultMddArray ); 01501 01502 return resultMdd; 01503 }/* IF CUDD */ 01504 } 01505 01506 01516 mdd_t * 01517 Mc_ComputeACloseMinterm( 01518 mdd_t *aSet, 01519 mdd_t *target, 01520 array_t *Support, 01521 mdd_manager *mddMgr) 01522 { 01523 if (bdd_get_package_name() == CUDD && target != NIL(mdd_t)) { 01524 mdd_t *range; /* range of Support */ 01525 mdd_t *legalSet; /* aSet without the don't cares */ 01526 mdd_t *closeCube; 01527 int dist; 01528 array_t *bddSupport; /* Support in terms of bdd vars */ 01529 mdd_t *minterm; /* a random minterm */ 01530 01531 /* Check that support of set is contained in Support. */ 01532 assert(SetCheckSupport(aSet, Support, mddMgr)); 01533 assert(!mdd_is_tautology(aSet, 0)); 01534 range = mdd_range_mdd(mddMgr, Support); 01535 legalSet = bdd_and(aSet, range, 1, 1); 01536 mdd_free(range); 01537 closeCube = mdd_closest_cube(legalSet, target, &dist); 01538 bddSupport = mdd_id_array_to_bdd_array(mddMgr, Support); 01539 minterm = bdd_pick_one_minterm(closeCube, bddSupport); 01540 01541 assert(MintermCheckWellFormed(minterm, Support, mddMgr)); 01542 assert(mdd_count_onset(mddMgr, minterm, Support) == 1); 01543 assert(mdd_lequal(minterm,legalSet,1,1)); 01544 01545 mdd_array_free(bddSupport); 01546 mdd_free(legalSet); 01547 mdd_free(closeCube); 01548 01549 return minterm; 01550 } else { 01551 return Mc_ComputeAMinterm(aSet, Support, mddMgr); 01552 }/* if CUDD */ 01553 01554 } /* McComputeACloseMinterm */ 01555 01556 01557 01558 01566 char * 01567 Mc_MintermToStringAiger( 01568 mdd_t *aMinterm, 01569 array_t *aSupport, 01570 Ntk_Network_t *aNetwork) 01571 { 01572 int i; 01573 char *tmp1String; 01574 char *tmp2String; 01575 char bodyString[McMaxStringLength_c]; 01576 char *mintermString = NIL(char); 01577 mdd_manager *mddMgr = Ntk_NetworkReadMddManager( aNetwork ); 01578 array_t *valueArray; 01579 array_t *stringArray = array_alloc( char *, 0 ); 01580 01581 aMinterm = GET_NORMAL_PT(aMinterm); 01582 valueArray = McConvertMintermToValueArray(aMinterm, aSupport, mddMgr); 01583 for ( i = 0 ; i < array_n( aSupport ); i++ ) { 01584 01585 int mddId = array_fetch( int, aSupport, i ); 01586 int value = array_fetch( int, valueArray, i ); 01587 Ntk_Node_t *node = Ntk_NetworkFindNodeByMddId( aNetwork, mddId ); 01588 char *nodeName = Ntk_NodeReadName( node ); 01589 if(!((nodeName[0] == '$') && (nodeName[1] == '_'))) 01590 { 01591 Var_Variable_t *nodeVar = Ntk_NodeReadVariable( node ); 01592 01593 if ( Var_VariableTestIsSymbolic( nodeVar ) ) { 01594 char *symbolicValue = Var_VariableReadSymbolicValueFromIndex(nodeVar, 01595 value ); 01596 sprintf( bodyString, "%s", symbolicValue ); 01597 } 01598 else { 01599 sprintf( bodyString, "%d", value ); 01600 } 01601 tmp1String = util_strsav( bodyString ); 01602 array_insert_last( char *, stringArray, tmp1String ); 01603 } 01604 } 01605 array_free(valueArray); 01606 01607 array_sort( stringArray, cmp); 01608 01609 for ( i = 0 ; i < array_n( stringArray ); i++ ) { 01610 tmp1String = array_fetch( char *, stringArray, i ); 01611 if( i == 0 ) { 01612 mintermString = util_strcat3(tmp1String, "", "" ); 01613 } 01614 else { 01615 tmp2String = util_strcat3(mintermString, "", tmp1String ); 01616 FREE(mintermString); 01617 mintermString = tmp2String; 01618 } 01619 FREE(tmp1String); 01620 } 01621 array_free( stringArray ); 01622 01623 tmp1String = util_strcat3(mintermString, " ", ""); 01624 FREE(mintermString); 01625 mintermString = tmp1String; 01626 01627 return mintermString; 01628 } 01629 01630 01638 char * 01639 Mc_MintermToStringAigerInput( 01640 mdd_t *aMinterm, 01641 array_t *aSupport, 01642 Ntk_Network_t *aNetwork) 01643 { 01644 int i; 01645 char *tmp1String; 01646 char *tmp2String; 01647 char bodyString[McMaxStringLength_c]; 01648 char *mintermString = NIL(char); 01649 mdd_manager *mddMgr = Ntk_NetworkReadMddManager( aNetwork ); 01650 array_t *valueArray; 01651 array_t *stringArray = array_alloc( char *, 0 ); 01652 01653 aMinterm = GET_NORMAL_PT(aMinterm); 01654 valueArray = McConvertMintermToValueArray(aMinterm, aSupport, mddMgr); 01655 for ( i = 0 ; i < array_n( aSupport ); i++ ) { 01656 01657 int mddId = array_fetch( int, aSupport, i ); 01658 int value = array_fetch( int, valueArray, i ); 01659 Ntk_Node_t *node = Ntk_NetworkFindNodeByMddId( aNetwork, mddId ); 01660 char *nodeName = Ntk_NodeReadName( node ); 01661 if((nodeName[0] == '$') && (nodeName[1] == '_')) 01662 { 01663 Var_Variable_t *nodeVar = Ntk_NodeReadVariable( node ); 01664 01665 if ( Var_VariableTestIsSymbolic( nodeVar ) ) { 01666 char *symbolicValue = Var_VariableReadSymbolicValueFromIndex(nodeVar, 01667 value ); 01668 sprintf( bodyString, "%s", symbolicValue ); 01669 } 01670 else { 01671 sprintf( bodyString, "%d", value ); 01672 } 01673 tmp1String = util_strsav( bodyString ); 01674 array_insert_last( char *, stringArray, tmp1String ); 01675 } 01676 } 01677 array_free(valueArray); 01678 01679 array_sort( stringArray, cmp); 01680 01681 for ( i = 0 ; i < array_n( stringArray ); i++ ) { 01682 tmp1String = array_fetch( char *, stringArray, i ); 01683 if( i == 0 ) { 01684 mintermString = util_strcat3(tmp1String, "", "" ); 01685 } 01686 else { 01687 tmp2String = util_strcat3(mintermString, "", tmp1String ); 01688 FREE(mintermString); 01689 mintermString = tmp2String; 01690 } 01691 FREE(tmp1String); 01692 } 01693 array_free( stringArray ); 01694 01695 tmp1String = util_strcat3(mintermString, " ", ""); 01696 FREE(mintermString); 01697 mintermString = tmp1String; 01698 01699 return mintermString; 01700 } 01701 01709 char * 01710 Mc_MintermToString( 01711 mdd_t *aMinterm, 01712 array_t *aSupport, 01713 Ntk_Network_t *aNetwork) 01714 { 01715 int i; 01716 char *tmp1String; 01717 char *tmp2String; 01718 char bodyString[McMaxStringLength_c]; 01719 char *mintermString = NIL(char); 01720 mdd_manager *mddMgr = Ntk_NetworkReadMddManager( aNetwork ); 01721 array_t *valueArray; 01722 array_t *stringArray = array_alloc( char *, 0 ); 01723 01724 aMinterm = GET_NORMAL_PT(aMinterm); 01725 valueArray = McConvertMintermToValueArray(aMinterm, aSupport, mddMgr); 01726 for ( i = 0 ; i < array_n( aSupport ); i++ ) { 01727 01728 int mddId = array_fetch( int, aSupport, i ); 01729 int value = array_fetch( int, valueArray, i ); 01730 Ntk_Node_t *node = Ntk_NetworkFindNodeByMddId( aNetwork, mddId ); 01731 char *nodeName = Ntk_NodeReadName( node ); 01732 Var_Variable_t *nodeVar = Ntk_NodeReadVariable( node ); 01733 01734 if ( Var_VariableTestIsSymbolic( nodeVar ) ) { 01735 char *symbolicValue = Var_VariableReadSymbolicValueFromIndex(nodeVar, 01736 value ); 01737 sprintf( bodyString, "%s:%s", nodeName, symbolicValue ); 01738 } 01739 else { 01740 sprintf( bodyString, "%s:%d", nodeName, value ); 01741 } 01742 tmp1String = util_strsav( bodyString ); 01743 array_insert_last( char *, stringArray, tmp1String ); 01744 } 01745 array_free(valueArray); 01746 01747 array_sort( stringArray, cmp); 01748 01749 for ( i = 0 ; i < array_n( stringArray ); i++ ) { 01750 tmp1String = array_fetch( char *, stringArray, i ); 01751 if( i == 0 ) { 01752 mintermString = util_strcat3(tmp1String, "", "" ); 01753 } 01754 else { 01755 tmp2String = util_strcat3(mintermString, "\n", tmp1String ); 01756 FREE(mintermString); 01757 mintermString = tmp2String; 01758 } 01759 FREE(tmp1String); 01760 } 01761 array_free( stringArray ); 01762 01763 tmp1String = util_strcat3(mintermString, "\n", ""); 01764 FREE(mintermString); 01765 mintermString = tmp1String; 01766 01767 return mintermString; 01768 } 01769 01777 int 01778 Mc_PrintPath( 01779 array_t *aPath, 01780 Fsm_Fsm_t *modelFsm, 01781 boolean printInput) 01782 { 01783 int check, forced, i; 01784 int numForced; 01785 mdd_t *inputSet=NIL(mdd_t); 01786 mdd_t *uInput = NIL(mdd_t); 01787 mdd_t *vInput = NIL(mdd_t); 01788 01789 array_t *psVars = Fsm_FsmReadPresentStateVars( modelFsm ); 01790 array_t *inputVars = Fsm_FsmReadInputVars( modelFsm ); 01791 mdd_manager *mddMgr = Fsm_FsmReadMddManager( modelFsm ); 01792 01793 forced = 0; 01794 check = 1; 01795 numForced = 0; 01796 01797 01798 for( i = -1 ; i < (array_n( aPath )-1); i++ ) { 01799 01800 mdd_t *aState = ( i == -1 ) ? NIL(mdd_t) : array_fetch( mdd_t *, aPath, i ); 01801 mdd_t *bState = array_fetch( mdd_t *, aPath, (i+1) ); 01802 01803 if((long)aState%2) { 01804 aState = (mdd_t *)((long)aState -1); 01805 forced++; 01806 } 01807 else forced = 0; 01808 01809 if((long)bState%2) { 01810 bState = (mdd_t *)((long)bState -1); 01811 } 01812 01813 if ( printInput == TRUE && i != -1) { 01814 inputSet = Mc_FsmComputeDrivingInputMinterms( modelFsm, aState, bState ); 01815 vInput = Mc_ComputeACloseMinterm( inputSet, uInput, inputVars, mddMgr ); 01816 } 01817 if(forced) { 01818 fprintf(vis_stdout, "---- Forced %d\n", forced); 01819 numForced ++; 01820 } 01821 McPrintTransition( aState, bState, uInput, vInput, psVars, inputVars, 01822 printInput, modelFsm, (i+1) ); 01823 01824 01825 if ( uInput != NIL(mdd_t) ) { 01826 mdd_free(uInput); 01827 } 01828 uInput = vInput; 01829 01830 if ( inputSet != NIL(mdd_t) ) { 01831 mdd_free(inputSet); 01832 } 01833 } 01834 01835 if ( vInput != NIL(mdd_t) ) { 01836 mdd_free(uInput); 01837 } 01838 01839 if(Fsm_FsmReadFAFWFlag(modelFsm) > 0) { 01840 fprintf(vis_stdout, 01841 "# MC: the number of non-trivial forced segments %d\n", 01842 numForced); 01843 } 01844 01845 return 1; 01846 } 01847 01855 int 01856 Mc_PrintPathAiger( 01857 array_t *aPath, 01858 Fsm_Fsm_t *modelFsm, 01859 boolean printInput) 01860 { 01861 int check, forced, i; 01862 int numForced; 01863 mdd_t *inputSet=NIL(mdd_t); 01864 mdd_t *uInput = NIL(mdd_t); 01865 mdd_t *vInput = NIL(mdd_t); 01866 01867 array_t *psVars = Fsm_FsmReadPresentStateVars( modelFsm ); 01868 array_t *inputVars = Fsm_FsmReadInputVars( modelFsm ); 01869 01870 forced = 0; 01871 check = 1; 01872 numForced = 0; 01873 01874 Ntk_Network_t *network = Fsm_FsmReadNetwork( modelFsm ); 01875 01876 FILE *psO = Cmd_FileOpen("inputOrder.txt", "w", NIL(char *), 0); 01877 for(i=0; i<array_n(psVars); i++) 01878 { 01879 int mddId = array_fetch( int, psVars, i ); 01880 Ntk_Node_t *node = Ntk_NetworkFindNodeByMddId( network, mddId ); 01881 char *nodeName = Ntk_NodeReadName( node ); 01882 if((nodeName[0] == '$') && (nodeName[1] == '_')) 01883 { 01884 fprintf(psO, "%s\n", &nodeName[2]); 01885 } 01886 } 01887 fclose(psO); 01888 01889 for( i = -1 ; i < (array_n( aPath )-1); i++ ) { 01890 01891 mdd_t *aState = ( i == -1 ) ? NIL(mdd_t) : array_fetch( mdd_t *, aPath, i ); 01892 mdd_t *bState = array_fetch( mdd_t *, aPath, (i+1) ); 01893 01894 if((long)aState%2) { 01895 aState = (mdd_t *)((long)aState -1); 01896 forced++; 01897 } 01898 else forced = 0; 01899 01900 if((long)bState%2) { 01901 bState = (mdd_t *)((long)bState -1); 01902 } 01903 01904 if(forced) { 01905 fprintf(vis_stdout, "---- Forced %d\n", forced); 01906 numForced ++; 01907 } 01908 01909 /* The following fix is only for Sat-competition 2007 and will need to be fixed for future */ 01910 01911 if(i == (array_n(aPath)-2)) 01912 { 01913 McPrintTransitionAiger( aState, bState, uInput, vInput, psVars, inputVars, 01914 printInput, modelFsm, 1 ); 01915 } 01916 else 01917 { 01918 McPrintTransitionAiger( aState, bState, uInput, vInput, psVars, inputVars, 01919 printInput, modelFsm, 0 ); 01920 } 01921 01922 01923 if ( uInput != NIL(mdd_t) ) { 01924 mdd_free(uInput); 01925 } 01926 uInput = vInput; 01927 01928 if ( inputSet != NIL(mdd_t) ) { 01929 mdd_free(inputSet); 01930 } 01931 } 01932 01933 if ( vInput != NIL(mdd_t) ) { 01934 mdd_free(uInput); 01935 } 01936 01937 if(Fsm_FsmReadFAFWFlag(modelFsm) > 0) { 01938 fprintf(vis_stdout, 01939 "# MC: the number of non-trivial forced segments %d\n", 01940 numForced); 01941 } 01942 01943 return 1; 01944 } 01945 01946 01966 static Mvf_Function_t * 01967 NodeBuildPseudoInputMvf( 01968 Ntk_Node_t * node, 01969 mdd_manager * mddMgr) 01970 { 01971 Mvf_Function_t *mvf; 01972 int columnIndex = Ntk_NodeReadOutputIndex(node); 01973 Tbl_Table_t *table = Ntk_NodeReadTable(node); 01974 int mddId = Ntk_NodeReadMddId(node); 01975 01976 assert(mddId != NTK_UNASSIGNED_MDD_ID); 01977 mvf = Tbl_TableBuildNonDetConstantMvf(table, columnIndex, mddId, mddMgr); 01978 return mvf; 01979 } 01980 01990 static mdd_t * 01991 Mc_ComputeRangeOfPseudoInputs( 01992 Ntk_Network_t *network) 01993 { 01994 mdd_manager *mddMgr = Ntk_NetworkReadMddManager( network ); 01995 Mvf_Function_t *nodeMvf; 01996 mdd_t *tmpMdd, *zeroMdd; 01997 mdd_t *restrictMdd, *sumMdd; 01998 int restrictFlag; 01999 lsGen gen; 02000 Ntk_Node_t *node; 02001 int i; 02002 02003 zeroMdd = mdd_zero(mddMgr); 02004 restrictMdd = mdd_one(mddMgr); 02005 restrictFlag = 0; 02006 Ntk_NetworkForEachPseudoInput(network, gen, node) { 02007 nodeMvf = NodeBuildPseudoInputMvf(node, mddMgr); 02008 for(i=0; i<nodeMvf->num; i++) { 02009 tmpMdd = array_fetch(mdd_t *, nodeMvf, i); 02010 if(mdd_equal(tmpMdd, zeroMdd)) { 02011 restrictFlag = 1; 02012 break; 02013 } 02014 } 02015 if(restrictFlag) { 02016 sumMdd = mdd_zero(mddMgr); 02017 for(i=0; i<nodeMvf->num; i++) { 02018 tmpMdd = array_fetch(mdd_t *, nodeMvf, i); 02019 if(!mdd_equal(tmpMdd, zeroMdd)) { 02020 tmpMdd = mdd_or( sumMdd, tmpMdd, 1, 1 ); 02021 mdd_free(sumMdd); 02022 sumMdd = tmpMdd; 02023 } 02024 } 02025 tmpMdd = mdd_and( sumMdd, restrictMdd, 1, 1 ); 02026 mdd_free(sumMdd); 02027 mdd_free(restrictMdd); 02028 restrictMdd = tmpMdd; 02029 } 02030 Mvf_FunctionFree(nodeMvf); 02031 } 02032 mdd_free(zeroMdd); 02033 02034 return(restrictMdd); 02035 } 02036 02037 02048 mdd_t * 02049 Mc_FsmComputeDrivingInputMinterms( 02050 Fsm_Fsm_t *fsm, 02051 mdd_t *aState, 02052 mdd_t *bState ) 02053 { 02054 int i; 02055 int psMddId; 02056 int inputMddId; 02057 mdd_gen *mddGen; 02058 Ntk_Node_t *latch, *node, *dataNode; 02059 array_t *aMinterm, *bMinterm; 02060 mdd_t *resultMdd; 02061 array_t *resultMvfs; 02062 array_t *inputArray = Fsm_FsmReadInputVars( fsm ); 02063 array_t *psArray = Fsm_FsmReadPresentStateVars( fsm ); 02064 Ntk_Network_t *network = Fsm_FsmReadNetwork( fsm ); 02065 st_table *leaves = st_init_table(st_ptrcmp, st_ptrhash); 02066 array_t *roots = array_alloc( Ntk_Node_t *, 0 ); 02067 array_t *latches = array_alloc( Ntk_Node_t *, 0 ); 02068 array_t *support = array_alloc( int, 0 ); 02069 mdd_t *rangeOfPseudoInputs, *tmpMdd; 02070 02071 arrayForEachItem(int , psArray, i, psMddId ) { 02072 latch = Ntk_NetworkFindNodeByMddId( network, psMddId ); 02073 dataNode = Ntk_LatchReadDataInput( latch ); 02074 array_insert_last( int, support, psMddId ); 02075 array_insert_last( Ntk_Node_t *, roots, dataNode ); 02076 array_insert_last( Ntk_Node_t *, latches, latch ); 02077 } 02078 02079 /* Convert the minterm to an array of assignments to support vars. */ 02080 foreach_mdd_minterm(aState, mddGen, aMinterm, support) { 02081 mdd_gen_free(mddGen); 02082 break; 02083 /* NOT REACHED */ 02084 } 02085 02086 foreach_mdd_minterm(bState, mddGen, bMinterm, support) { 02087 mdd_gen_free(mddGen); 02088 break; 02089 /* NOT REACHED */ 02090 } 02091 array_free( support ); 02092 02093 arrayForEachItem(int , inputArray, i, inputMddId ) { 02094 node = Ntk_NetworkFindNodeByMddId( network, inputMddId ); 02095 st_insert(leaves, (char *) node, (char *) NTM_UNUSED ); 02096 } 02097 02098 for ( i = 0 ; i < array_n( roots ); i++ ) { 02099 int value = array_fetch( int, aMinterm, i ); 02100 latch = array_fetch( Ntk_Node_t *, latches, i ); 02101 st_insert( leaves, (char *) latch, (char *) (long) value ); 02102 } 02103 02104 resultMvfs = Ntm_NetworkBuildMvfs( network, roots, leaves, NIL(mdd_t) ); 02105 02106 array_free( roots ); 02107 array_free( latches ); 02108 st_free_table( leaves ); 02109 02110 rangeOfPseudoInputs = Mc_ComputeRangeOfPseudoInputs(network); 02111 02112 resultMdd = rangeOfPseudoInputs; 02113 for ( i = 0 ; i < array_n( resultMvfs ) ; i++ ) { 02114 Mvf_Function_t *mvf = array_fetch( Mvf_Function_t *, resultMvfs, i ); 02115 int value = array_fetch( int, bMinterm, i ); 02116 mdd_t *activeMdd = Mvf_FunctionReadComponent( mvf, value ); 02117 tmpMdd = mdd_and( activeMdd, resultMdd, 1, 1 ); 02118 if(mdd_is_tautology(tmpMdd, 0)) { 02119 fprintf(stdout, "current error\n"); 02120 } 02121 mdd_free( resultMdd ); 02122 resultMdd = tmpMdd; 02123 Mvf_FunctionFree( mvf ); 02124 } 02125 array_free( resultMvfs); 02126 array_free( aMinterm ); 02127 array_free( bMinterm ); 02128 02129 return resultMdd; 02130 } 02131 02132 02140 mdd_t * 02141 Mc_ComputeAState( 02142 mdd_t *states, 02143 Fsm_Fsm_t *modelFsm) 02144 { 02145 array_t *PSVars = Fsm_FsmReadPresentStateVars( modelFsm ); 02146 mdd_manager *mddMgr = Ntk_NetworkReadMddManager( Fsm_FsmReadNetwork( modelFsm ) ); 02147 mdd_t *result = Mc_ComputeAMinterm( states, PSVars, mddMgr ); 02148 02149 return result; 02150 } 02151 02152 02160 mdd_t * 02161 Mc_ComputeACloseState( 02162 mdd_t *states, 02163 mdd_t *target, 02164 Fsm_Fsm_t *modelFsm) 02165 { 02166 array_t *PSVars = Fsm_FsmReadPresentStateVars( modelFsm ); 02167 mdd_manager *mddMgr = Ntk_NetworkReadMddManager( Fsm_FsmReadNetwork( modelFsm ) ); 02168 mdd_t *result = Mc_ComputeACloseMinterm( states, target, PSVars, mddMgr ); 02169 02170 return result; 02171 } 02172 02173 02181 void 02182 Mc_MintermPrint( 02183 mdd_t *aMinterm, 02184 array_t *support, 02185 Ntk_Network_t *aNetwork) 02186 { 02187 char *tmpString = Mc_MintermToString( aMinterm, support, aNetwork ); 02188 fprintf( vis_stdout, "%s", tmpString ); 02189 FREE(tmpString); 02190 } 02191 02199 void 02200 Mc_NodeTableAddCtlFormulaNodes( 02201 Ntk_Network_t *network, 02202 Ctlp_Formula_t *formula, 02203 st_table * nodesTable ) 02204 { 02205 NodeTableAddCtlFormulaNodes( network, formula, nodesTable ); 02206 } 02207 02217 void 02218 Mc_NodeTableAddLtlFormulaNodes( 02219 Ntk_Network_t *network, 02220 Ctlsp_Formula_t *formula, 02221 st_table * nodesTable ) 02222 { 02223 NodeTableAddLtlFormulaNodes(network, formula, nodesTable); 02224 } 02225 02237 Fsm_Fsm_t * 02238 Mc_ConstructReducedFsm( 02239 Ntk_Network_t *network, 02240 array_t *ctlFormulaArray) 02241 { 02242 return(McConstructReducedFsm(network, ctlFormulaArray)); 02243 } 02244 02245 02257 Mc_GSHScheduleType 02258 Mc_StringConvertToScheduleType( 02259 char *string) 02260 { 02261 return McStringConvertToScheduleType(string); 02262 } 02263 02277 int 02278 Mc_StringConvertToLockstepMode( 02279 char *string) 02280 { 02281 return McStringConvertToLockstepMode(string); 02282 } 02283 02284 02291 Mc_EarlyTermination_t * 02292 Mc_EarlyTerminationAlloc( 02293 Mc_EarlyTerminationType mode, 02294 mdd_t *states) 02295 { 02296 Mc_EarlyTermination_t *result = ALLOC(Mc_EarlyTermination_t, 1); 02297 02298 result->mode = mode; 02299 if (states != NIL(mdd_t)) { 02300 result->states = mdd_dup(states); 02301 } else { 02302 result->states = NIL(mdd_t); 02303 } 02304 02305 return result; 02306 } 02307 02315 void 02316 Mc_EarlyTerminationFree(Mc_EarlyTermination_t *earlyTermination) 02317 { 02318 if(earlyTermination == NIL(Mc_EarlyTermination_t) || 02319 earlyTermination == MC_NO_EARLY_TERMINATION) 02320 return; 02321 02322 if(earlyTermination->states != NIL(mdd_t)) 02323 mdd_free(earlyTermination->states); 02324 02325 free(earlyTermination); 02326 02327 return; 02328 } 02329 02337 boolean 02338 Mc_EarlyTerminationIsSkip(Mc_EarlyTermination_t *earlyTermination) 02339 { 02340 if (earlyTermination == NIL(Mc_EarlyTermination_t) || 02341 earlyTermination == MC_NO_EARLY_TERMINATION) 02342 return FALSE; 02343 02344 return (earlyTermination->mode == McCare_c && 02345 earlyTermination->states == NIL(mdd_t)); 02346 02347 } 02348 02349 /*---------------------------------------------------------------------------*/ 02350 /* Definition of internal functions */ 02351 /*---------------------------------------------------------------------------*/ 02352 02368 array_t * 02369 McCompletePathFwd( 02370 mdd_t *aState, 02371 mdd_t *bState, 02372 mdd_t *invariantStates, 02373 Fsm_Fsm_t *modelFsm, 02374 array_t *careSetArray, 02375 Mc_VerbosityLevel verbosity, 02376 Mc_DcLevel dcLevel) 02377 { 02378 mdd_t *tmp1Mdd; 02379 array_t *result; 02380 mdd_manager *mddMgr = Fsm_FsmReadMddManager( modelFsm ); 02381 mdd_t *zeroMdd = mdd_zero( mddMgr ); 02382 array_t *onionRings = array_alloc( mdd_t *, 0 ); 02383 Img_ImageInfo_t * imageInfo = Fsm_FsmReadOrCreateImageInfo(modelFsm, 0, 1); 02384 mdd_t *c0, *c1; 02385 02386 assert( mdd_lequal( aState, invariantStates, 1, 1 ) ); 02387 assert( mdd_lequal( bState, invariantStates, 1, 1 ) ); 02388 02389 if ( mdd_equal( aState, bState ) ) { 02390 02391 /* 02392 * Alter the starting point to force routine to produce cycle if exists 02393 * Question: would it be quicker to do simultaneous backward/forward 02394 * analysis? 02395 */ 02396 02397 c0 = mdd_dup( aState ); 02398 array_insert_last( mdd_t *, onionRings, c0 ); 02399 02400 tmp1Mdd = Img_ImageInfoComputeImageWithDomainVars(imageInfo, 02401 aState, aState, careSetArray); 02402 c1 = mdd_and( tmp1Mdd, invariantStates, 1, 1 ); 02403 mdd_free(tmp1Mdd); 02404 array_insert_last( mdd_t *, onionRings, c1 ); 02405 } 02406 else { 02407 c0 = zeroMdd; 02408 c1 = mdd_dup( aState ); 02409 array_insert_last( mdd_t *, onionRings, c1 ); 02410 } 02411 02412 while (!mdd_equal_mod_care_set_array(c0, c1, careSetArray)) { 02413 02414 mdd_t *tmp2Mdd; 02415 02416 if ( McStateTestMembership( bState, c1 ) ) { 02417 break; 02418 } 02419 02420 /* 02421 * performance gain from using dc's in this fp computation. 02422 * use only when dclevel >= max 02423 */ 02424 if ( dcLevel >= McDcLevelRchFrontier_c ) { 02425 mdd_t *annulusMdd = mdd_and( c0, c1, 0, 1 ); 02426 mdd_t *discMdd = mdd_dup( c1 ); 02427 mdd_t *dcMdd = bdd_between( annulusMdd, discMdd ); 02428 02429 tmp2Mdd = Img_ImageInfoComputeImageWithDomainVars(imageInfo, 02430 annulusMdd, discMdd, careSetArray); 02431 02432 if ( verbosity > McVerbosityNone_c ) { 02433 fprintf(vis_stdout, 02434 "--Fwd completion: |low| = %d\t|upper| = %d\t|between|=%d\n", 02435 mdd_size(annulusMdd), mdd_size(discMdd), mdd_size(dcMdd)); 02436 } 02437 02438 mdd_free( annulusMdd ); 02439 mdd_free( discMdd ); 02440 mdd_free( dcMdd ); 02441 } 02442 else { 02443 tmp2Mdd = Img_ImageInfoComputeImageWithDomainVars(imageInfo, c1, c1, 02444 careSetArray); 02445 } 02446 02447 tmp1Mdd = mdd_and( tmp2Mdd, invariantStates, 1, 1); 02448 mdd_free(tmp2Mdd); 02449 02450 c0 = c1; 02451 c1 = mdd_or( c1, tmp1Mdd, 1, 1 ); 02452 mdd_free( tmp1Mdd ); 02453 02454 array_insert_last( mdd_t *, onionRings, c1 ); 02455 } 02456 02457 if ( McStateTestMembership( bState, c1 ) ) { 02458 result = Mc_BuildPathFromCore(bState, onionRings, modelFsm, 02459 McGreaterZero_c ); 02460 } 02461 else { 02462 result = NIL(array_t); 02463 } 02464 02465 mdd_free( zeroMdd ); 02466 mdd_array_free( onionRings); 02467 02468 return result; 02469 } 02470 02486 array_t * 02487 McCompletePathBwd( 02488 mdd_t *aState, 02489 mdd_t *bState, 02490 mdd_t *invariantStates, 02491 Fsm_Fsm_t *modelFsm, 02492 array_t *careSetArray, 02493 Mc_VerbosityLevel verbosity, 02494 Mc_DcLevel dcLevel) 02495 { 02496 mdd_t *tmp1Mdd; 02497 array_t *result; 02498 mdd_manager *mddMgr = Fsm_FsmReadMddManager( modelFsm ); 02499 mdd_t *zeroMdd = mdd_zero( mddMgr ); 02500 array_t *onionRings = array_alloc( mdd_t *, 0 ); 02501 Img_ImageInfo_t * imageInfo = Fsm_FsmReadOrCreateImageInfo(modelFsm, 1, 0); 02502 mdd_t *c0, *c1; 02503 02504 02505 assert( mdd_lequal( aState, invariantStates, 1, 1 ) ); 02506 assert( mdd_lequal( bState, invariantStates, 1, 1 ) ); 02507 02508 if ( mdd_equal( aState, bState ) ) { 02509 02510 /* 02511 * Alter the starting point to force routine to produce cycle if exists 02512 * Question: would it be quicker to do simultaneous backward/forward 02513 * analysis? 02514 */ 02515 02516 c0 = mdd_dup( bState ); 02517 array_insert_last( mdd_t *, onionRings, c0 ); 02518 02519 tmp1Mdd = Img_ImageInfoComputePreImageWithDomainVars(imageInfo, bState, 02520 bState, careSetArray); 02521 c1 = mdd_and( tmp1Mdd, invariantStates, 1, 1 ); 02522 mdd_free(tmp1Mdd); 02523 array_insert_last( mdd_t *, onionRings, c1 ); 02524 } 02525 else { 02526 c0 = zeroMdd; 02527 c1 = mdd_dup( bState ); 02528 array_insert_last( mdd_t *, onionRings, c1 ); 02529 } 02530 02531 while (!mdd_equal_mod_care_set_array(c0, c1, careSetArray)) { 02532 02533 mdd_t *tmp2Mdd; 02534 02535 if ( McStateTestMembership( aState, c1 ) ) { 02536 break; 02537 } 02538 02539 /* 02540 * performance gain from using dc's in this fp computation. 02541 * use only when dclevel >= max 02542 */ 02543 if ( dcLevel >= McDcLevelRchFrontier_c ) { 02544 mdd_t *annulusMdd = mdd_and( c0, c1, 0, 1 ); 02545 mdd_t *discMdd = mdd_dup( c1 ); 02546 mdd_t *dcMdd = bdd_between( annulusMdd, discMdd ); 02547 02548 tmp2Mdd = Img_ImageInfoComputePreImageWithDomainVars(imageInfo, 02549 annulusMdd, discMdd, careSetArray); 02550 02551 if ( verbosity > McVerbosityNone_c ) { 02552 fprintf(vis_stdout, 02553 "--Bwd completion: |low| = %d\t|upper| = %d\t|between|=%d\n", 02554 mdd_size(annulusMdd), mdd_size(discMdd), mdd_size(dcMdd)); 02555 } 02556 02557 mdd_free( annulusMdd ); 02558 mdd_free( discMdd ); 02559 mdd_free( dcMdd ); 02560 } 02561 else { 02562 tmp2Mdd = Img_ImageInfoComputePreImageWithDomainVars(imageInfo, c1, c1, 02563 careSetArray); 02564 } 02565 02566 tmp1Mdd = mdd_and( tmp2Mdd, invariantStates, 1, 1); 02567 mdd_free(tmp2Mdd); 02568 02569 c0 = c1; 02570 c1 = mdd_or( c1, tmp1Mdd, 1, 1 ); 02571 mdd_free( tmp1Mdd ); 02572 02573 array_insert_last( mdd_t *, onionRings, c1 ); 02574 } 02575 02576 if ( McStateTestMembership( aState, c1 ) ) { 02577 result = Mc_BuildPathToCore(aState, onionRings, modelFsm, McGreaterZero_c); 02578 } 02579 else { 02580 result = NIL(array_t); 02581 } 02582 02583 mdd_free( zeroMdd ); 02584 mdd_array_free( onionRings); 02585 02586 return result; 02587 } 02588 02605 int 02606 McCommandInitState( 02607 Hrc_Manager_t **hmgr, 02608 int argc, 02609 char **argv) 02610 { 02611 mdd_t *modelInitialStates; 02612 mdd_t *anInitialState; 02613 Fsm_Fsm_t *modelFsm; 02614 char *formulaTxt; 02615 array_t *stateVars; 02616 FILE *ctlFile; 02617 02618 if ( argc == 1 ) { 02619 ctlFile = vis_stdout; 02620 } 02621 else { 02622 if ( !strcmp( "-h", argv[1] ) || ( argc > 2 ) ) { 02623 fprintf( vis_stdout, "Usage: _init_state_formula [-h] init_file\n\tinit_file - file to write init state formula to (default is stdout)\n"); 02624 return 1; 02625 } 02626 ctlFile = Cmd_FileOpen( argv[1], "w", NIL(char *), 0 ); 02627 } 02628 02629 modelFsm = Fsm_HrcManagerReadCurrentFsm(*hmgr); 02630 if (modelFsm == NIL(Fsm_Fsm_t)) { 02631 if ( argc != 1 ) { 02632 fclose( ctlFile ); 02633 } 02634 return 1; 02635 } 02636 stateVars = Fsm_FsmReadPresentStateVars( modelFsm ); 02637 02638 modelInitialStates = Fsm_FsmComputeInitialStates( modelFsm ); 02639 if ( modelInitialStates == NIL(mdd_t) ) { 02640 (void) fprintf( vis_stdout, "** mc error: - cant build init states (mutual latch dependancy?)\n%s\n", 02641 error_string() ); 02642 if ( argc != 1 ) { 02643 fclose( ctlFile ); 02644 } 02645 return 1; 02646 } 02647 anInitialState = Mc_ComputeAState( modelInitialStates, modelFsm ); 02648 mdd_free(modelInitialStates); 02649 02650 formulaTxt = McStatePrintAsFormula( anInitialState, stateVars, modelFsm ); 02651 mdd_free(anInitialState); 02652 02653 fprintf( ctlFile, "AG EF %s;\n", formulaTxt ); 02654 FREE(formulaTxt); 02655 02656 if ( argc != 1 ) { 02657 fclose(ctlFile); 02658 } 02659 02660 return 0; 02661 } 02662 02663 02664 02672 char * 02673 McStatePrintAsFormula( 02674 mdd_t *aMinterm, 02675 array_t *aSupport, 02676 Fsm_Fsm_t *modelFsm) 02677 { 02678 int i; 02679 char *tmp1String; 02680 char *tmp2String; 02681 char *tmp3String; 02682 char bodyString[McMaxStringLength_c]; 02683 char *mintermString = NIL(char); 02684 mdd_manager *mddMgr = Ntk_NetworkReadMddManager( Fsm_FsmReadNetwork( modelFsm ) ); 02685 Ntk_Network_t *aNetwork = Fsm_FsmReadNetwork( modelFsm ); 02686 array_t *valueArray = McConvertMintermToValueArray( aMinterm, aSupport, mddMgr ); 02687 array_t *stringArray = array_alloc( char *, 0 ); 02688 02689 for ( i = 0 ; i < array_n( aSupport ); i++ ) { 02690 02691 int mddId = array_fetch( int, aSupport, i ); 02692 int value = array_fetch( int, valueArray, i ); 02693 Ntk_Node_t *node = Ntk_NetworkFindNodeByMddId( aNetwork, mddId ); 02694 char *nodeName = Ntk_NodeReadName( node ); 02695 Var_Variable_t *nodeVar = Ntk_NodeReadVariable( node ); 02696 02697 if ( Var_VariableTestIsSymbolic( nodeVar ) ) { 02698 char *symbolicValue = Var_VariableReadSymbolicValueFromIndex( nodeVar, value ); 02699 sprintf( bodyString, "%s=%s", nodeName, symbolicValue ); 02700 } 02701 else { 02702 sprintf( bodyString, "%s=%d", nodeName, value ); 02703 } 02704 tmp1String = util_strsav( bodyString ); 02705 array_insert_last( char *, stringArray, tmp1String ); 02706 } 02707 array_free(valueArray); 02708 02709 array_sort( stringArray, cmp); 02710 02711 for ( i = 0 ; i < array_n( stringArray ); i++ ) { 02712 tmp1String = array_fetch( char *, stringArray, i ); 02713 if( i == 0 ) { 02714 mintermString = util_strcat3("(", tmp1String, ")" ); 02715 } 02716 else { 02717 tmp2String = util_strcat3( mintermString, " * (", tmp1String ); 02718 FREE(mintermString); 02719 tmp3String = util_strcat3( tmp2String, ")", "" ); 02720 FREE(tmp2String); 02721 mintermString = tmp3String; 02722 } 02723 FREE(tmp1String); 02724 } 02725 array_free( stringArray ); 02726 02727 tmp1String = util_strcat3( "( ", mintermString, " )" ); 02728 FREE(mintermString); 02729 mintermString = tmp1String; 02730 02731 return mintermString; 02732 } 02733 02753 int 02754 McComputeOnionRingsWithClosestCore( 02755 mdd_t *aState, 02756 array_t *arrayOfOnionRings, 02757 Fsm_Fsm_t *modelFsm) 02758 { 02759 int index; 02760 int distance = 0; 02761 02762 while( TRUE ) { 02763 for( index = 0 ; index < array_n( arrayOfOnionRings ) ; index++ ) { 02764 array_t *iOnionRings = array_fetch( array_t *, arrayOfOnionRings, index ); 02765 02766 /* will crash if run out of rings -> if not in there */ 02767 mdd_t *stateSet = array_fetch( mdd_t *, iOnionRings, distance ); 02768 02769 if ( McStateTestMembership( aState, stateSet ) ) 02770 return index; 02771 } 02772 distance++; 02773 } 02774 assert(0); 02775 } 02776 02777 02778 02789 array_t * 02790 McRemoveIndexedOnionRings( 02791 int index, 02792 array_t *arrayOfOnionRings) 02793 { 02794 int i; 02795 array_t *dupArrayOfOnionRings = array_alloc( array_t *, 0 ); 02796 array_t *OnionRings; 02797 02798 for ( i = 0 ; i < array_n( arrayOfOnionRings ) ; i++ ) { 02799 if ( i == index ) { 02800 continue; 02801 } 02802 OnionRings = array_fetch( array_t *, arrayOfOnionRings, i ); 02803 array_insert_last( array_t *, dupArrayOfOnionRings, OnionRings ); 02804 } 02805 02806 return dupArrayOfOnionRings; 02807 } 02808 02809 02810 02811 02812 02813 02814 02822 array_t * 02823 McConvertMintermToValueArray( 02824 mdd_t *aMinterm, 02825 array_t *aSupport, 02826 mdd_manager *mddMgr) 02827 { 02828 array_t *resultValueArray; 02829 02830 /* this will be performed only in v0s-g executables */ 02831 assert( MintermCheckWellFormed( aMinterm, aSupport, mddMgr )); 02832 02833 resultValueArray = array_alloc( int, 0 ); 02834 { 02835 int i; 02836 for( i = 0 ; i < array_n( aSupport ); i++ ) { 02837 int aSupportVar = array_fetch( int, aSupport, i ); 02838 int j; 02839 for( j = 0 ; TRUE ; j++) { 02840 02841 mdd_t *faceMdd, *tmpMdd; 02842 array_t *tmpArray = array_alloc( int, 0 ); 02843 02844 array_insert_last( int, tmpArray, j ); 02845 faceMdd = mdd_literal( mddMgr, aSupportVar, tmpArray ); 02846 array_free( tmpArray ); 02847 02848 tmpMdd = mdd_and( faceMdd, aMinterm, 1, 1 ); 02849 mdd_free( faceMdd ); 02850 if ( !mdd_is_tautology( tmpMdd, 0 ) ) { 02851 mdd_free( tmpMdd ); 02852 array_insert_last( int, resultValueArray, j ); 02853 break; 02854 } 02855 mdd_free( tmpMdd ); 02856 } 02857 } 02858 } 02859 02860 return resultValueArray; 02861 } 02862 02863 02864 02865 02866 02881 void 02882 McPrintTransitionAiger( 02883 mdd_t *aState, 02884 mdd_t *bState, 02885 mdd_t *uInput, 02886 mdd_t *vInput, 02887 array_t *stateSupport, 02888 array_t *inputSupport, 02889 boolean printInputs, 02890 Fsm_Fsm_t *modelFsm, 02891 int seqNumber) 02892 { 02893 Ntk_Network_t *modelNetwork = Fsm_FsmReadNetwork( modelFsm ); 02894 char *aString = aState ? Mc_MintermToStringAiger( aState, stateSupport, modelNetwork ) : NIL(char); 02895 char *bString = Mc_MintermToStringAiger( bState, stateSupport, modelNetwork ); 02896 char *inpString = aState ? Mc_MintermToStringAigerInput( aState, stateSupport, modelNetwork ) : NIL(char); 02897 02898 st_table *node2MvfAigTable; 02899 02900 node2MvfAigTable = 02901 (st_table *)Ntk_NetworkReadApplInfo(modelNetwork, MVFAIG_NETWORK_APPL_KEY); 02902 02903 if ( aState == NIL(mdd_t) ) { 02904 FREE(bString); 02905 return; 02906 } 02907 02908 fprintf(vis_stdout, "%s", aString); 02909 fprintf(vis_stdout, "%s", inpString); 02910 02911 02912 /* first test that there are inputs */ 02913 /* if ( array_n( inputSupport ) > 0 ) { 02914 if ( uInput == NIL(mdd_t) ) { 02915 char *vString = Mc_MintermToStringAiger( vInput, inputSupport, modelNetwork ); 02916 FREE(vString); 02917 } 02918 else { 02919 boolean unchanged=TRUE; 02920 char *uString = Mc_MintermToStringAiger( uInput, inputSupport, modelNetwork ); 02921 char *vString = Mc_MintermToStringAiger( vInput, inputSupport, modelNetwork ); 02922 FREE(uString); 02923 FREE(vString); 02924 } 02925 } */ 02926 02927 if(seqNumber == 1) 02928 { 02929 fprintf(vis_stdout, "1 "); 02930 } 02931 else 02932 { 02933 fprintf(vis_stdout, "0 "); 02934 } 02935 02936 02937 fprintf(vis_stdout, "%s", bString); 02938 02939 FREE( aString ); 02940 FREE( bString ); 02941 fprintf (vis_stdout, "\n"); 02942 return; 02943 } 02944 02945 02946 02947 02962 void 02963 McPrintTransition( 02964 mdd_t *aState, 02965 mdd_t *bState, 02966 mdd_t *uInput, 02967 mdd_t *vInput, 02968 array_t *stateSupport, 02969 array_t *inputSupport, 02970 boolean printInputs, 02971 Fsm_Fsm_t *modelFsm, 02972 int seqNumber) 02973 { 02974 Ntk_Network_t *modelNetwork = Fsm_FsmReadNetwork( modelFsm ); 02975 char *aString = aState ? Mc_MintermToString( aState, stateSupport, modelNetwork ) : NIL(char); 02976 char *bString = Mc_MintermToString( bState, stateSupport, modelNetwork ); 02977 02978 char *tmp1String = aString; 02979 char *tmp2String = bString; 02980 char *ptr1; 02981 char *ptr2; 02982 st_table *node2MvfAigTable; 02983 02984 node2MvfAigTable = 02985 (st_table *)Ntk_NetworkReadApplInfo(modelNetwork, MVFAIG_NETWORK_APPL_KEY); 02986 02987 if ( aState == NIL(mdd_t) ) { 02988 fprintf( vis_stdout, "--State %d:\n%s\n", seqNumber, bString ); 02989 FREE(bString); 02990 return; 02991 } 02992 02993 fprintf(vis_stdout, "--Goes to state %d:\n", seqNumber ); 02994 02995 { 02996 boolean unchanged=TRUE; 02997 while ( (tmp1String != NIL(char)) && ((ptr1 = strchr( tmp1String, '\n' ) ) != NIL(char) ) ) { 02998 ptr2 = strchr( tmp2String, '\n' ); 02999 *ptr1 = 0; 03000 *ptr2 = 0; 03001 if ( (strcmp( tmp1String, tmp2String ) ) ) { 03002 fprintf( vis_stdout, "%s\n", tmp2String ); 03003 unchanged = FALSE; 03004 } 03005 tmp1String = & (ptr1[1]); 03006 tmp2String = & (ptr2[1]); 03007 } 03008 if (unchanged == TRUE) { 03009 fprintf( vis_stdout, "<Unchanged>\n"); 03010 } 03011 } 03012 03013 03014 if ( printInputs == TRUE ) { 03015 /* first test that there are inputs */ 03016 if ( array_n( inputSupport ) > 0 ) { 03017 fprintf(vis_stdout, "--On input:\n"); 03018 if ( uInput == NIL(mdd_t) ) { 03019 char *vString = Mc_MintermToString( vInput, inputSupport, modelNetwork ); 03020 fprintf(vis_stdout, "%s", vString ); 03021 FREE(vString); 03022 } 03023 else { 03024 boolean unchanged=TRUE; 03025 char *uString = Mc_MintermToString( uInput, inputSupport, modelNetwork ); 03026 char *vString = Mc_MintermToString( vInput, inputSupport, modelNetwork ); 03027 tmp1String = uString; 03028 tmp2String = vString; 03029 while ( (tmp1String != NIL(char)) && ((ptr1 = strchr( tmp1String, '\n' ) ) != NIL(char) ) ) { 03030 ptr2 = strchr( tmp2String, '\n' ); 03031 *ptr1 = 0; 03032 *ptr2 = 0; 03033 if ( (strcmp( tmp1String, tmp2String ) ) ) { 03034 fprintf( vis_stdout, "%s\n", tmp2String ); 03035 unchanged = FALSE; 03036 } 03037 tmp1String = & (ptr1[1]); 03038 tmp2String = & (ptr2[1]); 03039 } 03040 if (unchanged == TRUE) { 03041 fprintf( vis_stdout, "<Unchanged>\n"); 03042 } 03043 FREE(uString); 03044 FREE(vString); 03045 } 03046 } 03047 } 03048 03049 FREE( aString ); 03050 FREE( bString ); 03051 fprintf (vis_stdout, "\n"); 03052 } 03053 03054 03062 void 03063 McStatePassesFormula( 03064 mdd_t *aState, 03065 Ctlp_Formula_t *formula, 03066 McDbgLevel debugLevel, 03067 Fsm_Fsm_t *modelFsm) 03068 { 03069 McStatePassesOrFailsFormula( aState, formula, 1, debugLevel, modelFsm ); 03070 } 03071 03072 03080 void 03081 McStateFailsFormula( 03082 mdd_t *aState, 03083 Ctlp_Formula_t *formula, 03084 McDbgLevel debugLevel, 03085 Fsm_Fsm_t *modelFsm) 03086 { 03087 McStatePassesOrFailsFormula( aState, formula, 0, debugLevel, modelFsm ); 03088 } 03089 03090 03098 void 03099 McStatePassesOrFailsFormula( 03100 mdd_t *aState, 03101 Ctlp_Formula_t *formula, 03102 int pass, 03103 McDbgLevel debugLevel, 03104 Fsm_Fsm_t *modelFsm) 03105 { 03106 array_t *PSVars = Fsm_FsmReadPresentStateVars( modelFsm ); 03107 char *formulaText = Ctlp_FormulaConvertToString( formula ); 03108 Ntk_Network_t *modelNetwork = Fsm_FsmReadNetwork( modelFsm ); 03109 03110 /* Nodes created in converting formulae like AU may not have text 03111 * attached to them. */ 03112 if (formulaText == NIL(char)) 03113 return; 03114 03115 fprintf( vis_stdout, "--State\n"); 03116 Mc_MintermPrint( aState, PSVars, modelNetwork ); 03117 if ( pass ) 03118 fprintf( vis_stdout, "passes "); 03119 else 03120 fprintf( vis_stdout, "fails "); 03121 03122 if( debugLevel > McDbgLevelMin_c) 03123 fprintf(vis_stdout, "%s.\n\n", formulaText); 03124 else 03125 fprintf(vis_stdout, "\n\n"); 03126 03127 FREE(formulaText); 03128 } 03129 03130 03131 03144 McPath_t * 03145 McPathNormalize( 03146 McPath_t *aPath) 03147 { 03148 int i, j; 03149 int forced; 03150 03151 array_t *stemArray = McPathReadStemArray( aPath ); 03152 array_t *cycleArray = McPathReadCycleArray( aPath ); 03153 03154 McPath_t *result = McPathAlloc(); 03155 array_t *newStem = array_alloc( mdd_t *, 0 ); 03156 array_t *newCycle = array_alloc( mdd_t *, 0 ); 03157 03158 mdd_t *lastState = GET_NORMAL_PT(array_fetch_last(mdd_t *, cycleArray)); 03159 03160 McPathSetStemArray( result, newStem ); 03161 McPathSetCycleArray( result, newCycle ); 03162 03163 for( i = 0 ; i < array_n( stemArray ) ; i++ ) { 03164 mdd_t *tmpState = array_fetch( mdd_t *, stemArray, i ); 03165 forced = 0; 03166 if((long)tmpState % 2) { 03167 forced = 1; 03168 tmpState = (mdd_t *)((long)tmpState - 1); 03169 } 03170 array_insert_last(mdd_t *, newStem, 03171 (mdd_t *)((long)(mdd_dup(tmpState)) + forced) ); 03172 03173 if ( mdd_equal( lastState, tmpState ) ) { 03174 break; 03175 } 03176 } 03177 03178 for( j = i; j < array_n( stemArray ); j++ ) { 03179 mdd_t *tmpState = array_fetch( mdd_t *, stemArray, j ); 03180 forced = 0; 03181 if((long)tmpState % 2) { 03182 forced = 1; 03183 tmpState = (mdd_t *)((long)tmpState - 1); 03184 } 03185 03186 array_insert_last(mdd_t *, newCycle, 03187 (mdd_t *)((long)(mdd_dup(tmpState)) + forced) ); 03188 03189 } 03190 03191 /* first state of cycle array == last state of stem array => start from j=1 */ 03192 for( j = 1; j < array_n( cycleArray ); j++ ) { 03193 mdd_t *tmpState = array_fetch( mdd_t *, cycleArray, j ); 03194 forced = 0; 03195 if((long)tmpState % 2) { 03196 forced = 1; 03197 tmpState = (mdd_t *)((long)tmpState - 1); 03198 } 03199 array_insert_last(mdd_t *, newCycle, 03200 (mdd_t *)((long)(mdd_dup(tmpState)) + forced) ); 03201 03202 } 03203 03204 return result; 03205 03206 } 03207 03208 03209 03222 array_t * 03223 McCreateMergedPath( 03224 array_t *aPath, 03225 array_t *bPath) 03226 { 03227 int i, pos, forced; 03228 mdd_t *tmpState, *endOfAPath; 03229 array_t *aPathDup = McMddArrayDuplicateFAFW( aPath ); 03230 array_t *bPathDup = McMddArrayDuplicateFAFW( bPath ); 03231 03232 for( i = 1 ; i < array_n( bPathDup ) ; i++ ) { 03233 tmpState = array_fetch( mdd_t *, bPathDup, i ); 03234 array_insert_last( mdd_t *, aPathDup, tmpState ); 03235 } 03236 pos = array_n(aPathDup) - array_n(bPathDup); 03237 endOfAPath = array_fetch(mdd_t *, aPathDup, pos); 03238 03239 tmpState = array_fetch( mdd_t *, bPathDup, 0 ); 03240 forced = 0; 03241 if((long)tmpState % 2) { 03242 forced = 1; 03243 tmpState = (mdd_t *)((long)tmpState - 1); 03244 } 03245 if(forced && mdd_equal(tmpState, endOfAPath)) { 03246 array_insert(mdd_t *, aPathDup, pos, (mdd_t *)((long)endOfAPath + forced) ); 03247 } 03248 03249 mdd_free( tmpState ); 03250 array_free( bPathDup ); 03251 03252 return aPathDup; 03253 } 03254 03266 array_t * 03267 McMddArrayDuplicateFAFW(array_t *mddArray) 03268 { 03269 int i, forced; 03270 mdd_t *newTempMdd; 03271 int length = array_n(mddArray); 03272 array_t *result = array_alloc(mdd_t *, length); 03273 03274 for (i = 0; i < length; i++) { 03275 mdd_t *tempMdd = array_fetch(mdd_t *, mddArray, i); 03276 forced = 0; 03277 if((long)tempMdd % 2) { 03278 forced = 1; 03279 tempMdd = (mdd_t *)((long)tempMdd - 1); 03280 } 03281 03282 newTempMdd = mdd_dup(tempMdd); 03283 array_insert(mdd_t *, result, i, (mdd_t *)((long)newTempMdd + forced)); 03284 } 03285 03286 return (result); 03287 } 03288 03298 mdd_t * 03299 McMddArrayAnd(array_t *mddArray) 03300 { 03301 mdd_t *result, *mdd1, *mdd2 = NIL(mdd_t); 03302 int i; 03303 03304 result = NIL(mdd_t); 03305 arrayForEachItem(mdd_t *, mddArray, i, mdd1) { 03306 if (result == NIL(mdd_t)) 03307 result = mdd_dup(mdd1); 03308 else { 03309 mdd2 = result; 03310 result = mdd_and(result, mdd1, 1, 1); 03311 mdd_free(mdd2); 03312 } 03313 } 03314 03315 return (result); 03316 } 03317 03327 mdd_t * 03328 McMddArrayOr(array_t *mddArray) 03329 { 03330 mdd_t *result, *mdd1, *mdd2 = NIL(mdd_t); 03331 int i; 03332 03333 result = NIL(mdd_t); 03334 arrayForEachItem(mdd_t *, mddArray, i, mdd1) { 03335 if (result == NIL(mdd_t)) 03336 result = mdd_dup(mdd1); 03337 else { 03338 mdd2 = result; 03339 result = mdd_or(result, mdd1, 1, 1); 03340 mdd_free(mdd2); 03341 } 03342 } 03343 03344 return (result); 03345 } 03346 03359 array_t * 03360 McCreateJoinedPath( 03361 array_t *aPath, 03362 array_t *bPath) 03363 { 03364 int i; 03365 mdd_t *tmpState; 03366 array_t *aPathDup = McMddArrayDuplicateFAFW( aPath ); 03367 array_t *bPathDup = McMddArrayDuplicateFAFW( bPath ); 03368 03369 for( i = 0 ; i < array_n( bPathDup ) ; i++ ) { 03370 tmpState = array_fetch( mdd_t *, bPathDup, i ); 03371 array_insert_last( mdd_t *, aPathDup, tmpState ); 03372 } 03373 array_free( bPathDup ); 03374 03375 return aPathDup; 03376 } 03377 03378 03386 boolean 03387 McStateSatisfiesFormula( 03388 Ctlp_Formula_t *aFormula, 03389 mdd_t *aState ) 03390 { 03391 mdd_t *passStates = Ctlp_FormulaObtainLatestApprox( aFormula ); 03392 03393 if ( mdd_lequal( aState, passStates, 1, 1 ) ) { 03394 mdd_free( passStates ); 03395 return TRUE; 03396 } 03397 else { 03398 mdd_free( passStates ); 03399 return FALSE; 03400 } 03401 } 03402 03403 03404 03412 boolean 03413 McStateTestMembership( 03414 mdd_t *aState, 03415 mdd_t *setOfStates ) 03416 { 03417 return mdd_lequal( aState, setOfStates, 1, 1 ); 03418 } 03419 03427 mdd_t * 03428 McGetSuccessorInTarget( 03429 mdd_t *aState, 03430 mdd_t *targetStates, 03431 Fsm_Fsm_t *modelFsm ) 03432 { 03433 mdd_t *tmpMdd, *succsInTarget, *result; 03434 array_t *careSetArray = array_alloc(mdd_t *, 0); 03435 Img_ImageInfo_t * imageInfo = Fsm_FsmReadOrCreateImageInfo(modelFsm, 0, 1); 03436 03437 array_insert_last(mdd_t *, careSetArray, targetStates); 03438 tmpMdd = Img_ImageInfoComputeImageWithDomainVars(imageInfo, aState, 03439 aState, careSetArray); 03440 array_free(careSetArray); 03441 succsInTarget = mdd_and(tmpMdd, targetStates, 1, 1); 03442 #if 1 03443 result = Mc_ComputeAState(succsInTarget, modelFsm); 03444 #else 03445 result = Mc_ComputeACloseState(succsInTarget, aState, modelFsm); 03446 #endif 03447 03448 mdd_free( tmpMdd ); 03449 mdd_free( succsInTarget ); 03450 03451 return result; 03452 } 03453 03461 mdd_t * 03462 McGetSuccessorInTargetAmongFairStates( 03463 mdd_t *aState, 03464 mdd_t *targetStates, 03465 array_t *arrayOfOnionRings, 03466 Fsm_Fsm_t *modelFsm ) 03467 { 03468 mdd_t *tmpMdd, *succsInTarget, *result; 03469 mdd_t *fairStates, *newFairStates, *onionRing; 03470 mdd_t *targetStatesInFairStates; 03471 array_t *onionRings; 03472 int i, j; 03473 array_t *careSetArray = array_alloc(mdd_t *, 0); 03474 03475 Img_ImageInfo_t * imageInfo = Fsm_FsmReadOrCreateImageInfo(modelFsm, 0, 1); 03476 03477 03478 fairStates = 0; 03479 for(i=0; i<array_n(arrayOfOnionRings); i++) { 03480 onionRings = array_fetch(array_t *, arrayOfOnionRings, i); 03481 for(j=0; j<array_n(onionRings); j++) { 03482 onionRing = array_fetch(mdd_t *,onionRings, j); 03483 03484 if(fairStates) { 03485 newFairStates = mdd_or(fairStates, onionRing, 1, 1); 03486 mdd_free(fairStates); 03487 fairStates = newFairStates; 03488 } 03489 else { 03490 fairStates = mdd_dup(onionRing); 03491 } 03492 } 03493 } 03494 targetStatesInFairStates = mdd_and(fairStates, targetStates, 1, 1); 03495 mdd_free(fairStates); 03496 03497 array_insert_last(mdd_t *, careSetArray, targetStatesInFairStates); 03498 tmpMdd = Img_ImageInfoComputeImageWithDomainVars(imageInfo, aState, 03499 aState, careSetArray); 03500 succsInTarget = mdd_and(tmpMdd, targetStatesInFairStates, 1, 1); 03501 mdd_array_free(careSetArray); 03502 result = Mc_ComputeACloseState(succsInTarget, aState, modelFsm); 03503 03504 mdd_free( tmpMdd ); 03505 mdd_free( succsInTarget ); 03506 03507 return result; 03508 } 03509 03510 03518 array_t * 03519 McPathReadStemArray( 03520 McPath_t *aPath ) 03521 { 03522 return aPath->stemArray; 03523 } 03524 03532 array_t * 03533 McPathReadCycleArray( 03534 McPath_t *aPath ) 03535 { 03536 return aPath->cycleArray; 03537 } 03538 03546 void 03547 McPathSetStemArray( 03548 McPath_t *aPath, 03549 array_t *stemArray) 03550 { 03551 aPath->stemArray = stemArray; 03552 } 03553 03561 void 03562 McPathSetCycleArray( 03563 McPath_t *aPath, 03564 array_t *cycleArray ) 03565 { 03566 aPath->cycleArray = cycleArray; 03567 } 03568 03576 McPath_t * 03577 McPathAlloc(void) 03578 { 03579 McPath_t *tmpPath = ( McPath_t * ) malloc( sizeof( McPath_t ) ); 03580 03581 tmpPath->stemArray = NIL(array_t); 03582 tmpPath->cycleArray = NIL(array_t); 03583 03584 return tmpPath; 03585 } 03586 03594 void 03595 McNormalizeBddPointer(array_t *bddArray) 03596 { 03597 int i; 03598 bdd_t *p; 03599 03600 for(i=0; i<array_n(bddArray); i++) { 03601 p = array_fetch(bdd_t *, bddArray, i); 03602 if((long)p%2) p = (mdd_t *)( (long)p -1 ); 03603 array_insert(bdd_t *, bddArray, i, p); 03604 } 03605 } 03606 03607 void 03608 McPathFree( 03609 McPath_t * aPath ) 03610 { 03611 if ( aPath->stemArray ) { 03612 McNormalizeBddPointer(aPath->stemArray); 03613 mdd_array_free( aPath->stemArray ); 03614 } 03615 03616 if ( aPath->cycleArray ) { 03617 McNormalizeBddPointer(aPath->cycleArray); 03618 mdd_array_free( aPath->cycleArray ); 03619 } 03620 03621 FREE( aPath ); 03622 } 03623 03631 McOptions_t * 03632 McOptionsAlloc(void) 03633 { 03634 McOptions_t *result = ALLOC(McOptions_t, 1); 03635 03636 memset(result, 0, sizeof(McOptions_t)); 03637 03638 result->useMore = FALSE; 03639 result->reduceFsm = FALSE; 03640 result->printInputs = FALSE; 03641 result->useFormulaTree = FALSE; 03642 result->simFormat = FALSE; 03643 result->ctlFile = NIL(FILE); 03644 result->guideFile = NIL(FILE); 03645 result->debugFile = NIL(FILE); 03646 result->fwdBwd = McFwd_c; 03647 result->dcLevel = McDcLevelNone_c; 03648 result->dbgLevel = McDbgLevelMin_c; 03649 result->schedule = McGSH_EL_c; 03650 result->lockstep = MC_LOCKSTEP_OFF; 03651 result->verbosityLevel = McVerbosityNone_c; 03652 result->timeOutPeriod = 0; 03653 result->ardcOptions = NIL(Fsm_ArdcOptions_t); 03654 result->invarApproxFlag = Fsm_Rch_Default_c; 03655 result->invarOnionRingsFlag = FALSE; 03656 result->traversalDirection = McBwd_c; 03657 result->doCoverageHoskote = FALSE; 03658 result->doCoverageImproved = FALSE; 03659 result->incre = TRUE; 03660 03661 03662 return result; 03663 } 03664 03672 void 03673 McOptionsFree( 03674 McOptions_t *options) 03675 { 03676 if (options->debugFile != NIL(FILE)){ 03677 fclose(options->debugFile); 03678 } 03679 if (options->ardcOptions != NIL(Fsm_ArdcOptions_t)){ 03680 FREE(options->ardcOptions); 03681 } 03682 FREE(options); 03683 } 03684 03685 03693 McDbgLevel 03694 McOptionsReadDbgLevel( 03695 McOptions_t *options ) 03696 { 03697 return options->dbgLevel; 03698 } 03699 03708 FILE * 03709 McOptionsReadGuideFile( 03710 McOptions_t *options ) 03711 { 03712 return options->guideFile; 03713 } 03714 03722 FILE * 03723 McOptionsReadSystemFile( 03724 McOptions_t *options ) 03725 { 03726 return options->systemFile; 03727 } 03728 03736 int 03737 McOptionsReadTimeOutPeriod( 03738 McOptions_t *options ) 03739 { 03740 return options->timeOutPeriod; 03741 } 03742 03750 Mc_VerbosityLevel 03751 McOptionsReadVerbosityLevel( 03752 McOptions_t *options ) 03753 { 03754 return options->verbosityLevel; 03755 } 03756 03764 Mc_LeMethod_t 03765 McOptionsReadLeMethod( 03766 McOptions_t *options ) 03767 { 03768 return options->leMethod; 03769 } 03770 03778 Mc_DcLevel 03779 McOptionsReadDcLevel( 03780 McOptions_t *options ) 03781 { 03782 return options->dcLevel; 03783 } 03784 03792 FILE * 03793 McOptionsReadCtlFile( 03794 McOptions_t *options ) 03795 { 03796 return options->ctlFile; 03797 } 03798 03806 FILE * 03807 McOptionsReadDebugFile( 03808 McOptions_t *options ) 03809 { 03810 return options->debugFile; 03811 } 03812 03820 int 03821 McOptionsReadSimValue( 03822 McOptions_t *options) 03823 { 03824 return options->simFormat; 03825 } 03826 03834 int 03835 McOptionsReadUseMore( 03836 McOptions_t *options) 03837 { 03838 return options->useMore; 03839 } 03840 03848 boolean 03849 McOptionsReadVacuityDetect( 03850 McOptions_t *options) 03851 { 03852 return options->vd ; 03853 } 03854 03862 int 03863 McOptionsReadBeerMethod( 03864 McOptions_t *options) 03865 { 03866 return options->beer ; 03867 } 03868 03869 03877 int 03878 McOptionsReadReduceFsm( 03879 McOptions_t *options) 03880 { 03881 return options->reduceFsm; 03882 } 03883 03891 int 03892 McOptionsReadPrintInputs( 03893 McOptions_t *options) 03894 { 03895 return options->printInputs; 03896 } 03897 03905 boolean 03906 McOptionsReadUseFormulaTree( 03907 McOptions_t *options) 03908 { 03909 return options->useFormulaTree; 03910 } 03911 03919 Mc_GSHScheduleType 03920 McOptionsReadSchedule( 03921 McOptions_t *options) 03922 { 03923 return options->schedule; 03924 } 03925 03933 int 03934 McOptionsReadLockstep( 03935 McOptions_t *options) 03936 { 03937 return options->lockstep; 03938 } 03939 03947 Fsm_RchType_t 03948 McOptionsReadInvarApproxFlag( 03949 McOptions_t *options) 03950 { 03951 return (options->invarApproxFlag); 03952 } 03953 03961 boolean 03962 McOptionsReadInvarOnionRingsFlag( 03963 McOptions_t *options) 03964 { 03965 return (options->invarOnionRingsFlag); 03966 } 03967 03975 Mc_FwdBwdAnalysis 03976 McOptionsReadFwdBwd( 03977 McOptions_t *options) 03978 { 03979 return options->fwdBwd; 03980 } 03981 03989 Mc_FwdBwdAnalysis 03990 McOptionsReadTraversalDirection( 03991 McOptions_t *options) 03992 { 03993 return options->traversalDirection; 03994 } 03995 04003 Fsm_ArdcOptions_t * 04004 McOptionsReadArdcOptions( 04005 McOptions_t *options) 04006 { 04007 return options->ardcOptions; 04008 } 04009 04010 04018 int 04019 McOptionsReadCoverageHoskote( 04020 McOptions_t *options) 04021 { 04022 return options->doCoverageHoskote; 04023 } 04024 04032 int 04033 McOptionsReadCoverageImproved( 04034 McOptions_t *options) 04035 { 04036 return options->doCoverageImproved; 04037 } 04038 04046 void 04047 McOptionsSetFwdBwd( 04048 McOptions_t *options, 04049 Mc_FwdBwdAnalysis fwdBwd ) 04050 { 04051 options->fwdBwd = fwdBwd; 04052 } 04053 04061 void 04062 McOptionsSetGuideFile( 04063 McOptions_t *options, 04064 FILE *guideFile ) 04065 { 04066 options->guideFile = guideFile; 04067 } 04068 04076 void 04077 McOptionsSetVariablesForSystem( 04078 McOptions_t *options, 04079 FILE *systemFile ) 04080 { 04081 options->systemFile = systemFile; 04082 } 04090 void 04091 McOptionsSetTraversalDirection( 04092 McOptions_t *options, 04093 Mc_FwdBwdAnalysis fwdBwd ) 04094 { 04095 options->traversalDirection = fwdBwd; 04096 } 04097 04105 void 04106 McOptionsSetUseMore( 04107 McOptions_t *options, 04108 boolean useMore ) 04109 { 04110 options->useMore = useMore; 04111 } 04112 04120 void 04121 McOptionsSetReduceFsm( 04122 McOptions_t *options, 04123 boolean reduceFsm ) 04124 { 04125 options->reduceFsm = reduceFsm; 04126 } 04127 04135 void 04136 McOptionsSetVacuityDetect( 04137 McOptions_t *options, 04138 boolean vd ) 04139 { 04140 options->vd = vd; 04141 } 04142 04150 void 04151 McOptionsSetBeerMethod( 04152 McOptions_t *options, 04153 boolean beer ) 04154 { 04155 options->beer = beer; 04156 } 04157 04165 void 04166 McOptionsSetFAFWFlag( 04167 McOptions_t *options, 04168 boolean FAFWFlag ) 04169 { 04170 options->FAFWFlag = FAFWFlag; 04171 } 04179 void 04180 McOptionsSetPrintInputs( 04181 McOptions_t *options, 04182 boolean printInputs ) 04183 { 04184 options->printInputs = printInputs; 04185 } 04186 04194 void 04195 McOptionsSetUseFormulaTree( 04196 McOptions_t *options, 04197 boolean useFormulaTree ) 04198 { 04199 options->useFormulaTree = useFormulaTree; 04200 } 04201 04209 void 04210 McOptionsSetSchedule( 04211 McOptions_t *options, 04212 Mc_GSHScheduleType schedule ) 04213 { 04214 options->schedule = schedule; 04215 } 04216 04224 void 04225 McOptionsSetLockstep( 04226 McOptions_t *options, 04227 int lockstep ) 04228 { 04229 options->lockstep = lockstep; 04230 } 04231 04239 void 04240 McOptionsSetSimValue( 04241 McOptions_t *options, 04242 boolean simValue ) 04243 { 04244 options->simFormat = simValue; 04245 } 04246 04254 void 04255 McOptionsSetDbgLevel( 04256 McOptions_t *options, 04257 McDbgLevel dbgLevel ) 04258 { 04259 options->dbgLevel = dbgLevel; 04260 } 04261 04269 void 04270 McOptionsSetVerbosityLevel( 04271 McOptions_t *options, 04272 Mc_VerbosityLevel verbosityLevel ) 04273 { 04274 options->verbosityLevel = verbosityLevel; 04275 } 04276 04284 void 04285 McOptionsSetLeMethod( 04286 McOptions_t *options, 04287 Mc_LeMethod_t leMethod) 04288 { 04289 options->leMethod = leMethod; 04290 } 04291 04299 void 04300 McOptionsSetDcLevel( 04301 McOptions_t *options, 04302 Mc_DcLevel dcLevel) 04303 { 04304 options->dcLevel = dcLevel; 04305 } 04306 04314 void 04315 McOptionsSetArdcOptions( 04316 McOptions_t *options, 04317 Fsm_ArdcOptions_t *ardcOptions) 04318 { 04319 options->ardcOptions = ardcOptions; 04320 } 04321 04329 void 04330 McOptionsSetInvarOnionRingsFlag( 04331 McOptions_t *options, int shellFlag) 04332 { 04333 if (shellFlag) options->invarOnionRingsFlag = TRUE; 04334 else options->invarOnionRingsFlag = FALSE; 04335 } 04336 04337 04345 void 04346 McOptionsSetCtlFile( 04347 McOptions_t *options, 04348 FILE *file) 04349 { 04350 options->ctlFile = file; 04351 } 04352 04360 void 04361 McOptionsSetDebugFile( 04362 McOptions_t *options, 04363 FILE *file) 04364 { 04365 options->debugFile = file; 04366 } 04367 04375 void 04376 McOptionsSetTimeOutPeriod( 04377 McOptions_t *options, 04378 int timeOutPeriod) 04379 { 04380 options->timeOutPeriod = timeOutPeriod; 04381 } 04382 04390 void 04391 McOptionsSetInvarApproxFlag( 04392 McOptions_t *options, 04393 Fsm_RchType_t approxFlag) 04394 { 04395 options->invarApproxFlag = approxFlag; 04396 } 04397 04398 04399 04407 void 04408 McOptionsSetCoverageHoskote( 04409 McOptions_t *options, 04410 boolean doCoverageHoskote ) 04411 { 04412 options->doCoverageHoskote = doCoverageHoskote; 04413 } 04414 04422 void 04423 McOptionsSetCoverageImproved( 04424 McOptions_t *options, 04425 boolean doCoverageImproved ) 04426 { 04427 options->doCoverageImproved = doCoverageImproved; 04428 } 04429 04430 04438 boolean 04439 McQueryContinue(char *query) 04440 { 04441 char result[2]; 04442 04443 fprintf(vis_stdout, "%s", query); 04444 if (fgets(result, 2, stdin) == NULL) return FALSE; 04445 04446 if(!strcmp(result,"1")) 04447 return TRUE; 04448 else if(!strcmp(result,"0")) 04449 return FALSE; 04450 else { 04451 fprintf(vis_stdout, "-- Must enter 0/1\n"); 04452 return McQueryContinue(query); 04453 } 04454 } 04455 04456 04465 void 04466 McPrintSupport( 04467 mdd_t *aMdd, 04468 mdd_manager *mddMgr, 04469 Ntk_Network_t *aNetwork ) 04470 { 04471 int i; 04472 char *tmp1String, *tmp2String; 04473 char *mintermString = NIL(char); 04474 char bodyString[McMaxStringLength_c]; 04475 array_t *aSupport = mdd_get_support( mddMgr, aMdd ); 04476 array_t *stringArray = array_alloc( char *, 0 ); 04477 04478 for ( i = 0 ; i < array_n( aSupport ); i++ ) { 04479 04480 int mddId = array_fetch( int, aSupport, i ); 04481 Ntk_Node_t *node = Ntk_NetworkFindNodeByMddId( aNetwork, mddId ); 04482 char *nodeName = Ntk_NodeReadName( node ); 04483 sprintf( bodyString, "%s", nodeName ); 04484 tmp1String = util_strsav( bodyString ); 04485 array_insert_last( char *, stringArray, tmp1String ); 04486 } 04487 04488 array_sort( stringArray, cmp); 04489 04490 for ( i = 0 ; i < array_n( stringArray ); i++ ) { 04491 tmp1String = array_fetch( char *, stringArray, i ); 04492 if( i == 0 ) { 04493 mintermString = util_strcat3(tmp1String, "", "" ); 04494 } 04495 else { 04496 tmp2String = util_strcat3(mintermString, "\n", tmp1String ); 04497 FREE(mintermString); 04498 mintermString = tmp2String; 04499 } 04500 FREE(tmp1String); 04501 } 04502 fprintf(vis_stdout, "%s\n", mintermString ); 04503 } 04504 04505 04506 04517 int 04518 McPrintSimPath( 04519 FILE *outputFile, 04520 array_t *aPath, 04521 Fsm_Fsm_t *modelFsm) 04522 { 04523 int i; 04524 04525 array_t *inputVars = Fsm_FsmReadInputVars( modelFsm ); 04526 array_t *psVars = Fsm_FsmReadPresentStateVars( modelFsm ); 04527 04528 Ntk_Network_t *network = Fsm_FsmReadNetwork( modelFsm ); 04529 mdd_manager *mddMgr = Fsm_FsmReadMddManager( modelFsm ); 04530 04531 array_t *inputSortedVars = SortMddIds( inputVars, network ); 04532 array_t *psSortedVars = SortMddIds( psVars, network ); 04533 04534 fprintf(outputFile, "# UC Berkeley, VIS Release 1.3\n"); 04535 fprintf(outputFile, "# Network: %s\n", Ntk_NetworkReadName( network ) ); 04536 fprintf(outputFile, "# Simulation vectors have been generated to show language non-empty\n\n"); 04537 04538 fprintf( outputFile, ".inputs " ); 04539 PrintNodes( inputSortedVars, network ); 04540 fprintf( outputFile, "\n" ); 04541 04542 fprintf( outputFile, ".latches " ); 04543 PrintNodes( psSortedVars, network ); 04544 fprintf( outputFile, "\n" ); 04545 04546 fprintf( outputFile, ".outputs\n" ); 04547 04548 for( i = -1 ; i < (array_n( aPath ) - 1); i++ ) { 04549 04550 if ( i == -1 ) { 04551 mdd_t *initState = array_fetch( mdd_t *, aPath, (i+1) ); 04552 array_t *initValues = McConvertMintermToValueArray( initState, psSortedVars, mddMgr ); 04553 04554 fprintf( outputFile, ".initial "); 04555 PrintDeck( initValues, psSortedVars, network ); 04556 array_free( initValues ); 04557 04558 fprintf( outputFile, "\n" ); 04559 fprintf( outputFile, ".start_vectors\n"); 04560 } 04561 else { 04562 array_t *psValues; 04563 array_t *nsValues; 04564 array_t *inputValues; 04565 04566 mdd_t *psState = array_fetch( mdd_t *, aPath, i ); 04567 mdd_t *nsState = array_fetch( mdd_t *, aPath, (i+1) ); 04568 mdd_t *inputSet = Mc_FsmComputeDrivingInputMinterms( modelFsm, psState, nsState ); 04569 mdd_t *input = Mc_ComputeAMinterm( inputSet, inputVars, mddMgr ); 04570 04571 inputValues = McConvertMintermToValueArray( input, inputSortedVars, mddMgr ); 04572 PrintDeck( inputValues, inputSortedVars, network ); 04573 array_free( inputValues ); 04574 fprintf( outputFile, " ;"); 04575 04576 psValues = McConvertMintermToValueArray( psState, psSortedVars, mddMgr ); 04577 PrintDeck( psValues, psSortedVars, network ); 04578 array_free( psValues ); 04579 fprintf( outputFile, " ;"); 04580 04581 nsValues = McConvertMintermToValueArray( nsState, psSortedVars, mddMgr ); 04582 PrintDeck( nsValues, psSortedVars, network ); 04583 array_free( nsValues ); 04584 fprintf( outputFile, " ;\n"); 04585 04586 mdd_free( inputSet ); 04587 mdd_free( input ); 04588 } 04589 } 04590 array_free( psSortedVars ); 04591 array_free( inputSortedVars ); 04592 04593 return 1; 04594 } 04595 04596 04608 Fsm_Fsm_t * 04609 McConstructReducedFsm( 04610 Ntk_Network_t *network, 04611 array_t *ctlFormulaArray ) 04612 { 04613 int i; 04614 Ntk_Node_t *node; 04615 array_t *nodeArray; 04616 st_table *formulaNodes; 04617 Ctlp_Formula_t *fairnessCondition; 04618 Ctlp_Formula_t *ctlFormula; 04619 array_t *formulaCombNodes; 04620 Fsm_Fsm_t *netFsm = Fsm_NetworkReadFsm( network ); 04621 Fsm_Fsm_t *reducedFsm; 04622 Fsm_Fairness_t *netFairness = Fsm_FsmReadFairnessConstraint( netFsm ); 04623 array_t *reducedFsmFairness = array_alloc( Ctlp_Formula_t *, 0 ); 04624 04625 if (netFairness) { 04626 if ( !Fsm_FairnessTestIsBuchi( netFairness ) ) { 04627 (void) fprintf(vis_stderr, "** mc error: non Buchi fairness constraints not supported\n"); 04628 (void) fprintf(vis_stderr, "** mc error: ignoring fairness constraints\n"); 04629 } 04630 else { 04631 int j; 04632 int numBuchi = Fsm_FairnessReadNumConjunctsOfDisjunct( netFairness, 0 ); 04633 for( j = 0 ; j < numBuchi; j++ ) { 04634 Ctlp_Formula_t *tmpFormula = Fsm_FairnessReadFinallyInfFormula( netFairness, 0, j ); 04635 Ctlp_Formula_t *reducedFsmCondition = Ctlp_FormulaDup( tmpFormula ); 04636 array_insert_last( Ctlp_Formula_t *, reducedFsmFairness, reducedFsmCondition ); 04637 } 04638 } 04639 } 04640 04641 formulaNodes = st_init_table( st_ptrcmp, st_ptrhash ); 04642 arrayForEachItem( Ctlp_Formula_t *, ctlFormulaArray, i, ctlFormula ) { 04643 NodeTableAddCtlFormulaNodes( network, ctlFormula, formulaNodes ); 04644 } 04645 04646 arrayForEachItem( Ctlp_Formula_t *, reducedFsmFairness, i, fairnessCondition ) { 04647 NodeTableAddCtlFormulaNodes( network, fairnessCondition, formulaNodes ); 04648 } 04649 04650 { 04651 st_generator *stGen; 04652 nodeArray = array_alloc( Ntk_Node_t *, 0 ); 04653 st_foreach_item( formulaNodes, stGen, &node, NIL(char *) ) { 04654 array_insert_last( Ntk_Node_t *, nodeArray, node ); 04655 } 04656 } 04657 st_free_table( formulaNodes ); 04658 04659 formulaCombNodes = Ntk_NodeComputeCombinationalSupport( network, nodeArray, FALSE ); 04660 array_free( nodeArray ); 04661 if(array_n(formulaCombNodes) == 0) { 04662 04663 /* Free the fairness constraint array (if any) */ 04664 for (i=0; i<array_n(reducedFsmFairness); i++){ 04665 Ctlp_Formula_t *formula = array_fetch(Ctlp_Formula_t*, 04666 reducedFsmFairness, i); 04667 Ctlp_FormulaFree(formula); 04668 } 04669 array_free(reducedFsmFairness); 04670 /* Free the formulaCombNodes */ 04671 array_free(formulaCombNodes); 04672 /* We should return a NIL fsm */ 04673 return NIL(Fsm_Fsm_t); 04674 } 04675 { 04676 graph_t *dupPart; 04677 graph_t *origPart = Part_NetworkReadPartition( network ); 04678 array_t *reducedFsmLatches = array_alloc( Ntk_Node_t *, 0 ); 04679 array_t *reducedFsmInputs = array_alloc( Ntk_Node_t *, 0 ); 04680 int i; 04681 arrayForEachItem( Ntk_Node_t *, formulaCombNodes, i, node ) { 04682 if ( Ntk_NodeTestIsInput( node ) == TRUE ) { 04683 array_insert_last( Ntk_Node_t *, reducedFsmInputs, node ); 04684 } 04685 else { 04686 assert( Ntk_NodeTestIsLatch( node ) == TRUE ); 04687 array_insert_last( Ntk_Node_t *, reducedFsmLatches, node ); 04688 } 04689 } 04690 if ((array_n(reducedFsmInputs) == 04691 Ntk_NetworkReadNumInputs(network)) && 04692 (array_n(reducedFsmLatches) == 04693 Ntk_NetworkReadNumLatches(network))){ 04694 /* We did not observe any reduction. Return a NIL fsm. */ 04695 /* After freeing appropriate stuff */ 04696 04697 /* Free the fairness constraint array (if any) */ 04698 for (i=0; i<array_n(reducedFsmFairness); i++){ 04699 Ctlp_Formula_t *formula = array_fetch(Ctlp_Formula_t*, 04700 reducedFsmFairness, i); 04701 Ctlp_FormulaFree(formula); 04702 } 04703 array_free(reducedFsmFairness); 04704 array_free(formulaCombNodes); 04705 array_free(reducedFsmLatches); 04706 array_free(reducedFsmInputs); 04707 return NIL(Fsm_Fsm_t); 04708 } 04709 dupPart = Part_PartitionDuplicate( origPart ); 04710 array_free( formulaCombNodes ); 04711 reducedFsm = Fsm_FsmCreateReducedFsm( network, dupPart, reducedFsmLatches, 04712 reducedFsmInputs, reducedFsmFairness ); 04713 array_free( reducedFsmLatches ); 04714 array_free( reducedFsmInputs ); 04715 array_free( reducedFsmFairness ); 04716 } 04717 04718 return reducedFsm; 04719 04720 } 04721 04755 Mc_EarlyTermination_t * 04756 McObtainUpdatedEarlyTerminationCondition( 04757 Mc_EarlyTermination_t *earlyTermination, 04758 mdd_t *careStates, 04759 Ctlp_FormulaType formulaType) 04760 { 04761 Mc_EarlyTermination_t *result; 04762 04763 switch (formulaType) { 04764 case Ctlp_NOT_c: 04765 if (earlyTermination == MC_NO_EARLY_TERMINATION) 04766 return MC_NO_EARLY_TERMINATION; 04767 result = Mc_EarlyTerminationAlloc(earlyTermination->mode, 04768 earlyTermination->states); 04769 switch (result->mode) { 04770 case McAll_c: 04771 result->mode = McSome_c; 04772 break; 04773 case McSome_c: 04774 result->mode = McAll_c; 04775 break; 04776 case McCare_c: 04777 break; 04778 default: 04779 assert(0); 04780 } 04781 break; 04782 case Ctlp_AND_c: 04783 if (careStates == NIL(mdd_t)) { 04784 if (earlyTermination == MC_NO_EARLY_TERMINATION) { 04785 result = MC_NO_EARLY_TERMINATION; 04786 } else if (earlyTermination->mode == McAll_c) { 04787 result = Mc_EarlyTerminationAlloc(McAll_c, earlyTermination->states); 04788 } else { 04789 /* Here mode is CARE or SOME: inherit care states from parent. */ 04790 result = Mc_EarlyTerminationAlloc(McCare_c, earlyTermination->states); 04791 } 04792 } else { 04793 /* There are care states from sibling. */ 04794 if (earlyTermination == MC_NO_EARLY_TERMINATION) { 04795 /* No early termination from parent: just use sibling's care states. */ 04796 result = Mc_EarlyTerminationAlloc(McCare_c, careStates); 04797 } else if (earlyTermination->mode == McAll_c) { 04798 /* If some goal states are not in care set, we know we cannot achieve 04799 * the goal; otherwise, we just propagate the parent's condition. 04800 */ 04801 if (mdd_lequal(earlyTermination->states, careStates, 1, 1)) { 04802 result = Mc_EarlyTerminationAlloc(McAll_c, earlyTermination->states); 04803 } else { 04804 result = Mc_EarlyTerminationAlloc(McCare_c, NIL(mdd_t)); /* failure */ 04805 } 04806 } else if (earlyTermination->mode == McSome_c) { 04807 /* If no goal states are in the care set, we have failed; otherwise 04808 * we refine the goal set to those states also in the care set. 04809 */ 04810 if (mdd_lequal(earlyTermination->states, careStates, 1, 0)) { 04811 result = Mc_EarlyTerminationAlloc(McCare_c, NIL(mdd_t)); /* failure */ 04812 } else { 04813 mdd_t *andMdd = mdd_and(earlyTermination->states, careStates, 1, 1); 04814 result = Mc_EarlyTerminationAlloc(McSome_c, andMdd); 04815 mdd_free(andMdd); 04816 } 04817 } else { /* if (earlyTermination->mode == McCare_c) */ 04818 /* Intersect care states from parent and sibling. */ 04819 mdd_t *andMdd = mdd_and(earlyTermination->states, careStates, 1, 1); 04820 result = Mc_EarlyTerminationAlloc(McCare_c, andMdd); 04821 mdd_free(andMdd); 04822 } 04823 } 04824 break; 04825 case Ctlp_THEN_c: 04826 case Ctlp_OR_c: 04827 if (careStates == NIL(mdd_t)) { 04828 if (earlyTermination == MC_NO_EARLY_TERMINATION) { 04829 result = MC_NO_EARLY_TERMINATION; 04830 } else if (earlyTermination->mode == McSome_c) { 04831 if (formulaType == Ctlp_OR_c) { 04832 result = Mc_EarlyTerminationAlloc(McSome_c, 04833 earlyTermination->states); 04834 } else { 04835 result = Mc_EarlyTerminationAlloc(McAll_c, 04836 earlyTermination->states); 04837 } 04838 } else { 04839 /* Here mode is CARE or ALL: inherit care states from parent. */ 04840 result = Mc_EarlyTerminationAlloc(McCare_c, earlyTermination->states); 04841 } 04842 } else { 04843 /* There are care states from sibling. 04844 * Since f->g is !f+g, we treat the THEN and OR cases together by 04845 * complementing the care set in the latter case. */ 04846 mdd_t *mask = (formulaType == Ctlp_OR_c) ? 04847 bdd_not(careStates) : bdd_dup(careStates); 04848 if (earlyTermination == MC_NO_EARLY_TERMINATION) { 04849 /* No early termination from parent: just use sibling's care states. */ 04850 result = Mc_EarlyTerminationAlloc(McCare_c, mask); 04851 } else if (earlyTermination->mode == McAll_c) { 04852 /* Remove the goal states already attained from the goal set. */ 04853 mdd_t *andMdd = mdd_and(earlyTermination->states, mask, 1, 1); 04854 result = Mc_EarlyTerminationAlloc(McAll_c, andMdd); 04855 mdd_free(andMdd); 04856 } else if (earlyTermination->mode == McSome_c) { 04857 /* If some goal states were already attained, declare success; 04858 * otherwise just propagate the parent's condition. 04859 */ 04860 if (mdd_lequal(earlyTermination->states, mask, 1, 1)) { 04861 result = Mc_EarlyTerminationAlloc(McSome_c, 04862 earlyTermination->states); 04863 } else { 04864 result = Mc_EarlyTerminationAlloc(McCare_c, NIL(mdd_t)); /* success */ 04865 } 04866 } else { /* if (earlyTermination->mode == McCare_c) */ 04867 /* Intersect care states from parent and sibling. */ 04868 mdd_t *andMdd = mdd_and(earlyTermination->states, mask, 1, 1); 04869 result = Mc_EarlyTerminationAlloc(McCare_c, andMdd); 04870 mdd_free(andMdd); 04871 } 04872 mdd_free(mask); 04873 } 04874 break; 04875 default: 04876 result = MC_NO_EARLY_TERMINATION; 04877 } 04878 return result; 04879 04880 } /* McObtainUpdatedEarlyTerminationCondition */ 04881 04882 04906 boolean 04907 McCheckEarlyTerminationForUnderapprox( 04908 Mc_EarlyTermination_t *earlyTermination, 04909 mdd_t *underApprox, 04910 array_t *careStatesArray) 04911 { 04912 if(earlyTermination == MC_NO_EARLY_TERMINATION) 04913 return FALSE; 04914 04915 /* for an underapproximation and McAll_c (McSome_c), you just check 04916 whether all states (some states) are already reached */ 04917 return(((earlyTermination->mode != McSome_c) && 04918 (mdd_lequal_mod_care_set_array(earlyTermination->states, underApprox, 04919 1, 1, careStatesArray))) 04920 || 04921 ( 04922 (earlyTermination->mode == McSome_c) && 04923 (!mdd_lequal_mod_care_set_array(underApprox, 04924 earlyTermination->states, 1, 04925 0, careStatesArray)))); 04926 } 04927 04928 04953 boolean 04954 McCheckEarlyTerminationForOverapprox( 04955 Mc_EarlyTermination_t *earlyTermination, 04956 mdd_t *overApprox, 04957 array_t *careStatesArray) 04958 { 04959 if(earlyTermination == MC_NO_EARLY_TERMINATION) 04960 return FALSE; 04961 04962 /* For an overapproximation and McAll_c (McSome_c), you check 04963 whether some state (all states) are already missing */ 04964 return(((earlyTermination->mode == McAll_c) && 04965 (!mdd_lequal_mod_care_set_array(earlyTermination->states, 04966 overApprox, 1, 1, careStatesArray))) 04967 || 04968 ((earlyTermination->mode != McAll_c) && 04969 (mdd_lequal_mod_care_set_array(earlyTermination->states, 04970 overApprox, 1, 0, 04971 careStatesArray)))); 04972 } 04973 04974 04988 array_t * 04989 Mc_ReadHints( 04990 FILE *guideFP 04991 ) 04992 { 04993 Ctlp_FormulaArray_t *invarArray; /* formulae representing hints */ 04994 int i; /* to iterate over formulae */ 04995 Ctlp_Formula_t *formula; /* idem */ 04996 04997 if (guideFP == NIL(FILE)){ 04998 fprintf(vis_stderr, 04999 "** mc error: can't read hint file.\n"); 05000 return NIL(array_t); 05001 } 05002 05003 invarArray = Ctlp_FileParseFormulaArray( guideFP ); 05004 05005 if (invarArray == NIL(array_t)){ 05006 fprintf(vis_stderr, 05007 "** mc error: parse error in hints file.\n"); 05008 return NIL(array_t); 05009 } 05010 05011 if (array_n(invarArray) == 0){ 05012 fprintf(vis_stdout, "** mc error: File contained no hints.\n"); 05013 Ctlp_FormulaArrayFree(invarArray); 05014 return NIL(array_t); 05015 } 05016 05017 05018 array_insert_last(Ctlp_Formula_t *, invarArray, 05019 Ctlp_FormulaCreate(Ctlp_TRUE_c, NIL(void), NIL(void))); 05020 05021 /* some checks */ 05022 arrayForEachItem(Ctlp_Formula_t *, invarArray, i, formula){ 05023 if(!Ctlp_FormulaTestIsQuantifierFree(formula)){ 05024 (void) fprintf(vis_stdout, 05025 "** mc error: Hints contain temporal operators\n"); 05026 05027 Ctlp_FormulaArrayFree(invarArray); 05028 return NIL(array_t); 05029 } /* quantifier free */ 05030 05031 }/* checks */ 05032 05033 05034 return invarArray; 05035 }/* Mc_ReadHints */ 05036 05048 st_table * 05049 Mc_ReadSystemVariablesFAFW( 05050 Fsm_Fsm_t *fsm, 05051 FILE *systemFP 05052 ) 05053 { 05054 st_table *variablesTable; 05055 array_t *bddIdArray; 05056 char line[1024], nodeName[1024], *next; 05057 int mddId, bddId; 05058 int i, j, len, index; 05059 int errorFlag; 05060 Ntk_Node_t *node; 05061 Ntk_Network_t *network; 05062 mdd_manager *mgr; 05063 05064 errorFlag = 0; 05065 if (systemFP == NIL(FILE)){ 05066 fprintf(vis_stderr, 05067 "** mc error: can't read system file.\n"); 05068 return NIL(st_table); 05069 } 05070 05071 network = Fsm_FsmReadNetwork(fsm); 05072 mgr = Fsm_FsmReadMddManager(fsm); 05073 variablesTable = st_init_table(st_numcmp, st_numhash); 05074 while(fgets(line, 1024, systemFP)) { 05075 len = strlen(line); 05076 for(i=0; i<len; i++) { 05077 if(line[i] == ' ') continue; 05078 if(line[i] == '\t') continue; 05079 break; 05080 } 05081 next = &(line[i]); 05082 if(next[0] == '\n') continue; 05083 if(next[0] == '#') continue; 05084 len = strlen(next); 05085 index = 0; 05086 nodeName[0] = '\0'; 05087 for(i=0; i<len; i++) { 05088 if(next[i] == ' ') break; 05089 if(next[i] == '\t') break; 05090 if(next[i] == '\n') break; 05091 nodeName[index] = next[i]; 05092 index++; 05093 } 05094 nodeName[index] = '\0'; 05095 node = Ntk_NetworkFindNodeByName(network, nodeName); 05096 if(node == NIL(Ntk_Node_t)) { 05097 fprintf(vis_stderr, "Error : Can't find node '%s'\n", nodeName); 05098 errorFlag = 1; 05099 continue; 05100 } 05101 mddId = Ntk_NodeReadMddId(node); 05102 bddIdArray = mdd_id_to_bdd_id_array(mgr, mddId); 05103 for(j=0; j<array_n(bddIdArray); j++) { 05104 bddId = array_fetch(int, bddIdArray, j); 05105 st_insert(variablesTable, (char *)(long)bddId, (char *)(long)bddId); 05106 } 05107 array_free(bddIdArray); 05108 } 05109 05110 if(variablesTable->num_entries == 0) { 05111 st_free_table(variablesTable); 05112 variablesTable = 0; 05113 } 05114 if(errorFlag) { 05115 if(variablesTable) 05116 st_free_table(variablesTable); 05117 variablesTable = 0; 05118 return((st_table *)-1); 05119 } 05120 return variablesTable; 05121 }/* Mc_ReadSystemVariablesFAFW */ 05122 05123 05133 st_table * 05134 Mc_SetAllInputToSystem(Fsm_Fsm_t *fsm) 05135 { 05136 mdd_manager *mgr; 05137 array_t *inputVars, *bddIdArray; 05138 int i, j; 05139 int mddId, bddId; 05140 st_table *idTable; 05141 05142 idTable = st_init_table(st_numcmp, st_numhash); 05143 mgr = Fsm_FsmReadMddManager(fsm); 05144 /* inputVars = Fsm_FsmReadPrimaryInputVars(fsm); */ 05145 inputVars = Fsm_FsmReadInputVars(fsm); 05146 05147 if(inputVars) { 05148 for(i=0; i<array_n(inputVars); i++) { 05149 mddId = array_fetch(int, inputVars, i); 05150 bddIdArray = mdd_id_to_bdd_id_array(mgr, mddId); 05151 for(j=0; j<array_n(bddIdArray); j++) { 05152 bddId = array_fetch(int, bddIdArray, j); 05153 st_insert(idTable, (char *)(long)bddId, (char *)(long)bddId); 05154 } 05155 } 05156 } 05157 return(idTable); 05158 05159 } 05160 05174 array_t * 05175 Mc_EvaluateHints( 05176 Fsm_Fsm_t *fsm, 05177 Ctlp_FormulaArray_t *invarArray 05178 ) 05179 { 05180 array_t *invarStatesArray = NIL(array_t);/* array of sets of states: hints*/ 05181 int i, j; /* to iterate over formulae */ 05182 Ctlp_Formula_t *formula= NIL(Ctlp_Formula_t);/* idem */ 05183 mdd_t *invarFormulaStates = NIL(mdd_t);/* states in which formula is true */ 05184 mdd_t *one = NIL(mdd_t); 05185 array_t *psVars = Fsm_FsmReadPresentStateVars(fsm); 05186 array_t *inputVars = Fsm_FsmReadInputVars(fsm); 05187 array_t *psInputVars = array_join(psVars, inputVars); 05188 mdd_manager *mddMgr = Fsm_FsmReadMddManager(fsm); 05189 05190 invarStatesArray = array_alloc(mdd_t *, 0); 05191 05192 one = mdd_one(Fsm_FsmReadMddManager(fsm)); 05193 05194 arrayForEachItem(Ctlp_Formula_t *, invarArray, i, formula){ 05195 /* semantic checks */ 05196 if(!Mc_FormulaStaticSemanticCheckOnNetwork(formula, 05197 Fsm_FsmReadNetwork(fsm), 05198 TRUE)){ 05199 (void) fprintf(vis_stdout, 05200 "** mc error: Error evaluating hint:\n%s\n", 05201 error_string()); 05202 05203 mdd_free(one); 05204 mdd_array_free(invarStatesArray); 05205 return NIL(array_t); 05206 }/* if semantic error */ 05207 05208 assert(Ctlp_FormulaTestIsQuantifierFree(formula)); 05209 05210 Ctlp_FlushStates(formula); 05211 05212 05213 /* compute the set of states represented by the invariant. */ 05214 invarFormulaStates = 05215 Mc_FsmEvaluateFormula(fsm, formula, one, 05216 NIL(Fsm_Fairness_t), NIL(array_t), 05217 MC_NO_EARLY_TERMINATION, 05218 NIL(Fsm_HintsArray_t), Mc_None_c, 05219 McVerbosityNone_c, McDcLevelNone_c, 0, 05220 McGSH_EL_c); 05221 05222 05223 if (!mdd_check_support(mddMgr, invarFormulaStates, psInputVars)) { 05224 mdd_t *temp; 05225 int mddId; 05226 array_t *supportArray = mdd_get_support(mddMgr, invarFormulaStates); 05227 array_t *leftOverVars = array_alloc(int, 0); 05228 /* store the PS and the Input Vars of this FSM */ 05229 st_table *supportTable = st_init_table(st_numcmp, st_numhash); 05230 05231 arrayForEachItem(int, psInputVars, j, mddId) { 05232 (void) st_insert(supportTable, (char *) (long) mddId, NIL(char)); 05233 } 05234 05235 /* isolate the vars outside this FSM */ 05236 arrayForEachItem(int, supportArray, j, mddId) { 05237 if (st_is_member(supportTable, (char *)(long)mddId) == 0) { 05238 array_insert_last(int, leftOverVars, mddId); 05239 } 05240 } 05241 05242 /* Quantify them out */ 05243 if (array_n(leftOverVars) > 0) { 05244 fprintf(vis_stdout, "GS warning ** Quantifying out variables not relevant to the reduced FSM in hint %d. \n", i+1); 05245 arrayForEachItem(int, leftOverVars, j, mddId) { 05246 fprintf(vis_stdout, "%s\n", (mdd_get_var_by_id(mddMgr, mddId)).name); 05247 } 05248 temp = mdd_smooth(mddMgr, invarFormulaStates, leftOverVars); 05249 mdd_free(invarFormulaStates); 05250 invarFormulaStates = temp; 05251 } 05252 array_free(leftOverVars); 05253 st_free_table(supportTable); 05254 array_free(supportArray); 05255 } 05256 05257 array_insert_last(mdd_t *, invarStatesArray, invarFormulaStates); 05258 }/* for each formula */ 05259 05260 array_free(psInputVars); 05261 mdd_free(one); 05262 return invarStatesArray; 05263 }/* Mc_EvaluateHints */ 05264 05279 array_t * 05280 Mc_ComputeGuideArray( 05281 Fsm_Fsm_t *fsm, 05282 FILE *guideFP 05283 ) 05284 { 05285 Ctlp_FormulaArray_t *hintFormulae; 05286 array_t * hintSets; 05287 05288 hintFormulae = Mc_ReadHints(guideFP); 05289 fclose(guideFP); 05290 05291 if( hintFormulae == NIL(Ctlp_FormulaArray_t)) 05292 return NIL(array_t); 05293 05294 hintSets = Mc_EvaluateHints(fsm, hintFormulae); 05295 05296 Ctlp_FormulaArrayFree(hintFormulae); 05297 05298 return hintSets; 05299 }/* Mc_ComputeGuideArray */ 05300 05301 05313 Mc_GuidedSearch_t Mc_ReadGuidedSearchType(void) 05314 { 05315 char *string = Cmd_FlagReadByName("guided_search_hint_type"); 05316 05317 if(string == NIL(char)) /* default */ 05318 return Mc_Local_c; 05319 if(!strcmp(string, "global")) 05320 return Mc_Global_c; 05321 if(!strcmp(string, "local")) 05322 return Mc_Local_c; 05323 else 05324 return Mc_None_c; 05325 } 05326 05327 05337 void 05338 Mc_CheckPathToCore(Fsm_Fsm_t *fsm, array_t *pathToCore) 05339 { 05340 array_t *inputVars; 05341 int i; 05342 mdd_t *fromState, *toState, *inputSet; 05343 mdd_manager *mgr = Ntk_NetworkReadMddManager(Fsm_FsmReadNetwork(fsm)); 05344 05345 inputVars = Fsm_FsmReadInputVars( fsm ); 05346 for(i=-1; i<array_n(pathToCore)-1; i++) { 05347 fromState = (i==-1) ? 0 : array_fetch(mdd_t *, pathToCore, i); 05348 toState = array_fetch(mdd_t *, pathToCore, i+1); 05349 if((long)fromState % 2) fromState = (mdd_t *)((long)fromState - 1); 05350 if((long)toState % 2) toState = (mdd_t *)((long)toState - 1); 05351 inputSet = ( i == -1) ? 0 : 05352 Mc_FsmComputeDrivingInputMinterms( fsm, fromState, toState ); 05353 05354 if(inputSet) 05355 Mc_ComputeAMinterm( inputSet, inputVars, mgr ); 05356 else if(i != -1) 05357 fprintf(vis_stderr, "Illegal path from %d to %d\n", i, i+1); 05358 } 05359 05360 } 05361 05371 void 05372 Mc_CheckPathFromCore(Fsm_Fsm_t *fsm, array_t *pathFromCore) 05373 { 05374 array_t *inputVars; 05375 int i; 05376 mdd_t *fromState, *toState, *inputSet; 05377 mdd_manager *mgr = Ntk_NetworkReadMddManager(Fsm_FsmReadNetwork(fsm)); 05378 05379 inputVars = Fsm_FsmReadInputVars( fsm ); 05380 for(i=array_n(pathFromCore); i>0; i--) { 05381 fromState = (i==array_n(pathFromCore)) ? 0 : array_fetch(mdd_t *, pathFromCore, i); 05382 toState = array_fetch(mdd_t *, pathFromCore, i-1); 05383 if((long)fromState % 2) fromState = (mdd_t *)((long)fromState - 1); 05384 if((long)toState % 2) toState = (mdd_t *)((long)toState - 1); 05385 inputSet = ( i == array_n(pathFromCore)) ? 0 : 05386 Mc_FsmComputeDrivingInputMinterms( fsm, fromState, toState ); 05387 05388 if(inputSet) 05389 Mc_ComputeAMinterm( inputSet, inputVars, mgr ); 05390 else if(i != array_n(pathFromCore)) 05391 fprintf(vis_stderr, "Illegal path from %d to %d\n", i, i+1); 05392 } 05393 } 05394 05404 void 05405 Mc_PrintStates( 05406 Fsm_Fsm_t *modelFsm, 05407 mdd_t *states) 05408 { 05409 array_t *PSVars = Fsm_FsmReadPresentStateVars( modelFsm ); 05410 Ntk_Network_t *aNetwork = Fsm_FsmReadNetwork( modelFsm ); 05411 mdd_manager *mddMgr = Fsm_FsmReadMddManager( modelFsm ); 05412 mdd_t *zeroMdd, *new_states; 05413 char *tmpString; 05414 double size; 05415 05416 /* 05417 * sometimes, this function will be constrained by number of minterm 05418 * in the given set of states. 05419 * num_minterm = mdd_num_of_mintern(states); 05420 * if(num_minterm > MAX_MINTERM) { 05421 * fprintf( stdout, "Too many minterms in given states\n" ); 05422 * return; 05423 * } 05424 */ 05425 if((long)states % 2) { 05426 states = (mdd_t *)((long)states - 1); 05427 } 05428 zeroMdd = mdd_zero( mddMgr ); 05429 states = mdd_dup(states); 05430 if(mdd_equal(states, zeroMdd)) { 05431 fprintf(stdout, "ZERO mdd\n"); 05432 mdd_free(zeroMdd); 05433 return; 05434 } 05435 size = mdd_count_onset(mddMgr, states, PSVars); 05436 if(size > 40.0) { 05437 fprintf(stdout, "Too many minterms in given states %.0f\n", size); 05438 return; 05439 } 05440 fprintf( stdout, " " ); 05441 while(1) { 05442 mdd_t *result = Mc_ComputeAMinterm( states, PSVars, mddMgr ); 05443 05444 new_states = mdd_and( states, result, 1, 0 ); 05445 mdd_free( states ); 05446 states = new_states; 05447 05448 tmpString = Mc_MintermToString( result, PSVars, aNetwork ); 05449 fprintf( stdout, "%s ", tmpString ); 05450 FREE(tmpString); 05451 mdd_free( result ); 05452 05453 if(mdd_equal(states, zeroMdd)) { 05454 mdd_free(zeroMdd); 05455 mdd_free(states); 05456 break; 05457 } 05458 } 05459 fprintf(stdout, "\n"); 05460 } 05461 05471 void 05472 Mc_PrintNumStates( 05473 Fsm_Fsm_t *modelFsm, 05474 mdd_t *states) 05475 { 05476 array_t *PSVars = Fsm_FsmReadPresentStateVars( modelFsm ); 05477 mdd_manager *mddMgr = Fsm_FsmReadMddManager( modelFsm ); 05478 mdd_t *zeroMdd; 05479 double size; 05480 05481 /* 05482 * sometimes, this function will be constrained by number of minterm 05483 * in the given set of states. 05484 * num_minterm = mdd_num_of_mintern(states); 05485 * if(num_minterm > MAX_MINTERM) { 05486 * fprintf( stdout, "Too many minterms in given states\n" ); 05487 * return; 05488 * } 05489 */ 05490 if((long)states % 2) { 05491 states = (mdd_t *)((long)states - 1); 05492 } 05493 zeroMdd = mdd_zero( mddMgr ); 05494 states = mdd_dup(states); 05495 if(mdd_equal(states, zeroMdd)) { 05496 fprintf(stdout, "ZERO mdd\n"); 05497 mdd_free(zeroMdd); 05498 mdd_free(states); 05499 return; 05500 } 05501 size = mdd_count_onset(mddMgr, states, PSVars); 05502 fprintf(stdout, "num states : %.0f\n", size); 05503 mdd_free(zeroMdd); 05504 mdd_free(states); 05505 } 05506 05516 void 05517 Mc_PrintRings( 05518 Fsm_Fsm_t *modelFsm, 05519 array_t *onionRings) 05520 { 05521 int j; 05522 mdd_t *innerRing; 05523 05524 if(array_n(onionRings) > 0) { 05525 for(j=0; j<array_n(onionRings); j++) { 05526 innerRing = array_fetch(mdd_t *, onionRings, j); 05527 fprintf(vis_stdout, "%d'th ring : ", j); 05528 if(innerRing) 05529 Mc_PrintStates(modelFsm, innerRing); 05530 else 05531 fprintf(vis_stdout, "\n"); 05532 } 05533 } 05534 } 05535 05545 void 05546 Mc_PrintNumRings( 05547 Fsm_Fsm_t *modelFsm, 05548 array_t *onionRings) 05549 { 05550 int j; 05551 mdd_t *innerRing; 05552 05553 if(array_n(onionRings) > 0) { 05554 for(j=0; j<array_n(onionRings); j++) { 05555 innerRing = array_fetch(mdd_t *, onionRings, j); 05556 fprintf(vis_stdout, "%d'th ring : ", j); 05557 if(innerRing) 05558 Mc_PrintNumStates(modelFsm, innerRing); 05559 else 05560 fprintf(vis_stdout, "\n"); 05561 } 05562 } 05563 } 05564 05565 05575 mdd_t * 05576 McComputeACloseMinterm( 05577 mdd_t *aSet, 05578 mdd_t *target, 05579 array_t *Support, 05580 mdd_manager *mddMgr) 05581 { 05582 if (bdd_get_package_name() == CUDD) { 05583 mdd_t *range; /* range of Support */ 05584 mdd_t *legalSet; /* aSet without the don't cares */ 05585 mdd_t *closeCube; 05586 int dist; 05587 array_t *bddSupport; /* Support in terms of bdd vars */ 05588 mdd_t *minterm; /* a random minterm */ 05589 05590 /* Check that support of set is contained in Support. */ 05591 assert(SetCheckSupport(aSet, Support, mddMgr)); 05592 assert(!mdd_is_tautology(aSet, 0)); 05593 range = mdd_range_mdd(mddMgr, Support); 05594 legalSet = bdd_and(aSet, range, 1, 1); 05595 mdd_free(range); 05596 closeCube = mdd_closest_cube(legalSet, target, &dist); 05597 bddSupport = mdd_id_array_to_bdd_array(mddMgr, Support); 05598 minterm = bdd_pick_one_minterm(closeCube, bddSupport); 05599 05600 assert(MintermCheckWellFormed(minterm, Support, mddMgr)); 05601 assert(mdd_count_onset(mddMgr, minterm, Support) == 1); 05602 assert(mdd_lequal(minterm,legalSet,1,1)); 05603 05604 mdd_array_free(bddSupport); 05605 mdd_free(legalSet); 05606 mdd_free(closeCube); 05607 05608 return minterm; 05609 } else { 05610 return Mc_ComputeAMinterm(aSet, Support, mddMgr); 05611 }/* if CUDD */ 05612 05613 } /* McComputeACloseMinterm */ 05614 05622 mdd_t * 05623 McComputeACloseState( 05624 mdd_t *states, 05625 mdd_t *target, 05626 Fsm_Fsm_t *modelFsm) 05627 { 05628 array_t *PSVars = Fsm_FsmReadPresentStateVars(modelFsm); 05629 mdd_manager *mddMgr = Ntk_NetworkReadMddManager( 05630 Fsm_FsmReadNetwork(modelFsm)); 05631 mdd_t *result; 05632 05633 if (mdd_is_tautology(target, 0)) { 05634 result = Mc_ComputeAMinterm(states, PSVars, mddMgr); 05635 } else { 05636 result = McComputeACloseMinterm(states, target, PSVars, mddMgr); 05637 } 05638 05639 return result; 05640 05641 } /* McComputeACloseState */ 05642 05643 05655 Mc_GSHScheduleType 05656 McStringConvertToScheduleType( 05657 char *string) 05658 { 05659 if (strcmp("off", string) == 0) { 05660 return McGSH_old_c; 05661 } else if (strcmp("EL", string) == 0) { 05662 return McGSH_EL_c; 05663 } else if (strcmp("EL1", string) == 0) { 05664 return McGSH_EL1_c; 05665 } else if (strcmp("EL2", string) == 0) { 05666 return McGSH_EL2_c; 05667 } else if (strcmp("random", string) == 0) { 05668 return McGSH_Random_c; 05669 } else if (strcmp("budget", string) == 0) { 05670 return McGSH_Budget_c; 05671 } else { 05672 return McGSH_Unassigned_c; 05673 } 05674 05675 } /* McStringConvertToScheduleType */ 05676 05677 05691 int 05692 McStringConvertToLockstepMode( 05693 char *string) 05694 { 05695 int n; 05696 05697 if (strcmp("off", string) == 0) { 05698 return MC_LOCKSTEP_OFF; 05699 } else if (strcmp("on", string) == 0) { 05700 return MC_LOCKSTEP_EARLY_TERMINATION; 05701 } else if (strcmp("all", string) == 0) { 05702 return MC_LOCKSTEP_ALL_SCCS; 05703 } else if (Cmd_StringCheckIsInteger(string, &n) == 2) { 05704 return n; 05705 } else { 05706 return MC_LOCKSTEP_UNASSIGNED; 05707 } 05708 05709 } /* McStringConvertToLockstepMode */ 05710 05711 05712 /*---------------------------------------------------------------------------*/ 05713 /* Definition of static functions */ 05714 /*---------------------------------------------------------------------------*/ 05715 05724 static void 05725 PrintNodes( 05726 array_t *mddIdArray, 05727 Ntk_Network_t *network ) 05728 { 05729 int i; 05730 int mddId; 05731 05732 arrayForEachItem(int , mddIdArray, i, mddId) { 05733 Ntk_Node_t *node = Ntk_NetworkFindNodeByMddId( network, mddId ); 05734 char *nodeName = Ntk_NodeReadName( node ); 05735 fprintf(vis_stdout, " %s ", nodeName ); 05736 } 05737 } 05738 05739 05748 static array_t * 05749 SortMddIds( 05750 array_t *mddIdArray, 05751 Ntk_Network_t *network ) 05752 { 05753 int i; 05754 int mddId; 05755 char *nodeName; 05756 st_table *nameToIndex = st_init_table( strcmp, st_strhash ); 05757 array_t *nodeNameArray = array_alloc( char *, 0 ); 05758 array_t *result = array_alloc( int, 0 ); 05759 05760 arrayForEachItem(int, mddIdArray, i, mddId) { 05761 Ntk_Node_t *node = Ntk_NetworkFindNodeByMddId( network, mddId ); 05762 nodeName = Ntk_NodeReadName( node ); 05763 st_insert( nameToIndex, nodeName, (char *) (long) i ); 05764 array_insert_last( char *, nodeNameArray, nodeName ); 05765 } 05766 array_sort( nodeNameArray, cmp); 05767 05768 arrayForEachItem(char *, nodeNameArray, i, nodeName ) { 05769 int index; 05770 st_lookup_int( nameToIndex, nodeName, & index ); 05771 mddId = array_fetch( int, mddIdArray, index ); 05772 array_insert_last( int, result, mddId ); 05773 } 05774 st_free_table( nameToIndex ); 05775 array_free( nodeNameArray ); 05776 05777 return result; 05778 } 05779 05789 static void 05790 PrintDeck( 05791 array_t *mddValues, 05792 array_t *mddIdArray, 05793 Ntk_Network_t *network ) 05794 { 05795 int i; 05796 int mddId; 05797 05798 arrayForEachItem(int, mddIdArray, i, mddId) { 05799 int value = array_fetch( int, mddValues, i ); 05800 Ntk_Node_t *node = Ntk_NetworkFindNodeByMddId( network, mddId ); 05801 Var_Variable_t *nodeVar = Ntk_NodeReadVariable( node ); 05802 if ( Var_VariableTestIsSymbolic( nodeVar ) ) { 05803 char *symbolicValue = Var_VariableReadSymbolicValueFromIndex( nodeVar, value ); 05804 fprintf( vis_stdout, "%s ", symbolicValue ); 05805 } 05806 else { 05807 fprintf( vis_stdout, "%d ", value ); 05808 } 05809 } 05810 } 05811 05819 static int 05820 cmp( 05821 const void * s1, 05822 const void * s2) 05823 { 05824 return(strcmp(*(char **)s1, *(char **)s2)); 05825 } 05826 05835 static boolean 05836 AtomicFormulaCheckSemantics( 05837 Ctlp_Formula_t *formula, 05838 Ntk_Network_t *network, 05839 boolean inputsAllowed) 05840 { 05841 05842 char *nodeNameString = Ctlp_FormulaReadVariableName( formula ); 05843 char *nodeValueString = Ctlp_FormulaReadValueName( formula ); 05844 Ntk_Node_t *node = Ntk_NetworkFindNodeByName( network, nodeNameString ); 05845 05846 Var_Variable_t *nodeVar; 05847 int nodeValue; 05848 05849 if ( !node ) { 05850 error_append("Could not find node corresponding to the name\n\t- "); 05851 error_append( nodeNameString ); 05852 error_append("\n(Wire for this name may have been removed by synthesis)"); 05853 return FALSE; 05854 } 05855 05856 nodeVar = Ntk_NodeReadVariable( node ); 05857 if ( Var_VariableTestIsSymbolic( nodeVar ) ){ 05858 05859 nodeValue = Var_VariableReadIndexFromSymbolicValue( nodeVar, nodeValueString ); 05860 if ( nodeValue == -1 ) { 05861 error_append("Value specified in RHS is not in domain of variable\n"); 05862 error_append( Ctlp_FormulaReadVariableName( formula ) ); 05863 error_append("="); 05864 error_append( Ctlp_FormulaReadValueName( formula ) ); 05865 return FALSE; 05866 } 05867 } 05868 else { 05869 int check; 05870 05871 check = Cmd_StringCheckIsInteger(nodeValueString, &nodeValue); 05872 if( check==0 ) { 05873 error_append("Value in the RHS is illegal\n"); 05874 error_append( Ctlp_FormulaReadVariableName( formula ) ); 05875 error_append("="); 05876 error_append( Ctlp_FormulaReadValueName( formula ) ); 05877 return FALSE; 05878 } 05879 if( check==1 ) { 05880 error_append("Value in the RHS is out of range of int\n"); 05881 error_append( Ctlp_FormulaReadVariableName( formula ) ); 05882 error_append("="); 05883 error_append( Ctlp_FormulaReadValueName( formula ) ); 05884 return FALSE; 05885 } 05886 if ( !(Var_VariableTestIsValueInRange( nodeVar, nodeValue ) ) ) { 05887 error_append("Value specified in RHS is not in domain of variable\n"); 05888 error_append( Ctlp_FormulaReadVariableName( formula ) ); 05889 error_append("="); 05890 error_append( Ctlp_FormulaReadValueName( formula ) ); 05891 return FALSE; 05892 } 05893 } 05894 05895 if(!inputsAllowed){ 05896 boolean coverSupport; 05897 lsGen tmpGen; 05898 Ntk_Node_t *tmpNode; 05899 st_table *supportNodes = st_init_table(st_ptrcmp, st_ptrhash); 05900 array_t *thisNodeArray = array_alloc( Ntk_Node_t *, 0); 05901 05902 array_insert_last( Ntk_Node_t *, thisNodeArray, node ); 05903 Ntk_NetworkForEachNode(network, tmpGen, tmpNode) { 05904 if (Ntk_NodeTestIsConstant(tmpNode) || Ntk_NodeTestIsLatch(tmpNode)) { 05905 st_insert(supportNodes, (char *) tmpNode, NIL(char)); 05906 } 05907 } 05908 05909 coverSupport = Ntk_NetworkTestLeavesCoverSupportOfRoots(network, 05910 thisNodeArray, 05911 supportNodes); 05912 array_free(thisNodeArray); 05913 st_free_table(supportNodes); 05914 05915 if ( coverSupport == FALSE ) { 05916 char *tmpString = 05917 util_strcat3( "\nNode ", nodeNameString, 05918 " is not driven only by latches and constants.\n"); 05919 error_append(tmpString); 05920 return FALSE; 05921 } 05922 } 05923 05924 return TRUE; 05925 } 05926 05934 static void 05935 NodeTableAddCtlFormulaNodes( 05936 Ntk_Network_t *network, 05937 Ctlp_Formula_t *formula, 05938 st_table * nodesTable ) 05939 { 05940 if ( formula == NIL(Ctlp_Formula_t) ) { 05941 return; 05942 } 05943 05944 if ( Ctlp_FormulaReadType( formula ) == Ctlp_ID_c ) { 05945 char *nodeNameString = Ctlp_FormulaReadVariableName( formula ); 05946 Ntk_Node_t *node = Ntk_NetworkFindNodeByName( network, nodeNameString ); 05947 if( node ) 05948 st_insert( nodesTable, ( char *) node, NIL(char) ); 05949 return; 05950 } 05951 05952 NodeTableAddCtlFormulaNodes( network, Ctlp_FormulaReadRightChild( formula ), nodesTable ); 05953 NodeTableAddCtlFormulaNodes( network, Ctlp_FormulaReadLeftChild( formula ), nodesTable ); 05954 05955 return; 05956 } 05957 05965 static void 05966 NodeTableAddLtlFormulaNodes( 05967 Ntk_Network_t *network, 05968 Ctlsp_Formula_t *formula, 05969 st_table * nodesTable ) 05970 { 05971 if ( formula == NIL(Ctlsp_Formula_t) ) { 05972 return; 05973 } 05974 05975 if ( Ctlsp_FormulaReadType( formula ) == Ctlsp_ID_c ) { 05976 char *nodeNameString = Ctlsp_FormulaReadVariableName( formula ); 05977 Ntk_Node_t *node = Ntk_NetworkFindNodeByName( network, nodeNameString ); 05978 if( node ) 05979 st_insert( nodesTable, ( char *) node, NIL(char) ); 05980 return; 05981 } 05982 05983 NodeTableAddLtlFormulaNodes( network, Ctlsp_FormulaReadRightChild( formula ), nodesTable ); 05984 NodeTableAddLtlFormulaNodes( network, Ctlsp_FormulaReadLeftChild( formula ), nodesTable ); 05985 05986 return; 05987 } 05988 05996 static boolean 05997 MintermCheckWellFormed( 05998 mdd_t *aMinterm, 05999 array_t *aSupport, 06000 mdd_manager *mddMgr) 06001 { 06002 06003 /* first check its support */ 06004 if (!SetCheckSupport(aMinterm, aSupport, mddMgr)) { 06005 return FALSE; 06006 } 06007 06008 /* now check its a minterm */ 06009 { 06010 float cardinality = mdd_count_onset( mddMgr, aMinterm, aSupport ); 06011 if ( cardinality != 1 ) { 06012 fprintf( vis_stderr, "-- onset is not one\n"); 06013 return FALSE; 06014 } 06015 } 06016 return TRUE; 06017 } 06018 06019 06027 static boolean 06028 SetCheckSupport( 06029 mdd_t *aMinterm, 06030 array_t *aSupport, 06031 mdd_manager *mddMgr) 06032 { 06033 if (!mdd_check_support(mddMgr, aMinterm, aSupport)) { 06034 fprintf(vis_stderr, 06035 "** mc error: support of minterm is not contained in claimed support\n"); 06036 return FALSE; 06037 } 06038 return TRUE; 06039 }