VIS

src/mc/mcUtil.c

Go to the documentation of this file.
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 }