VIS

src/fsm/fsmFsm.c

Go to the documentation of this file.
00001 
00032 #include "fsmInt.h"
00033 
00034 static char rcsid[] UNUSED = "$Id: fsmFsm.c,v 1.88 2007/04/02 17:03:13 hhkim Exp $";
00035 
00038 /*---------------------------------------------------------------------------*/
00039 /* Static function prototypes                                                */
00040 /*---------------------------------------------------------------------------*/
00041 
00042 static Fsm_Fsm_t * FsmStructAlloc(Ntk_Network_t *network, graph_t *partition);
00043 static void FsmCreateVariableCubes(Fsm_Fsm_t *fsm);
00044 static int nameCompare(const void * name1, const void * name2);
00045 static boolean VarIdArrayCompare(mdd_manager *mddMgr, array_t *vars1, array_t *vars2);
00046 static boolean NSFunctionNamesCompare(mdd_manager *mddMgr, array_t *names1, array_t *names2);
00047 static array_t * GetMddSupportIdArray(Fsm_Fsm_t *fsm, st_table *mddIdTable, st_table *pseudoMddIdTable);
00048 
00052 /*---------------------------------------------------------------------------*/
00053 /* Definition of exported functions                                          */
00054 /*---------------------------------------------------------------------------*/
00055 
00084 Fsm_Fsm_t *
00085 Fsm_FsmCreateFromNetworkWithPartition(
00086   Ntk_Network_t *network,
00087   graph_t       *partition)
00088 {
00089   lsGen       gen;
00090   Ntk_Node_t *latch;
00091   Ntk_Node_t *input;
00092   Fsm_Fsm_t  *fsm;
00093   int i;
00094   
00095   fsm = FsmStructAlloc(network, partition);
00096   if (fsm == NIL(Fsm_Fsm_t)) return NIL(Fsm_Fsm_t);
00097   fsm->fairnessInfo.constraint = FsmFsmCreateDefaultFairnessConstraint(fsm);
00098   
00099   /* sort by name of latch */
00100   Ntk_NetworkForEachLatch(network, gen, latch){
00101     array_insert_last(char*, fsm->fsmData.nextStateFunctions,
00102                       Ntk_NodeReadName(latch));
00103   }
00104 
00105   array_sort(fsm->fsmData.nextStateFunctions, nameCompare);
00106 
00107   for (i = 0; i < array_n(fsm->fsmData.nextStateFunctions); i ++) {
00108     char *nodeName;
00109     nodeName = array_fetch(char *, fsm->fsmData.nextStateFunctions, i);
00110     latch = Ntk_NetworkFindNodeByName(network, nodeName);
00111     array_insert(char*, fsm->fsmData.nextStateFunctions, i,
00112                  Ntk_NodeReadName(Ntk_LatchReadDataInput(latch)));
00113     array_insert_last(int, fsm->fsmData.presentStateVars,
00114                       Ntk_NodeReadMddId(latch));
00115     array_insert_last(int, fsm->fsmData.nextStateVars,
00116                       Ntk_NodeReadMddId(Ntk_NodeReadShadow(latch)));
00117   }
00118   
00119   Ntk_NetworkForEachInput(network, gen, input){
00120     array_insert_last(int, fsm->fsmData.inputVars, Ntk_NodeReadMddId(input));
00121   }
00122   
00123   FsmCreateVariableCubes(fsm);
00124   return (fsm);
00125 }
00126 
00127 
00128 
00149 Fsm_Fsm_t *
00150 Fsm_FsmCreateReducedFsm(
00151   Ntk_Network_t *network,
00152   graph_t       *partition,
00153   array_t       *latches,
00154   array_t       *inputs,
00155   array_t       *fairArray)
00156 {
00157   Ntk_Node_t *latch;
00158   Ntk_Node_t *input;
00159   Fsm_Fsm_t  *fsm;
00160   Fsm_Fairness_t *fairness;
00161   int i,j;
00162   
00163   if (array_n(latches) == 0){
00164     error_append("Number of latches passed = 0. Cannot create sub-FSM.");
00165     return (NIL(Fsm_Fsm_t));
00166   }
00167   
00168   fsm = FsmStructAlloc(network, partition);
00169   if (fsm == NIL(Fsm_Fsm_t)) return NIL(Fsm_Fsm_t);
00170 
00171   /* initialize fairness constraints */
00172   if (fairArray != NIL(array_t)){
00173     fairness = FsmFairnessAlloc(fsm);    
00174     for (j = 0; j < array_n(fairArray); j++) {
00175       Ctlp_Formula_t *formula = array_fetch(Ctlp_Formula_t *, fairArray, j);
00176       
00177       FsmFairnessAddConjunct(fairness, formula, NIL(Ctlp_Formula_t), 0, j);
00178     }
00179     fsm->fairnessInfo.constraint = fairness;
00180   }
00181   else {
00182     fsm->fairnessInfo.constraint =
00183         FsmFsmCreateDefaultFairnessConstraint(fsm);
00184   }
00185 
00186   /* sort latches by name */
00187   for(i=0; i<array_n(latches); i++){
00188     latch = array_fetch(Ntk_Node_t*, latches, i);
00189     array_insert_last(char*, fsm->fsmData.nextStateFunctions,
00190                       Ntk_NodeReadName(latch));
00191   }
00192   array_sort(fsm->fsmData.nextStateFunctions, nameCompare);
00193 
00194   for(i=0; i<array_n(latches); i++){
00195     char *nodeName;
00196     nodeName = array_fetch(char *, fsm->fsmData.nextStateFunctions, i);
00197     latch = Ntk_NetworkFindNodeByName(network, nodeName);  
00198     array_insert_last(int, fsm->fsmData.presentStateVars,
00199                       Ntk_NodeReadMddId(latch));
00200     array_insert_last(int, fsm->fsmData.nextStateVars,
00201                       Ntk_NodeReadMddId(Ntk_NodeReadShadow(latch)));
00202     array_insert(char*, fsm->fsmData.nextStateFunctions, i, 
00203                       Ntk_NodeReadName(Ntk_LatchReadDataInput(latch)));
00204   }
00205   
00206   for(i=0; i<array_n(inputs); i++){
00207     input = array_fetch(Ntk_Node_t*, inputs, i);
00208     array_insert_last(int, fsm->fsmData.inputVars, Ntk_NodeReadMddId(input));
00209   }
00210 
00211   FsmCreateVariableCubes(fsm);
00212   return (fsm);
00213 }
00214 
00255 Fsm_Fsm_t *
00256 Fsm_FsmCreateAbstractFsm(
00257   Ntk_Network_t *network,
00258   graph_t       *partition,
00259   array_t       *latches,
00260   array_t       *invisibleVars,
00261   array_t       *inputs,
00262   array_t       *fairArray,
00263   boolean        independentFlag)
00264 {
00265   Ntk_Node_t *latch;
00266   Ntk_Node_t *input;
00267   Ntk_Node_t *node;
00268   Fsm_Fsm_t  *fsm;
00269   Fsm_Fairness_t *fairness;
00270   int i,j;
00271   
00272   if (FALSE && array_n(latches) == 0){
00273     error_append("Number of latches passed = 0. Cannot create sub-FSM.");
00274     return (NIL(Fsm_Fsm_t));
00275   }
00276   
00277   fsm = FsmStructAlloc(network, partition);
00278   if (fsm == NIL(Fsm_Fsm_t)) return NIL(Fsm_Fsm_t);
00279 
00280   /* initialize fairness constraints */
00281   if (fairArray != NIL(array_t)){
00282     fairness = FsmFairnessAlloc(fsm);    
00283     for (j = 0; j < array_n(fairArray); j++) {
00284       Ctlp_Formula_t *formula = array_fetch(Ctlp_Formula_t *, fairArray, j);
00285       
00286       FsmFairnessAddConjunct(fairness, formula, NIL(Ctlp_Formula_t), 0, j);
00287     }
00288     fsm->fairnessInfo.constraint = fairness;
00289   }
00290   else {
00291     fsm->fairnessInfo.constraint =
00292         FsmFsmCreateDefaultFairnessConstraint(fsm);
00293   }
00294 
00295   /* when independentFlag==FALSE, use globalPsVars and
00296    * primaryInputVars (instead of presentStateVars and inputVars) to
00297    * build the transition relation
00298    */
00299   if (!independentFlag) {
00300     fsm->fsmData.globalPsVars = array_alloc(int, 0);
00301     fsm->fsmData.primaryInputVars = array_alloc(int, 0);
00302   }
00303 
00304 
00305   /* sort latches by name */
00306   for(i=0; i<array_n(latches); i++){
00307     latch = array_fetch(Ntk_Node_t*, latches, i);
00308     array_insert_last(char*, fsm->fsmData.nextStateFunctions,
00309                       Ntk_NodeReadName(latch));
00310   }
00311   array_sort(fsm->fsmData.nextStateFunctions, nameCompare);
00312 
00313   for(i=0; i<array_n(latches); i++){
00314     char *nodeName;
00315     nodeName = array_fetch(char *, fsm->fsmData.nextStateFunctions, i);
00316     latch = Ntk_NetworkFindNodeByName(network, nodeName);  
00317     array_insert_last(int, fsm->fsmData.presentStateVars,
00318                       Ntk_NodeReadMddId(latch));
00319     array_insert_last(int, fsm->fsmData.nextStateVars,
00320                       Ntk_NodeReadMddId(Ntk_NodeReadShadow(latch)));
00321     array_insert(char*, fsm->fsmData.nextStateFunctions, i, 
00322                       Ntk_NodeReadName(Ntk_LatchReadDataInput(latch)));
00323     
00324     if (!independentFlag)
00325       array_insert_last(int, fsm->fsmData.globalPsVars,
00326                         Ntk_NodeReadMddId(latch));      
00327   }
00328 
00329   for(i=0; i<array_n(inputs); i++){
00330     input = array_fetch(Ntk_Node_t*, inputs, i);
00331     array_insert_last(int, fsm->fsmData.inputVars, Ntk_NodeReadMddId(input));
00332     
00333     if (!independentFlag)
00334       array_insert_last(int, fsm->fsmData.primaryInputVars, 
00335                         Ntk_NodeReadMddId(input));
00336   }
00337 
00338 
00339   arrayForEachItem(Ntk_Node_t *, invisibleVars, i, node) {
00340     array_insert_last(int, fsm->fsmData.inputVars, Ntk_NodeReadMddId(node));
00341 
00342     if (!independentFlag) {
00343       array_insert_last(int, fsm->fsmData.globalPsVars, 
00344                         Ntk_NodeReadMddId(node));
00345     }
00346   }
00347 
00348 
00349   FsmCreateVariableCubes(fsm);
00350   return (fsm);
00351 }
00352 
00353 
00367 void
00368 Fsm_FsmFree(
00369   Fsm_Fsm_t * fsm)
00370 {
00371   Part_PartitionFree(fsm->partition);
00372   Fsm_FsmSubsystemFree(fsm);
00373 }
00374 
00386 void
00387 Fsm_FsmSubsystemFree(
00388   Fsm_Fsm_t * fsm)
00389 {
00390 
00391   Fsm_FsmFreeImageInfo(fsm);
00392   
00393   /* Free reachability info. */
00394   if (fsm->reachabilityInfo.initialStates != NIL(mdd_t)){
00395     mdd_free(fsm->reachabilityInfo.initialStates);
00396   }
00397   if (fsm->reachabilityInfo.reachableStates != NIL(mdd_t)){
00398     mdd_free(fsm->reachabilityInfo.reachableStates);
00399   }
00400   if (fsm->reachabilityInfo.apprReachableStates != NIL(array_t))
00401     mdd_array_free(fsm->reachabilityInfo.apprReachableStates);
00402   if (fsm->reachabilityInfo.subPsVars != NIL(array_t)){
00403     int i;
00404     array_t *psVars;
00405     arrayForEachItem(array_t *, fsm->reachabilityInfo.subPsVars, i, psVars) {
00406       array_free(psVars);
00407     }
00408     array_free(fsm->reachabilityInfo.subPsVars);
00409   }
00410   if (Fsm_FsmReadReachabilityOnionRings(fsm) != NIL(array_t)){
00411     mdd_array_free(Fsm_FsmReadReachabilityOnionRings(fsm));
00412   }
00413 
00414   /* Free fairness info. */
00415   FsmFsmFairnessInfoUpdate(fsm, NIL(mdd_t), NIL(Fsm_Fairness_t), NIL(array_t));
00416 
00417   array_free(fsm->fsmData.presentStateVars);
00418   array_free(fsm->fsmData.nextStateVars);
00419   array_free(fsm->fsmData.inputVars);
00420   array_free(fsm->fsmData.nextStateFunctions);
00421   if (fsm->fsmData.pseudoInputVars)
00422     array_free(fsm->fsmData.pseudoInputVars);
00423   if (fsm->fsmData.primaryInputVars)
00424     array_free(fsm->fsmData.primaryInputVars);
00425   if (fsm->fsmData.globalPsVars)
00426     array_free(fsm->fsmData.globalPsVars);
00427 
00428   if (fsm->fsmData.presentStateCube)
00429     mdd_free(fsm->fsmData.presentStateCube);
00430   if (fsm->fsmData.nextStateCube)
00431     mdd_free(fsm->fsmData.nextStateCube);
00432   if (fsm->fsmData.inputCube)
00433     mdd_free(fsm->fsmData.inputCube);
00434   if (fsm->fsmData.pseudoInputCube)
00435     mdd_free(fsm->fsmData.pseudoInputCube);
00436   if (fsm->fsmData.primaryInputCube)
00437     mdd_free(fsm->fsmData.primaryInputCube);
00438   if (fsm->fsmData.globalPsCube)
00439     mdd_free(fsm->fsmData.globalPsCube);
00440 
00441   if (fsm->fsmData.pseudoInputBddVars)
00442     mdd_array_free(fsm->fsmData.pseudoInputBddVars);
00443   if (fsm->fsmData.presentStateBddVars)
00444     mdd_array_free(fsm->fsmData.presentStateBddVars);
00445 
00446   FREE(fsm);
00447 }
00448 
00462 void
00463 Fsm_FsmFreeCallback(
00464   void * data /* an object of type Fsm_Fsm_t*  type casted to void* */)
00465 {
00466   Fsm_FsmFree((Fsm_Fsm_t *) data);
00467 }
00468 
00469 
00479 Ntk_Network_t *
00480 Fsm_FsmReadNetwork(
00481   Fsm_Fsm_t * fsm)
00482 {
00483   return (fsm->network);
00484 }
00485 
00497 boolean
00498 Fsm_FsmReadUseUnquantifiedFlag(
00499   Fsm_Fsm_t * fsm)
00500 {
00501   return (fsm->useUnquantifiedFlag);
00502 }
00503 
00513 mdd_manager *
00514 Fsm_FsmReadMddManager(
00515   Fsm_Fsm_t * fsm)
00516 {
00517   return (Ntk_NetworkReadMddManager(fsm->network));
00518 }
00519 
00520 
00537 Fsm_Fsm_t *
00538 Fsm_NetworkReadOrCreateFsm(
00539   Ntk_Network_t * network)
00540 {
00541   Fsm_Fsm_t *fsm = (Fsm_Fsm_t*) Ntk_NetworkReadApplInfo(network, FSM_NETWORK_APPL_KEY);
00542       
00543   if (fsm == NIL(Fsm_Fsm_t)) {
00544     fsm = Fsm_FsmCreateFromNetworkWithPartition(network, NIL(graph_t));
00545     if (fsm != NIL(Fsm_Fsm_t)) {
00546       (void) Ntk_NetworkAddApplInfo(network, FSM_NETWORK_APPL_KEY,
00547                              (Ntk_ApplInfoFreeFn) Fsm_FsmFreeCallback,
00548                              (void *) fsm);
00549     }
00550   }
00551   
00552   return fsm;
00553 }
00554 
00555 
00568 Fsm_Fsm_t *
00569 Fsm_NetworkReadFsm(
00570   Ntk_Network_t * network)
00571 {
00572   return ((Fsm_Fsm_t*) Ntk_NetworkReadApplInfo(network,
00573                                                FSM_NETWORK_APPL_KEY));
00574 }
00575 
00576 
00589 Img_ImageInfo_t *
00590 Fsm_FsmReadImageInfo(
00591   Fsm_Fsm_t *fsm)
00592 {
00593   return (fsm->imageInfo);
00594 }
00595 
00607 void
00608 Fsm_FsmSetImageInfo(
00609   Fsm_Fsm_t *fsm, Img_ImageInfo_t *imageInfo)
00610 {
00611   fsm->imageInfo = imageInfo;
00612 }
00613 
00626 void
00627 Fsm_FsmFreeImageInfo(
00628   Fsm_Fsm_t *fsm)
00629 {
00630   if(fsm->imageInfo) {
00631     Img_ImageInfoFree(fsm->imageInfo);
00632     fsm->imageInfo = NIL(Img_ImageInfo_t);
00633   }
00634 
00635   if(fsm->unquantifiedImageInfo) {
00636     Img_ImageInfoFree(fsm->unquantifiedImageInfo);
00637     fsm->unquantifiedImageInfo = NIL(Img_ImageInfo_t);
00638   }
00639 }
00640 
00653 graph_t *
00654 Fsm_FsmReadPartition(
00655   Fsm_Fsm_t *fsm)
00656 {
00657   return (fsm->partition);
00658 }
00659 
00671 boolean
00672 Fsm_FsmTestIsReachabilityDone(
00673   Fsm_Fsm_t *fsm)
00674 {
00675   
00676   if (Fsm_FsmReadReachableStates(fsm) != NIL(mdd_t)) {
00677         return TRUE;
00678   }
00679   return FALSE;
00680 }
00681 
00694 boolean
00695 Fsm_FsmTestIsOverApproximateReachabilityDone(
00696   Fsm_Fsm_t *fsm)
00697 {
00698   
00699   if (Fsm_FsmReadOverApproximateReachableStates(fsm) != NIL(array_t)) {
00700         return TRUE;
00701   }
00702   return FALSE;
00703 }
00704 
00705 
00715 mdd_t *
00716 Fsm_FsmReadReachableStates(
00717   Fsm_Fsm_t *fsm)
00718 {
00719   if (fsm->reachabilityInfo.rchStatus == Fsm_Rch_Exact_c)
00720     return(fsm->reachabilityInfo.reachableStates);
00721   else
00722     return(NIL(mdd_t));
00723 }
00724 
00725 
00736 mdd_t *
00737 Fsm_FsmReadCurrentReachableStates(
00738   Fsm_Fsm_t *fsm)
00739 {
00740   return(fsm->reachabilityInfo.reachableStates);
00741 }
00742 
00743 
00753 array_t *
00754 Fsm_FsmReadOverApproximateReachableStates(
00755   Fsm_Fsm_t *fsm)
00756 {
00757   if (fsm->reachabilityInfo.overApprox >= 2)
00758     return(fsm->reachabilityInfo.apprReachableStates);
00759   else
00760     return(NIL(array_t));
00761 }
00762 
00763 
00773 array_t *
00774 Fsm_FsmReadCurrentOverApproximateReachableStates(
00775   Fsm_Fsm_t *fsm)
00776 {
00777   return(fsm->reachabilityInfo.apprReachableStates);
00778 }
00779 
00793 array_t *
00794 Fsm_FsmReadReachabilityOnionRings(
00795   Fsm_Fsm_t *fsm)
00796 {
00797   return fsm->reachabilityInfo.onionRings;
00798 }
00799 
00814 boolean
00815 Fsm_FsmReachabilityOnionRingsStates(
00816   Fsm_Fsm_t *fsm,
00817   mdd_t ** result)
00818 {
00819   int i;
00820   mdd_t *tmpMdd;
00821   mdd_t *ring;
00822   array_t *onionRings;
00823 
00824   onionRings = Fsm_FsmReadReachabilityOnionRings(fsm);
00825   if ( onionRings == NIL(array_t) ) {
00826     *result = NIL(mdd_t);
00827     return 0;
00828   }
00829 
00830   *result = bdd_zero(Fsm_FsmReadMddManager(fsm));
00831   arrayForEachItem(mdd_t *, onionRings, i, ring) {
00832     tmpMdd = mdd_or(*result, ring, 1, 1);
00833     mdd_free(*result);
00834     *result = tmpMdd;
00835   }
00836   if (Fsm_FsmReadCurrentReachableStates(fsm)) {
00837     if (mdd_lequal(Fsm_FsmReadCurrentReachableStates(fsm), *result, 1,1)) {
00838       FsmSetReachabilityOnionRingsUpToDateFlag(fsm, TRUE);
00839     }
00840   }
00841   return (Fsm_FsmTestReachabilityOnionRingsUpToDate(fsm));
00842 }
00843 
00857 boolean
00858 Fsm_FsmTestReachabilityOnionRingsUpToDate(
00859   Fsm_Fsm_t *fsm)
00860 {
00861   return fsm->reachabilityInfo.onionRingsUpToDate;
00862 }
00863 
00875 Fsm_RchType_t
00876 Fsm_FsmReadReachabilityOnionRingsMode(
00877   Fsm_Fsm_t *fsm)
00878 {
00879   return fsm->reachabilityInfo.onionRingsMode;
00880 }
00881 
00882   
00900 Img_ImageInfo_t *
00901 Fsm_FsmReadOrCreateImageInfo(Fsm_Fsm_t *fsm, int bwdImgFlag, int fwdImgFlag)
00902 {
00903   Img_DirectionType     imgFlag = Img_Forward_c;
00904   array_t               *presentStateVars, *inputVars;
00905   mdd_t                 *presentStateCube, *inputCube;
00906 
00907   if (bwdImgFlag && fwdImgFlag)
00908     imgFlag = Img_Both_c;
00909   else if (bwdImgFlag)
00910     imgFlag = Img_Backward_c;
00911 
00912   if (fsm->fsmData.globalPsVars) {
00913     presentStateVars = fsm->fsmData.globalPsVars;
00914     inputVars = fsm->fsmData.primaryInputVars;
00915     presentStateCube = fsm->fsmData.globalPsCube;
00916     inputCube = fsm->fsmData.primaryInputCube;
00917   } else {
00918     presentStateVars = fsm->fsmData.presentStateVars;
00919     inputVars = fsm->fsmData.inputVars;
00920     presentStateCube = fsm->fsmData.presentStateCube;
00921     inputCube = fsm->fsmData.inputCube;
00922   }
00923 
00924   fsm->imageInfo = Img_ImageInfoInitialize(fsm->imageInfo,
00925                                            fsm->partition,
00926                                            fsm->fsmData.nextStateFunctions,
00927                                            presentStateVars,
00928                                            fsm->fsmData.nextStateVars,
00929                                            inputVars,
00930                                            presentStateCube,
00931                                            fsm->fsmData.nextStateCube,
00932                                            inputCube,
00933                                            fsm->network,
00934                                            Img_Default_c, imgFlag, 0, 0);
00935 
00936   if (fsm->fsmData.globalPsVars) {
00937     Img_ImageInfoUpdateVariables(fsm->imageInfo,
00938                                  fsm->partition,
00939                                  fsm->fsmData.presentStateVars,
00940                                  fsm->fsmData.inputVars,
00941                                  fsm->fsmData.presentStateCube,
00942                                  fsm->fsmData.inputCube);
00943   }
00944 
00945   return(fsm->imageInfo);
00946 }
00947 
00966 Img_ImageInfo_t *
00967 Fsm_FsmReadOrCreateImageInfoFAFW(Fsm_Fsm_t *fsm, int bwdImgFlag, int fwdImgFlag)
00968 {
00969   Img_DirectionType     imgFlag = Img_Forward_c;
00970   array_t               *presentStateVars, *inputVars;
00971   mdd_t                 *presentStateCube, *inputCube;
00972   mdd_manager           *mgr;
00973 
00974   mgr = Fsm_FsmReadMddManager(fsm);
00975 
00976   if (bwdImgFlag && fwdImgFlag)
00977     imgFlag = Img_Both_c;
00978   else if (bwdImgFlag)
00979     imgFlag = Img_Backward_c;
00980 
00981   presentStateVars = fsm->fsmData.presentStateVars;
00982   inputVars = array_alloc(int , 0);
00983   presentStateCube = fsm->fsmData.presentStateCube;
00984   inputCube = mdd_one(mgr);
00985 
00986   fsm->unquantifiedImageInfo = Img_ImageInfoInitialize(
00987                                            fsm->unquantifiedImageInfo,
00988                                            fsm->partition,
00989                                            fsm->fsmData.nextStateFunctions,
00990                                            presentStateVars,
00991                                            fsm->fsmData.nextStateVars,
00992                                            inputVars,
00993                                            presentStateCube,
00994                                            fsm->fsmData.nextStateCube,
00995                                            inputCube,
00996                                            fsm->network,
00997                                            Img_Default_c, imgFlag, 1, 0);
00998 
00999   if(!Img_IsQuantifyArraySame(fsm->unquantifiedImageInfo, inputVars)) {
01000     array_free(inputVars);
01001   }
01002 
01003   if(!Img_IsQuantifyCubeSame(fsm->unquantifiedImageInfo, inputCube)) {
01004     mdd_free(inputCube);
01005   }
01006 
01007   return(fsm->unquantifiedImageInfo);
01008 }
01009 
01028 Img_ImageInfo_t *
01029 Fsm_FsmReadOrCreateImageInfoPrunedFAFW(Fsm_Fsm_t *fsm, mdd_t *Winning, int bwdImgFlag, int fwdImgFlag)
01030 {
01031   Img_DirectionType     imgFlag = Img_Forward_c;
01032   array_t               *presentStateVars, *inputVars;
01033   mdd_t                 *presentStateCube, *inputCube;
01034   mdd_manager           *mgr;
01035   Img_ImageInfo_t *imageInfo;
01036 
01037   mgr = Fsm_FsmReadMddManager(fsm);
01038 
01039   if (bwdImgFlag && fwdImgFlag)
01040     imgFlag = Img_Both_c;
01041   else if (bwdImgFlag)
01042     imgFlag = Img_Backward_c;
01043 
01044   presentStateVars = fsm->fsmData.presentStateVars;
01045   inputVars = array_alloc(int , 0);
01046   presentStateCube = fsm->fsmData.presentStateCube;
01047   inputCube = mdd_one(mgr);
01048 
01049   imageInfo = Img_ImageInfoInitialize(
01050                                            0,
01051                                            fsm->partition,
01052                                            fsm->fsmData.nextStateFunctions,
01053                                            presentStateVars,
01054                                            fsm->fsmData.nextStateVars,
01055                                            inputVars,
01056                                            presentStateCube,
01057                                            fsm->fsmData.nextStateCube,
01058                                            inputCube,
01059                                            fsm->network,
01060                                            Img_Default_c, imgFlag, 0, Winning);
01061 
01062   if(!Img_IsQuantifyArraySame(imageInfo, inputVars)) {
01063     array_free(inputVars);
01064   }
01065 
01066   if(!Img_IsQuantifyCubeSame(imageInfo, inputCube)) {
01067     mdd_free(inputCube);
01068   }
01069 
01070   return(imageInfo);
01071 }
01072 
01073 
01092 Img_ImageInfo_t *
01093 Fsm_FsmReadOrCreateImageInfoForComputingRange(Fsm_Fsm_t *fsm, int bwdImgFlag, int fwdImgFlag)
01094 {
01095   Img_DirectionType     imgFlag = Img_Forward_c;
01096   array_t               *presentStateVars, *inputVars;
01097   mdd_t                 *presentStateCube, *inputCube;
01098 
01099   if (bwdImgFlag && fwdImgFlag)
01100     imgFlag = Img_Both_c;
01101   else if (bwdImgFlag)
01102     imgFlag = Img_Backward_c;
01103 
01104   if (fsm->fsmData.globalPsVars) {
01105     presentStateVars = fsm->fsmData.globalPsVars;
01106     inputVars = fsm->fsmData.primaryInputVars;
01107     presentStateCube = fsm->fsmData.globalPsCube;
01108     inputCube = fsm->fsmData.primaryInputCube;
01109   } else {
01110     presentStateVars = fsm->fsmData.presentStateVars;
01111     inputVars = fsm->fsmData.inputVars;
01112     presentStateCube = fsm->fsmData.presentStateCube;
01113     inputCube = fsm->fsmData.inputCube;
01114   }
01115 
01116   fsm->imageInfo = Img_ImageInfoInitialize(fsm->imageInfo,
01117                                            fsm->partition,
01118                                            fsm->fsmData.nextStateFunctions,
01119                                            presentStateVars,
01120                                            fsm->fsmData.nextStateVars,
01121                                            inputVars,
01122                                            presentStateCube,
01123                                            fsm->fsmData.nextStateCube,
01124                                            inputCube,
01125                                            fsm->network,
01126                                            Img_Linear_Range_c, imgFlag, 0, 0);
01127 
01128   if (fsm->fsmData.globalPsVars) {
01129     Img_ImageInfoUpdateVariables(fsm->imageInfo,
01130                                  fsm->partition,
01131                                  fsm->fsmData.presentStateVars,
01132                                  fsm->fsmData.inputVars,
01133                                  fsm->fsmData.presentStateCube,
01134                                  fsm->fsmData.inputCube);
01135   }
01136 
01137   return(fsm->imageInfo);
01138 }
01139 
01167 mdd_t *
01168 Fsm_FsmComputeInitialStates(Fsm_Fsm_t *fsm)
01169 {
01170   int            i = 0;
01171   lsGen          gen;
01172   mdd_t         *initStates;
01173   Ntk_Node_t    *node;
01174   array_t       *initRelnArray;
01175   array_t       *initMvfs;
01176   array_t       *initNodes;
01177   array_t       *initVertices;
01178   array_t       *latchMddIds;
01179   st_table      *supportNodes;
01180   st_table      *supportVertices;
01181   mdd_manager   *mddManager = Fsm_FsmReadMddManager(fsm);
01182   graph_t       *partition  = fsm->partition;
01183   Ntk_Network_t *network    = fsm->network;
01184   int            numLatches;
01185   array_t       *psVars;
01186   Img_MethodType imageMethod;
01187   
01188   /* If already computed, just return a copy. */
01189   if (fsm->reachabilityInfo.initialStates != NIL(mdd_t)){
01190     return (mdd_dup(fsm->reachabilityInfo.initialStates));
01191   }
01192 
01193   psVars = fsm->fsmData.presentStateVars;
01194   numLatches = array_n(psVars);
01195 
01196   /*
01197    * Get the array of initial nodes, both as network nodes and as partition
01198    * vertices.
01199    */
01200   initNodes    = array_alloc(Ntk_Node_t *, numLatches);
01201   initVertices = array_alloc(vertex_t *, numLatches);
01202   latchMddIds  = array_alloc(int, numLatches);
01203   for (i=0; i<numLatches; i++){
01204     int latchMddId = array_fetch(int, psVars, i);
01205     Ntk_Node_t *latch = Ntk_NetworkFindNodeByMddId(network, latchMddId);
01206     Ntk_Node_t *initNode   = Ntk_LatchReadInitialInput(latch);
01207     vertex_t   *initVertex = Part_PartitionFindVertexByName(partition,
01208                                 Ntk_NodeReadName(initNode));
01209     array_insert(Ntk_Node_t *, initNodes, i, initNode);
01210     array_insert(vertex_t *, initVertices, i, initVertex);
01211     array_insert(int, latchMddIds, i, Ntk_NodeReadMddId(latch));
01212   }
01213 
01214   /*
01215    * Get the table of legal support nodes, both as network nodes and
01216    * as partition vertices. Inputs (both primary and pseudo) and constants
01217    * constitute the legal support nodes.
01218    */
01219   supportNodes    = st_init_table(st_ptrcmp, st_ptrhash);
01220   supportVertices = st_init_table(st_ptrcmp, st_ptrhash);
01221   Ntk_NetworkForEachNode(network, gen, node) {
01222     vertex_t *vertex = Part_PartitionFindVertexByName(partition,
01223                                                       Ntk_NodeReadName(node));
01224 
01225     if (Ntk_NodeTestIsConstant(node) || Ntk_NodeTestIsInput(node)) {
01226       st_insert(supportNodes, (char *) node, NIL(char));
01227       st_insert(supportVertices, (char *) vertex, NIL(char));
01228     }
01229   }
01230 
01231   /*
01232    * If the initial nodes are not covered by the legal support nodes, then
01233    * return NIL.
01234    */
01235   if (!Ntk_NetworkTestLeavesCoverSupportOfRoots(network, initNodes,
01236                                                 supportNodes)) {
01237     array_free(initNodes);
01238     array_free(initVertices);
01239     array_free(latchMddIds);
01240     st_free_table(supportNodes);
01241     st_free_table(supportVertices);
01242     return NIL(mdd_t);
01243   }
01244 
01245   /*
01246    * At this point, we are certain that the initialization functions are
01247    * well-defined. Get the MVF for each initialization node, in terms of the
01248    * support vertices.  Note that the MVF for each initial node is guaranteed to
01249    * exist in the partition, since an initial node is a combinational
01250    * output.
01251    */
01252   array_free(initNodes);
01253   st_free_table(supportNodes);
01254   initMvfs = Part_PartitionCollapse(partition, initVertices,
01255                                     supportVertices, NIL(mdd_t)); 
01256   array_free(initVertices);
01257   st_free_table(supportVertices);
01258 
01259   /* Compute the relation (x_i = g_i(u)) for each latch. */
01260   initRelnArray = array_alloc(mdd_t*, numLatches);
01261   for (i = 0; i < numLatches; i++) {
01262     int latchMddId = array_fetch(int, latchMddIds, i);
01263     Mvf_Function_t *initMvf = array_fetch(Mvf_Function_t *, initMvfs, i);
01264     mdd_t *initLatchReln = Mvf_FunctionBuildRelationWithVariable(initMvf,
01265                                                                 latchMddId);
01266     array_insert(mdd_t *, initRelnArray, i, initLatchReln);
01267   }
01268 
01269   array_free(latchMddIds);
01270   Mvf_FunctionArrayFree(initMvfs);
01271 
01272   /* init_states(x) = \exists u \[\prod (x_i = g_i(u))\] */
01273   /*initStates = Fsm_MddMultiwayAndSmooth(mddManager, initRelnArray,
01274                                         fsm->fsmData.inputVars);
01275   */    
01276 
01277   imageMethod = Img_UserSpecifiedMethod();
01278   if (imageMethod != Img_Iwls95_c && imageMethod != Img_Mlp_c)
01279     imageMethod = Img_Iwls95_c;
01280   initStates = Img_MultiwayLinearAndSmooth(mddManager, initRelnArray,
01281                                            fsm->fsmData.inputVars, psVars,
01282                                            imageMethod, Img_Forward_c); 
01283 
01284   mdd_array_free(initRelnArray); 
01285 
01286   fsm->reachabilityInfo.initialStates = initStates;
01287   return mdd_dup(initStates);
01288 }
01289 
01290 
01291 
01306 array_t *
01307 Fsm_FsmReadPresentStateVars(Fsm_Fsm_t *fsm)
01308 {
01309   return fsm->fsmData.presentStateVars;
01310 }
01311 
01326 array_t *
01327 Fsm_FsmReadNextStateVars(Fsm_Fsm_t *fsm)
01328 {
01329   return fsm->fsmData.nextStateVars;
01330 }
01331 
01347 array_t *
01348 Fsm_FsmReadNextStateFunctionNames(Fsm_Fsm_t *fsm)
01349 {
01350   return fsm->fsmData.nextStateFunctions;
01351 }
01352 
01368 array_t *
01369 Fsm_FsmReadInputVars(Fsm_Fsm_t *fsm)
01370 {
01371   return fsm->fsmData.inputVars;
01372 }
01373 
01374 array_t *
01375 Fsm_FsmReadPrimaryInputVars(Fsm_Fsm_t *fsm)
01376 {
01377   return fsm->fsmData.primaryInputVars;
01378 }
01379 
01380 
01395 array_t *
01396 Fsm_FsmReadPseudoInputVars(Fsm_Fsm_t *fsm)
01397 {
01398   return fsm->fsmData.pseudoInputVars;
01399 }
01400 
01412 void
01413 Fsm_FsmSetInputVars(Fsm_Fsm_t *fsm, array_t *inputVars)
01414 {
01415   fsm->fsmData.inputVars = inputVars;
01416 }
01417 
01429 void
01430 Fsm_FsmSetUseUnquantifiedFlag(Fsm_Fsm_t *fsm, boolean value)
01431 {
01432   fsm->useUnquantifiedFlag = value;
01433 }
01434 
01447 void
01448 Fsm_FsmSetInitialStates(Fsm_Fsm_t *fsm, mdd_t *initStates)
01449 {
01450   mdd_t *init;
01451   
01452   init = fsm->reachabilityInfo.initialStates;
01453   if (init != NIL(mdd_t)) {
01454     mdd_free(init);
01455   }
01456   fsm->reachabilityInfo.initialStates = initStates;
01457 }
01458 
01470 int
01471 Fsm_FsmReadFAFWFlag(Fsm_Fsm_t *fsm) 
01472 {
01473   return((int)(fsm->FAFWFlag));
01474 }
01475 
01487 void
01488 Fsm_FsmSetFAFWFlag(Fsm_Fsm_t *fsm, boolean FAFWFlag) 
01489 {
01490   fsm->FAFWFlag = FAFWFlag;
01491 }
01492 
01505 void
01506 Fsm_FsmSetSystemVariableFAFW(Fsm_Fsm_t *fsm, st_table *bddIdTable)
01507 {
01508   mdd_manager *mgr;
01509   array_t *inputVars, *bddIdArray;
01510   bdd_t *extCube, *uniCube;
01511   bdd_t *newCube, *varBdd;
01512   st_generator *gen;
01513   int mddId, bddId, tbddId, i, j;
01514 
01515   if(bddIdTable == 0 && fsm->FAFWFlag == 0) {
01516     if(fsm->extQuantifyInputCube)
01517       bdd_free(fsm->extQuantifyInputCube);
01518     if(fsm->uniQuantifyInputCube)
01519       bdd_free(fsm->uniQuantifyInputCube);
01520     fsm->extQuantifyInputCube = 0;
01521     fsm->uniQuantifyInputCube = 0;
01522     return;
01523   }
01524 
01525   mgr = Fsm_FsmReadMddManager(fsm);
01526   inputVars = Fsm_FsmReadInputVars(fsm);
01527 
01528   extCube = mdd_one(mgr);
01529   for(i=0; i<array_n(inputVars); i++) {
01530     mddId = array_fetch(int, inputVars, i);
01531     bddIdArray = mdd_id_to_bdd_id_array(mgr, mddId);
01532     for(j=0; j<array_n(bddIdArray); j++) {
01533       bddId = array_fetch(int, bddIdArray, j);
01534       if(bddIdTable && st_lookup_int(bddIdTable, (char *)(long)bddId, &tbddId)) {
01535         continue;
01536       }
01537       varBdd = bdd_get_variable(mgr, bddId);
01538       newCube = bdd_and(extCube, varBdd, 1, 1);
01539       bdd_free(extCube); bdd_free(varBdd);
01540       extCube = newCube;
01541     }
01542     array_free(bddIdArray);
01543   }
01544   uniCube = mdd_one(mgr);
01545   if(bddIdTable) {
01546     st_foreach_item(bddIdTable, gen, &bddId, &bddId) {
01547       varBdd = bdd_get_variable(mgr, bddId);
01548       newCube = bdd_and(uniCube, varBdd, 1, 1);
01549       bdd_free(uniCube); bdd_free(varBdd);
01550       uniCube = newCube;
01551     }
01552   }
01553   fsm->extQuantifyInputCube = extCube;
01554   fsm->uniQuantifyInputCube = uniCube;
01555 }
01556 
01569 bdd_t *
01570 Fsm_FsmReadExtQuantifyInputCube(Fsm_Fsm_t *fsm)
01571 {
01572   return(fsm->extQuantifyInputCube);
01573 }
01574 
01587 bdd_t *
01588 Fsm_FsmReadUniQuantifyInputCube(Fsm_Fsm_t *fsm)
01589 {
01590   return(fsm->uniQuantifyInputCube);
01591 }
01592 
01611 Fsm_Fsm_t *
01612 Fsm_HrcManagerReadCurrentFsm(Hrc_Manager_t *hmgr)
01613 {
01614   Fsm_Fsm_t     *fsm;
01615   Ntk_Network_t *network = Ntk_HrcManagerReadCurrentNetwork(hmgr);
01616   
01617   if (network == NIL(Ntk_Network_t)) {
01618     return NIL(Fsm_Fsm_t);
01619   }
01620 
01621   if (Ord_NetworkTestAreVariablesOrdered(network, Ord_InputAndLatch_c) == FALSE) {
01622     (void) fprintf(vis_stderr, "** fsm error: The MDD variables have not been ordered.  ");
01623     (void) fprintf(vis_stderr, "Use static_order.\n");
01624     return NIL(Fsm_Fsm_t);
01625   }
01626 
01627   if (Part_NetworkReadPartition(network) == NIL(graph_t)){
01628     (void) fprintf(vis_stderr, "** fsm error: Network has not been partitioned.  ");
01629     (void) fprintf(vis_stderr, "Use build_partition_mdds.\n");
01630     return NIL(Fsm_Fsm_t);
01631   }
01632 
01633   error_init();
01634   fsm = Fsm_NetworkReadOrCreateFsm(network);
01635   if (fsm == NIL(Fsm_Fsm_t)) {
01636     (void) fprintf(vis_stderr, "%s", error_string());
01637     (void) fprintf(vis_stderr, "\n");
01638   }
01639   
01640   return fsm;
01641 }
01642 
01658 Fsm_Fsm_t *
01659 Fsm_FsmCreateSubsystemFromNetwork(
01660   Ntk_Network_t *network,
01661   graph_t       *partition,
01662   st_table      *vertexTable,
01663   boolean       independentFlag,
01664   int           createPseudoVarMode)
01665 {
01666   lsGen       gen;
01667   Ntk_Node_t *latch;
01668   Ntk_Node_t *input;
01669   Fsm_Fsm_t  *fsm;
01670   char *latchName;
01671   int i;
01672   st_table *pseudoMddIdTable = NIL(st_table);
01673 
01674   fsm = FsmStructAlloc(network, partition);
01675   if (fsm == NIL(Fsm_Fsm_t)) return NIL(Fsm_Fsm_t);
01676   fsm->fairnessInfo.constraint = FsmFsmCreateDefaultFairnessConstraint(fsm);
01677 
01678   /*
01679    * Creates an FSM for the subsystem.
01680    */
01681   /* sort latches by name. */
01682   Ntk_NetworkForEachLatch(network, gen, latch) {
01683     latchName = Ntk_NodeReadName(latch); 
01684     if(st_lookup(vertexTable, latchName, (char **)0)) {
01685       array_insert_last(char*, fsm->fsmData.nextStateFunctions, latchName);
01686     } /* end of if(st_lookup(vertexTable)) */
01687   }
01688 
01689   if (independentFlag && createPseudoVarMode) {
01690     fsm->fsmData.pseudoInputVars = array_alloc(int, 0);
01691     fsm->fsmData.primaryInputVars = array_alloc(int, 0);
01692     fsm->fsmData.globalPsVars = array_alloc(int, 0);
01693     if (createPseudoVarMode == 2)
01694       pseudoMddIdTable = st_init_table(st_numcmp, st_numhash);
01695   }
01696 
01697   array_sort(fsm->fsmData.nextStateFunctions, nameCompare);
01698   
01699   arrayForEachItem(char *, fsm->fsmData.nextStateFunctions, i, latchName) {
01700     latch = Ntk_NetworkFindNodeByName(network, latchName); 
01701     array_insert(char*, fsm->fsmData.nextStateFunctions, i,
01702                  Ntk_NodeReadName(Ntk_LatchReadDataInput(latch)));
01703     array_insert_last(int, fsm->fsmData.nextStateVars,
01704                       Ntk_NodeReadMddId(Ntk_NodeReadShadow(latch)));
01705     array_insert_last(int, fsm->fsmData.presentStateVars,
01706                       Ntk_NodeReadMddId(latch));
01707   } /* end of Ntk_NetworkForEachLatch(network, gen, latch) */
01708 
01709   /* Fill in remaining latch for nextStateVars */
01710   if (!independentFlag || createPseudoVarMode) {
01711     Ntk_NetworkForEachLatch(network, gen, latch) {
01712       char *latchName = Ntk_NodeReadName(latch); 
01713       if(!st_lookup(vertexTable, latchName, (char **)0)) {
01714         if (independentFlag) {
01715           if (createPseudoVarMode == 1) {
01716             array_insert_last(int, fsm->fsmData.pseudoInputVars,
01717                                 Ntk_NodeReadMddId(latch));
01718             array_insert_last(int, fsm->fsmData.inputVars,
01719                                 Ntk_NodeReadMddId(latch));
01720           } else {
01721             st_insert(pseudoMddIdTable, (char *)(long)Ntk_NodeReadMddId(latch),
01722                         NIL(char));
01723           }
01724         } else {
01725           array_insert_last(int, fsm->fsmData.nextStateVars, 
01726                             Ntk_NodeReadMddId(Ntk_NodeReadShadow(latch)));
01727           array_insert_last(int, fsm->fsmData.presentStateVars,
01728                             Ntk_NodeReadMddId(latch));
01729         }
01730       }
01731     }
01732   }
01733 
01734   /* Input variables are identical for every subsystems */
01735   Ntk_NetworkForEachInput(network, gen, input){
01736     array_insert_last(int, fsm->fsmData.inputVars, Ntk_NodeReadMddId(input));
01737     if (independentFlag && createPseudoVarMode) {
01738       array_insert_last(int, fsm->fsmData.primaryInputVars,
01739                         Ntk_NodeReadMddId(input));
01740     }
01741   }
01742 
01743   if (independentFlag && createPseudoVarMode) {
01744     if (createPseudoVarMode == 2) {
01745       int       mddId;
01746       array_t   *supportMddIdArray;
01747       st_table  *mddIdTable;
01748 
01749       mddIdTable = st_init_table(st_numcmp, st_numhash);
01750       arrayForEachItem(int, fsm->fsmData.presentStateVars, i, mddId) {
01751         st_insert(mddIdTable, (char *)(long)mddId, NIL(char));
01752       }
01753       arrayForEachItem(int, fsm->fsmData.inputVars, i, mddId) {
01754         st_insert(mddIdTable, (char *)(long)mddId, NIL(char));
01755       }
01756 
01757       supportMddIdArray = GetMddSupportIdArray(fsm, mddIdTable,
01758                                                 pseudoMddIdTable);
01759 
01760       arrayForEachItem(int, supportMddIdArray, i, mddId) {
01761         if (!st_lookup(mddIdTable, (char *)(long)mddId, NIL(char *))) {
01762           array_insert_last(int, fsm->fsmData.pseudoInputVars, mddId);
01763           array_insert_last(int, fsm->fsmData.inputVars, mddId);
01764         }
01765       }
01766       st_free_table(mddIdTable);
01767       st_free_table(pseudoMddIdTable);
01768       array_free(supportMddIdArray);
01769     }
01770 
01771     array_append(fsm->fsmData.globalPsVars, fsm->fsmData.presentStateVars);
01772     array_append(fsm->fsmData.globalPsVars, fsm->fsmData.pseudoInputVars);
01773   }
01774 
01775   FsmCreateVariableCubes(fsm);
01776   fsm->fsmData.presentStateBddVars = mdd_id_array_to_bdd_array(
01777     Fsm_FsmReadMddManager(fsm), fsm->fsmData.presentStateVars);
01778   return (fsm);
01779 }
01780 
01801 void
01802 Fsm_InstantiateHint(
01803   Fsm_Fsm_t *fsm,
01804   mdd_t *hint,
01805   int fwdFlag,
01806   int bwdFlag,
01807   Ctlp_Approx_t type,
01808   int printStatus)
01809 {
01810   boolean underApprox = FALSE;
01811   Img_DirectionType imgFlag = Img_Forward_c;
01812 
01813   assert(type != Ctlp_Incomparable_c);
01814   
01815   if (bwdFlag && fwdFlag)
01816     imgFlag = Img_Both_c;
01817   else if (bwdFlag)
01818     imgFlag = Img_Backward_c;
01819 
01820   switch (type) {
01821   case (Ctlp_Underapprox_c): underApprox = TRUE; break;
01822   case (Ctlp_Overapprox_c): underApprox = FALSE; break;
01823   case (Ctlp_Exact_c):
01824     underApprox = TRUE;
01825     hint = mdd_one(Fsm_FsmReadMddManager(fsm));
01826     break;
01827   default: assert(0); break;
01828   }
01829   /* If we reach this point, underApprox has been explicitly assigned
01830    * by the switch. */
01831   
01832   Img_ImageConstrainAndClusterTransitionRelation(
01833     Fsm_FsmReadOrCreateImageInfo(fsm, bwdFlag, fwdFlag),
01834     imgFlag,
01835     hint,
01836     ((underApprox == TRUE) ?
01837      Img_GuidedSearchReadUnderApproxMinimizeMethod() :
01838      Img_GuidedSearchReadOverApproxMinimizeMethod()),
01839     underApprox, /* underapprox */
01840     0, /* dont clean up */
01841     0, /* no variable reordering */
01842     printStatus);
01843 
01844   Fsm_MinimizeTransitionRelationWithReachabilityInfo(fsm, imgFlag,
01845                                                      printStatus); 
01846   
01847   if (type == Ctlp_Exact_c) mdd_free(hint);
01848 
01849   return;
01850 }
01851 
01863 void
01864 Fsm_CleanUpHints( Fsm_Fsm_t *fsm, int fwdFlag, int bwdFlag, int printStatus)
01865 {
01866   Img_DirectionType     imgFlag = Img_Forward_c;
01867   mdd_t *one = bdd_one(Fsm_FsmReadMddManager(fsm));
01868   if (bwdFlag && fwdFlag)
01869     imgFlag = Img_Both_c;
01870   else if (bwdFlag)
01871     imgFlag = Img_Backward_c;
01872 
01873   Img_ImageConstrainAndClusterTransitionRelation(fsm->imageInfo,
01874                                                  imgFlag,
01875                                                  one,
01876                                                  Img_GuidedSearchReadUnderApproxMinimizeMethod(),
01877                                                  1, /* under approx */
01878                                                  1, /* clean up */
01879                                                  0, /* no variable reordering */
01880                                                  printStatus);
01881   mdd_free(one);
01882   return;
01883 }
01884 
01885 
01897 void
01898 Fsm_FsmFreeReachableStates(Fsm_Fsm_t *fsm)
01899 {
01900   if (fsm->reachabilityInfo.reachableStates) {
01901     mdd_free(fsm->reachabilityInfo.reachableStates);
01902     fsm->reachabilityInfo.reachableStates = NIL(mdd_t);
01903   }
01904 }
01905 
01917 void
01918 Fsm_FsmFreeOverApproximateReachableStates(Fsm_Fsm_t *fsm)
01919 {
01920   if (fsm->reachabilityInfo.apprReachableStates) {
01921     mdd_array_free(fsm->reachabilityInfo.apprReachableStates);
01922     fsm->reachabilityInfo.apprReachableStates = NIL(array_t);
01923     fsm->reachabilityInfo.overApprox = Fsm_Ardc_NotConverged_c;
01924   }
01925   if (fsm->reachabilityInfo.subPsVars) {
01926     int i;
01927     array_t *psVars;
01928 
01929     for (i = 0; i < array_n(fsm->reachabilityInfo.subPsVars); i++) {
01930       psVars = array_fetch(array_t *, fsm->reachabilityInfo.subPsVars, i);
01931       array_free(psVars);
01932     }
01933     array_free(fsm->reachabilityInfo.subPsVars);
01934     fsm->reachabilityInfo.subPsVars = NIL(array_t);
01935   }
01936 }
01937 
01938 
01950 int
01951 Fsm_FsmGetReachableDepth(Fsm_Fsm_t *fsm)
01952 {
01953     return(fsm->reachabilityInfo.depth);
01954 }
01955 
01974 boolean
01975 Fsm_FsmCheckSameSubFsmInTotalFsm(Fsm_Fsm_t *fsm,
01976                                  Fsm_Fsm_t *subFsm1,
01977                                  Fsm_Fsm_t *subFsm2)
01978 {
01979   mdd_manager *mddMgr = Fsm_FsmReadMddManager(fsm);
01980   boolean result;
01981   
01982   assert(Fsm_FsmReadNetwork(fsm) == Fsm_FsmReadNetwork(subFsm1));
01983   assert(Fsm_FsmReadNetwork(fsm) == Fsm_FsmReadNetwork(subFsm2));
01984   assert(Fsm_FsmReadMddManager(subFsm1) == mddMgr);
01985   assert(Fsm_FsmReadMddManager(subFsm2) == mddMgr);
01986 
01987   /* compare present state variables */
01988   result = VarIdArrayCompare(mddMgr,
01989                              Fsm_FsmReadPresentStateVars(subFsm1),
01990                              Fsm_FsmReadPresentStateVars(subFsm2));
01991   if (!result) return FALSE;
01992 
01993   /* compare next state variables */
01994   result = VarIdArrayCompare(mddMgr,
01995                              Fsm_FsmReadNextStateVars(subFsm1),
01996                              Fsm_FsmReadNextStateVars(subFsm2));
01997   if (!result) return FALSE;
01998 
01999   /* compare input variables */
02000   result = VarIdArrayCompare(mddMgr,
02001                              Fsm_FsmReadInputVars(subFsm1),
02002                              Fsm_FsmReadInputVars(subFsm2));
02003   if (!result) return FALSE;
02004 
02005   /* compare the pseudo input variables */
02006   result = VarIdArrayCompare(mddMgr,
02007                              Fsm_FsmReadPseudoInputVars(subFsm1),
02008                              Fsm_FsmReadPseudoInputVars(subFsm2));
02009   if (!result) return FALSE;
02010 
02011   /* compare next state functions */
02012   result = NSFunctionNamesCompare(mddMgr,
02013                                   Fsm_FsmReadNextStateFunctionNames(subFsm1),
02014                                   Fsm_FsmReadNextStateFunctionNames(subFsm2));
02015   if (!result) return FALSE;
02016 
02017   return TRUE;
02018 }
02019 
02033 Fsm_RchStatus_t
02034 Fsm_FsmReadReachabilityApproxComputationStatus(Fsm_Fsm_t *fsm)
02035 {
02036   return fsm->reachabilityInfo.rchStatus;
02037 }
02038 
02052 void
02053 Fsm_MinimizeTransitionRelationWithReachabilityInfo(
02054   Fsm_Fsm_t *fsm,
02055   Img_DirectionType fwdbwd,
02056   boolean verbosity)
02057 {
02058   Img_ImageInfo_t *imageInfo;
02059   array_t *minimizeArray = NIL(array_t);
02060   boolean fwd            = FALSE;
02061   boolean bwd            = FALSE;
02062   int     oldVerbosity;
02063   Fsm_RchStatus_t status;
02064   boolean  freeArray;
02065   mdd_t *exactrdc;
02066   
02067   switch (fwdbwd) {
02068   case Img_Forward_c:
02069     fwd = 1;
02070     break;
02071   case Img_Backward_c:
02072     bwd = 1;
02073     break;
02074   case Img_Both_c:
02075     fwd = 1;
02076     bwd= 1;
02077     break;
02078   default:
02079     assert(0);
02080     break;
02081   }
02082   
02083   imageInfo = Fsm_FsmReadOrCreateImageInfo(fsm, bwd, fwd);
02084   oldVerbosity = Img_ReadPrintMinimizeStatus(imageInfo);
02085   
02086   status = Fsm_FsmReadReachabilityApproxComputationStatus(fsm);
02087   exactrdc = Fsm_FsmReadCurrentReachableStates(fsm);
02088   
02089   if((status == Fsm_Rch_Exact_c || status == Fsm_Rch_Over_c) &&
02090      exactrdc != NIL(mdd_t) ){
02091     freeArray = TRUE;
02092     minimizeArray = array_alloc(mdd_t *, 1);
02093     array_insert_last(mdd_t *, minimizeArray, mdd_dup(exactrdc)); 
02094   }else{
02095     freeArray = FALSE;
02096     minimizeArray = Fsm_FsmReadCurrentOverApproximateReachableStates(fsm);
02097     if(minimizeArray == NIL(array_t))
02098       return;
02099   }
02100 
02101   if(verbosity)
02102     Img_SetPrintMinimizeStatus(imageInfo, 1);
02103 
02104   /* We never reorder the clusters of the iwls structure.  It is probably
02105      better to reorder them, but as this is written, there is no time to
02106      evaluate the effect of reordering. */
02107     Img_MinimizeTransitionRelation(imageInfo, minimizeArray,
02108                                  Img_DefaultMinimizeMethod_c, fwdbwd, FALSE);
02109   
02110   if(verbosity)
02111     Img_SetPrintMinimizeStatus(imageInfo, oldVerbosity);
02112 
02113   if(freeArray)
02114     mdd_array_free(minimizeArray);
02115 
02116   return;
02117 }
02118 
02119 
02120 
02121 /*---------------------------------------------------------------------------*/
02122 /* Definition of internal functions                                          */
02123 /*---------------------------------------------------------------------------*/
02124 
02137 void
02138 FsmSetReachabilityOnionRings(
02139   Fsm_Fsm_t *fsm, array_t *onionRings)
02140 {
02141   fsm->reachabilityInfo.onionRings = onionRings;
02142 }
02143 
02155 void
02156 FsmSetReachabilityOnionRingsMode(
02157   Fsm_Fsm_t *fsm, Fsm_RchType_t value)
02158 {
02159   fsm->reachabilityInfo.onionRingsMode = value;
02160 }
02161 
02173 void
02174 FsmSetReachabilityOnionRingsUpToDateFlag(
02175   Fsm_Fsm_t *fsm,  boolean value)
02176 {
02177   fsm->reachabilityInfo.onionRingsUpToDate = value;
02178 }
02179 
02191 void
02192 FsmSetReachabilityApproxComputationStatus(
02193   Fsm_Fsm_t *fsm,  Fsm_RchStatus_t value)
02194 {
02195   fsm->reachabilityInfo.rchStatus = value;
02196 }
02197 
02209 void
02210 FsmSetReachabilityOverApproxComputationStatus(
02211   Fsm_Fsm_t *fsm,  Fsm_Ardc_StatusType_t status)
02212 {
02213   fsm->reachabilityInfo.overApprox = status;
02214 }
02215 
02227 Fsm_Ardc_StatusType_t
02228 FsmReadReachabilityOverApproxComputationStatus(Fsm_Fsm_t *fsm)
02229 {
02230   return(fsm->reachabilityInfo.overApprox);
02231 }
02232 
02246 void
02247 FsmSetReachabilityComputationMode(
02248   Fsm_Fsm_t *fsm,  Fsm_RchType_t value)
02249 {
02250   fsm->reachabilityInfo.reachabilityMode = value;
02251 }
02252 
02266 Fsm_RchType_t
02267 FsmReadReachabilityComputationMode(
02268   Fsm_Fsm_t *fsm)
02269 {
02270   return fsm->reachabilityInfo.reachabilityMode;
02271 }
02272 
02273 
02285 void
02286 FsmResetReachabilityFields(Fsm_Fsm_t *fsm, Fsm_RchType_t approxFlag)
02287 {
02288   int i;
02289   mdd_t *reachableStates;
02290   /* free reachable states if it is necessary to recompute anyway. */
02291   if (approxFlag != Fsm_Rch_Oa_c) {
02292     if (Fsm_FsmReadCurrentReachableStates(fsm)) {
02293       Fsm_FsmFreeReachableStates(fsm);
02294     }
02295   } else if (Fsm_FsmReadCurrentOverApproximateReachableStates(fsm)) {
02296     Fsm_FsmFreeOverApproximateReachableStates(fsm);
02297   }
02298         
02299   /* free onion rings */
02300   if (Fsm_FsmReadReachabilityOnionRings(fsm) != NIL(array_t)) {
02301     arrayForEachItem(mdd_t *, Fsm_FsmReadReachabilityOnionRings(fsm), i,
02302         reachableStates) {
02303       mdd_free(reachableStates);
02304     }
02305     array_free(Fsm_FsmReadReachabilityOnionRings(fsm));
02306     FsmSetReachabilityOnionRings(fsm, NIL(array_t));
02307   }
02308   fsm->reachabilityInfo.depth = 0;
02309   FsmSetReachabilityComputationMode(fsm, Fsm_Rch_Default_c);
02310   FsmSetReachabilityApproxComputationStatus(fsm, Fsm_Rch_Under_c);
02311   FsmSetReachabilityOnionRingsUpToDateFlag(fsm, FALSE);
02312   FsmSetReachabilityOnionRingsMode(fsm, Fsm_Rch_Default_c);
02313   return;
02314 } /* end of FsmResetReachabilityFields */
02315 
02316 
02317 /*---------------------------------------------------------------------------*/
02318 /* Definition of internal functions                                          */
02319 /*---------------------------------------------------------------------------*/
02331 FsmHdStruct_t *
02332 FsmHdStructAlloc(int nvars)
02333 {
02334   FsmHdStruct_t *hdInfo = ALLOC(FsmHdStruct_t, 1);
02335   if (hdInfo == NIL(FsmHdStruct_t)) return hdInfo;
02336   hdInfo->numDeadEnds = 0;
02337   hdInfo->firstSubset = TRUE;
02338   hdInfo->lastIter = -1;
02339   hdInfo->partialImage = FALSE;
02340   hdInfo->residueCount = 0;
02341   hdInfo->interiorStates = NIL(mdd_t);
02342   hdInfo->interiorStateCandidate = NIL(mdd_t);
02343   hdInfo->deadEndResidue = NIL(mdd_t);
02344   hdInfo->options = Fsm_FsmHdGetTravOptions(nvars);
02345   hdInfo->stats = FsmHdStatsStructAlloc();
02346   hdInfo->imageOfReachedComputed = FALSE;
02347   hdInfo->onlyPartialImage = FALSE;
02348   hdInfo->slowGrowth = 0;
02349   hdInfo->deadEndWithOriginalTR = FALSE;
02350   hdInfo->deadEndComputation = FALSE;
02351   return hdInfo;
02352 }
02353 
02354 
02366 void
02367 FsmHdStructFree(FsmHdStruct_t *hdInfo)
02368 {
02369   if (hdInfo->interiorStates != NULL) mdd_free(hdInfo->interiorStates);
02370   if (hdInfo->interiorStateCandidate != NULL)
02371     mdd_free(hdInfo->interiorStateCandidate);
02372   if (hdInfo->deadEndResidue != NULL) mdd_free(hdInfo->deadEndResidue);
02373   
02374   FsmHdStatsStructFree(hdInfo->stats);
02375   Fsm_FsmHdFreeTravOptions(hdInfo->options);
02376   FREE(hdInfo);
02377   return;
02378 }
02379 
02391 void
02392 FsmGuidedSearchPrintOptions(void)
02393 {
02394   char *string =  Cmd_FlagReadByName("guided_search_hint_type");
02395   if (string == NIL(char)) string = "local";
02396   fprintf(vis_stdout, "Flag guided_search_hint_type is set to %s.\n", string);
02397   string = Cmd_FlagReadByName("guided_search_underapprox_minimize_method");
02398   if (string == NIL(char)) string = "and";
02399   fprintf(vis_stdout, "Flag guided_search_underapprox_minimize_method is set to %s.\n", string);
02400   string = Cmd_FlagReadByName("guided_search_overapprox_minimize_method");
02401   if (string == NIL(char)) string = "ornot";
02402   fprintf(vis_stdout, "Flag guided_search_overapprox_minimize_method is set to %s.\n", string);
02403   string = Cmd_FlagReadByName("guided_search_sequence");
02404   if (string == NIL(char)) string = "all hints to convergence";
02405   fprintf(vis_stdout, "Flag guided_search_overapprox_minimize_method is set to %s.\n", string);
02406   return;
02407 }
02408 
02409 
02410 
02411 /*---------------------------------------------------------------------------*/
02412 /* Definition of static functions                                          */
02413 /*---------------------------------------------------------------------------*/
02425 static Fsm_Fsm_t *
02426 FsmStructAlloc(Ntk_Network_t *network,
02427             graph_t     *partition)
02428 {
02429   Fsm_Fsm_t *fsm;
02430   if (Ntk_NetworkReadNumLatches(network) == 0) {
02431     error_append("Network has no latches. Cannot create FSM.");
02432     return (NIL(Fsm_Fsm_t));
02433   }
02434   
02435   fsm = ALLOC(Fsm_Fsm_t, 1);
02436   if (fsm == NIL(Fsm_Fsm_t)) return NIL(Fsm_Fsm_t);
02437   memset(fsm, 0, sizeof(Fsm_Fsm_t));
02438 
02439   fsm->network = network;
02440 
02441   if (partition == NIL(graph_t)) {
02442     partition = Part_NetworkReadPartition(network);
02443 
02444     if (partition == NIL(graph_t)) {
02445       error_append("Network has no partition. Cannot create FSM.");
02446       return (NIL(Fsm_Fsm_t));
02447     } else {
02448       fsm->partition = Part_PartitionDuplicate(partition);
02449     }
02450   } else {
02451     fsm->partition = partition;
02452   }
02453   
02454   FsmSetReachabilityOnionRings(fsm, NIL(array_t));
02455   FsmSetReachabilityOnionRingsUpToDateFlag(fsm, FALSE);
02456   FsmSetReachabilityOnionRingsMode(fsm, Fsm_Rch_Default_c);
02457   FsmSetReachabilityApproxComputationStatus(fsm, Fsm_Rch_Under_c);
02458   FsmSetReachabilityComputationMode(fsm, Fsm_Rch_Default_c);
02459   FsmSetReachabilityOverApproxComputationStatus(fsm, Fsm_Ardc_NotConverged_c);
02460 
02461   fsm->fsmData.presentStateVars   = array_alloc(int, 0);
02462   fsm->fsmData.nextStateVars      = array_alloc(int, 0);
02463   fsm->fsmData.inputVars          = array_alloc(int, 0);
02464   fsm->fsmData.nextStateFunctions = array_alloc(char *, 0);
02465 
02466   return (fsm);
02467 } /* end of FsmStructAlloc */
02468 
02469 
02481 static void
02482 FsmCreateVariableCubes(Fsm_Fsm_t *fsm)
02483 {
02484   mdd_manager *manager = Fsm_FsmReadMddManager(fsm);
02485   char *flagValue;
02486   boolean createVariableCubesFlag = TRUE;
02487 
02488   if (bdd_get_package_name() != CUDD)
02489     return;
02490 
02491   flagValue = Cmd_FlagReadByName("fsm_create_var_cubes");
02492   if (flagValue != NIL(char)) {
02493     if (strcmp(flagValue, "yes") == 0)
02494       createVariableCubesFlag = TRUE;
02495     else if (strcmp(flagValue, "no") == 0)
02496       createVariableCubesFlag = FALSE;
02497     else {
02498       fprintf(vis_stderr,
02499         "** ardc error : invalid value %s for create_var_cubes[yes/no]. **\n",
02500         flagValue);
02501     }
02502   }
02503 
02504   if (!createVariableCubesFlag)
02505     return;
02506 
02507   fsm->fsmData.createVarCubesFlag = TRUE;
02508   fsm->fsmData.presentStateCube =
02509         mdd_id_array_to_bdd_cube(manager, fsm->fsmData.presentStateVars);
02510   fsm->fsmData.nextStateCube =
02511         mdd_id_array_to_bdd_cube(manager, fsm->fsmData.nextStateVars);
02512   fsm->fsmData.inputCube =
02513         mdd_id_array_to_bdd_cube(manager, fsm->fsmData.inputVars);
02514   if (fsm->fsmData.pseudoInputVars) {
02515     fsm->fsmData.pseudoInputCube =
02516         mdd_id_array_to_bdd_cube(manager, fsm->fsmData.pseudoInputVars);
02517   }
02518   if (fsm->fsmData.primaryInputVars) {
02519     fsm->fsmData.primaryInputCube =
02520         mdd_id_array_to_bdd_cube(manager, fsm->fsmData.primaryInputVars);
02521   }
02522   if (fsm->fsmData.globalPsVars) {
02523     fsm->fsmData.globalPsCube =
02524         mdd_id_array_to_bdd_cube(manager, fsm->fsmData.globalPsVars);
02525   }
02526 }
02527 
02528 
02538 static int
02539 nameCompare(
02540   const void * name1,
02541   const void * name2)
02542 {
02543     return(strcmp(*(char **)name1, *(char **)name2));
02544 
02545 } /* end of signatureCompare */
02546 
02547 
02560 static boolean
02561 VarIdArrayCompare(mdd_manager *mddMgr,
02562                   array_t *vars1,
02563                   array_t *vars2)
02564 {
02565   
02566   mdd_t *cube1, *cube2;
02567   boolean result = FALSE;
02568   cube1 = bdd_compute_cube(mddMgr, vars1);
02569   cube2 = bdd_compute_cube(mddMgr, vars2);
02570   if ((cube1 == NIL(mdd_t)) || (cube2 == NIL(mdd_t))) {
02571     result = (cube1 == cube2) ? TRUE : FALSE;
02572   } else {
02573     result =  bdd_equal(cube1, cube2) ? TRUE : FALSE;
02574   }
02575   if (cube1 != NIL(bdd_t)) bdd_free(cube1);
02576   if (cube2 != NIL(bdd_t)) bdd_free(cube2);
02577   return result;
02578 } /* end of VarIdArrayCompare */
02579 
02580 
02593 static boolean
02594 NSFunctionNamesCompare(mdd_manager *mddMgr,
02595                        array_t *names1,
02596                        array_t *names2)
02597 {
02598   int sizeArray = array_n(names1);
02599   int i, count;
02600   char *name;
02601   st_table *nameTable = st_init_table(strcmp, st_strhash);
02602 
02603   if (sizeArray != array_n(names2)) return FALSE;
02604   /* check if elements in names2 is in names1 */
02605   arrayForEachItem(char *, names1, i, name) {
02606     if (st_lookup_int(nameTable, name, &count)) {
02607       count++;
02608     } else {
02609       count = 1;
02610     }
02611     st_insert(nameTable, name, (char *)(long)count);
02612   }
02613   
02614   arrayForEachItem(char *, names2, i, name) {
02615     if (!st_lookup_int(nameTable, name, &count)) {
02616       st_free_table(nameTable);
02617       return FALSE;
02618     } else if (count == 0) { 
02619       st_free_table(nameTable);
02620       return FALSE;
02621     } else {
02622       count--;
02623       st_insert(nameTable, name, (char *)(long)count);   
02624     }
02625   }
02626   st_free_table(nameTable);
02627 
02628   /* check if elements in names1 is in names2 */
02629   nameTable = st_init_table(strcmp, st_strhash);
02630   arrayForEachItem(char *, names2, i, name) {
02631     if (st_lookup_int(nameTable, name, &count)) {
02632       count++;
02633     } else {
02634       count = 1;
02635     }
02636     st_insert(nameTable, name, (char *)(long)count);
02637   }
02638   
02639   arrayForEachItem(char *, names1, i, name) {
02640     if (!st_lookup_int(nameTable, name, &count)) {
02641       st_free_table(nameTable);
02642       return FALSE;
02643     } else if (count == 0) { 
02644       st_free_table(nameTable);
02645       return FALSE;
02646     } else {
02647       count--;
02648       st_insert(nameTable, name, (char *)(long)count);   
02649     }
02650   }
02651   st_free_table(nameTable);
02652   return TRUE;
02653 } /* end of NSFunctionNamesCompare */
02654 
02655 
02667 static array_t *
02668 GetMddSupportIdArray(Fsm_Fsm_t *fsm, st_table *mddIdTable,
02669                      st_table *pseudoMddIdTable)
02670 {
02671   mdd_t                 *func;
02672   char                  *nodeName;
02673   vertex_t              *vertex;
02674   Mvf_Function_t        *mvf;
02675   int                   i, j, k;
02676   long                  mddId;
02677   array_t               *varBddFunctionArray;
02678   mdd_manager           *mddManager;
02679   array_t               *supportMddIdArray, *support;
02680   st_table              *supportMddIdTable;
02681   st_generator          *stGen;
02682 
02683   supportMddIdTable = st_init_table(st_numcmp, st_numhash);
02684   mddManager = Part_PartitionReadMddManager(fsm->partition);
02685 
02686   for (i = 0; i < array_n(fsm->fsmData.nextStateFunctions); i++) {
02687     nodeName = array_fetch(char*, fsm->fsmData.nextStateFunctions, i);
02688     vertex = Part_PartitionFindVertexByName(fsm->partition, nodeName);
02689     mvf = Part_VertexReadFunction(vertex);
02690     mddId = (long) array_fetch(int, fsm->fsmData.nextStateVars, i);
02691     varBddFunctionArray = mdd_fn_array_to_bdd_fn_array(mddManager,
02692                                                        (int) mddId, mvf);
02693 
02694     for (j = 0; j < array_n(varBddFunctionArray); j++) {
02695       func = array_fetch(mdd_t *, varBddFunctionArray, j);
02696       support = mdd_get_support(mddManager, func);
02697       arrayForEachItem(int, support, k, mddId) {
02698         if (!st_lookup(supportMddIdTable, (char *)mddId, NIL(char *))) {
02699           if (st_lookup(mddIdTable, (char *)mddId, NIL(char *)) ||
02700               st_lookup(pseudoMddIdTable, (char *)mddId, NIL(char *))) {
02701             st_insert(supportMddIdTable, (char *)mddId, NIL(char));
02702           } else { /* intermediate variables */
02703             /* NEEDS to get the supports of an intermediate variable */
02704             assert(0);
02705           }
02706         }
02707       }
02708     }
02709     array_free(varBddFunctionArray);
02710   }
02711 
02712   supportMddIdArray = array_alloc(int, 0);
02713   st_foreach_item(supportMddIdTable, stGen, &mddId, NIL(char *)) {
02714     array_insert_last(int, supportMddIdArray, (int) mddId);
02715   }
02716 
02717   return(supportMddIdArray);
02718 }
02719 
02720