VIS

src/mc/mcDnC.c

Go to the documentation of this file.
00001 
00031 #include "mcInt.h"
00032 
00033 static char rcsid[] UNUSED = "$Id: mcDnC.c,v 1.9 2005/05/18 18:12:00 jinh Exp $";
00034 
00035 /*---------------------------------------------------------------------------*/
00036 /* Constant declarations                                                     */
00037 /*---------------------------------------------------------------------------*/
00038 
00039 /*---------------------------------------------------------------------------*/
00040 /* Structure declarations                                                    */
00041 /*---------------------------------------------------------------------------*/
00042 
00043 /*---------------------------------------------------------------------------*/
00044 /* Type declarations                                                         */
00045 /*---------------------------------------------------------------------------*/
00046 
00047 /*---------------------------------------------------------------------------*/
00048 /* Variable declarations                                                     */
00049 /*---------------------------------------------------------------------------*/
00050 
00051 /*---------------------------------------------------------------------------*/
00052 /* Macro declarations                                                        */
00053 /*---------------------------------------------------------------------------*/
00054 
00057 /*---------------------------------------------------------------------------*/
00058 /* Static function prototypes                                                */
00059 /*---------------------------------------------------------------------------*/
00060 static int SccIsStrong(mdd_manager *mddMgr, array_t *buechiFairness, mdd_t *SCC);
00061 static array_t * SortMddArrayBySize(Fsm_Fsm_t *fsm, array_t *mddArray);
00062 static int stringCompare(const void * s1, const void * s2);
00066 /*---------------------------------------------------------------------------*/
00067 /* Definition of exported functions                                          */
00068 /*---------------------------------------------------------------------------*/
00069 
00096 mdd_t *
00097 Mc_FsmCheckLanguageEmptinessByDnC(
00098   Fsm_Fsm_t *modelFsm,
00099   array_t *modelCareStates,
00100   Mc_AutStrength_t automatonStrength,
00101   int dcLevel,
00102   int dbgLevel,
00103   int printInputs,
00104   int verbosity,
00105   Mc_GSHScheduleType GSHschedule,
00106   Mc_FwdBwdAnalysis GSHdirection,
00107   int lockstep,
00108   FILE *dbgFile,
00109   int UseMore,
00110   int SimValue,
00111   char *driverName)
00112 {
00113   Ntk_Network_t   *network = Fsm_FsmReadNetwork(modelFsm);
00114   mdd_manager     *mddManager = Fsm_FsmReadMddManager(modelFsm);
00115   Fsm_Fairness_t  *modelFairness = NIL(Fsm_Fairness_t);
00116   array_t         *buechiFairness = NIL(array_t);
00117   int             isExactReachableStatesAvailable = 0;
00118   mdd_t           *reachableStates, *initialStates = NIL(mdd_t);
00119   mdd_t           *fairStates, *fairInitialStates = NIL(mdd_t);
00120   array_t         *onionRings = NIL(array_t);
00121   array_t         *strongSccClosedSets = NIL(array_t);
00122   array_t         *absLatchNameTableArray = NIL(array_t);
00123   int             numOfAbstractModels, iter, i, exitFlag;
00124   array_t         *arrayOfOnionRings = NIL(array_t);
00125   array_t         *ctlArray = array_alloc(Ctlp_Formula_t *, 0);
00126   array_t         *modelCareStatesArray = mdd_array_duplicate(modelCareStates);
00127   Mc_SccGen_t     *sccgen;
00128   int             composeIncSize, numOfLatches, maxLatchesToCompose;
00129 
00130   int             maxComposePercentage = 30;
00131   int             maxSccsToEnum = 100;
00132 
00133 
00134   /*
00135    * Read fairness constraints.
00136    */
00137   modelFairness = Fsm_FsmReadFairnessConstraint(modelFsm);
00138   buechiFairness = array_alloc(mdd_t *, 0);
00139   if (modelFairness != NIL(Fsm_Fairness_t)) {
00140     if (!Fsm_FairnessTestIsBuchi(modelFairness)) {
00141       (void) fprintf(vis_stdout, 
00142                      "** non-Buechi fairness constraints not supported\n");
00143       array_free(buechiFairness);
00144       assert(0);
00145     } else {
00146       int j;
00147       int numBuchi = Fsm_FairnessReadNumConjunctsOfDisjunct(modelFairness, 0);
00148       for (j = 0; j < numBuchi; j++) {
00149         Ctlp_Formula_t *tmpFormula;
00150         mdd_t *tempMdd;
00151         tmpFormula = Fsm_FairnessReadFinallyInfFormula(modelFairness, 0, j );
00152         tempMdd = Fsm_FairnessObtainFinallyInfMdd(modelFairness, 0, j,
00153                                                   modelCareStatesArray, 
00154                                                   (Mc_DcLevel) dcLevel);
00155         array_insert_last(mdd_t *, buechiFairness, tempMdd);
00156         array_insert_last( Ctlp_Formula_t *, ctlArray, 
00157                            Ctlp_FormulaDup(tmpFormula));
00158 #if 1
00159         fprintf(vis_stdout,"\nFairness[%d]:",j);
00160         Ctlp_FormulaPrint(vis_stdout, tmpFormula);
00161         fprintf(vis_stdout,"\n");
00162 #endif
00163       }
00164     }
00165   } else {
00166     array_insert_last(mdd_t *, buechiFairness, mdd_one(mddManager));
00167   }
00168 
00169   /*
00170    * If we need debugging information, arrayOfOnionRings != NIL(array_t), 
00171    */
00172   if (dbgLevel != McDbgLevelNone_c)
00173     arrayOfOnionRings = array_alloc(array_t *, 0);
00174   else
00175     arrayOfOnionRings = NIL(array_t);
00176 
00177   /* 
00178    * If exact/approximate reachable states are available, use them.
00179    */
00180   initialStates = Fsm_FsmComputeInitialStates(modelFsm);
00181   reachableStates = Fsm_FsmReadReachableStates(modelFsm);
00182   isExactReachableStatesAvailable = (reachableStates != NIL(mdd_t));
00183   if (!isExactReachableStatesAvailable) 
00184     reachableStates = McMddArrayAnd(modelCareStatesArray);
00185   else
00186     reachableStates = mdd_dup(reachableStates);
00187   onionRings = Fsm_FsmReadReachabilityOnionRings(modelFsm);
00188   if (onionRings == NIL(array_t)) {
00189     onionRings = array_alloc(mdd_t *, 0);
00190     array_insert(mdd_t *, onionRings, 0, mdd_dup(reachableStates));
00191   }else
00192     onionRings = mdd_array_duplicate(onionRings);
00193 
00194   strongSccClosedSets = array_alloc(mdd_t *, 0);
00195   array_insert(mdd_t *, strongSccClosedSets, 0, mdd_dup(reachableStates));
00196 
00197   /*
00198    * Compute a series of over-approximated abstract models
00199    */
00200   numOfLatches = array_n(Fsm_FsmReadPresentStateVars(modelFsm));
00201   maxLatchesToCompose = (numOfLatches * maxComposePercentage/100);
00202   maxLatchesToCompose = (maxLatchesToCompose > 20)? maxLatchesToCompose:20;
00203   composeIncSize = maxLatchesToCompose/10;
00204   composeIncSize = (composeIncSize > 4)? composeIncSize:4;
00205 
00206   absLatchNameTableArray = 
00207     Mc_CreateStaticRefinementScheduleArray(network,
00208                                            ctlArray,
00209                                            NIL(array_t),
00210                                            NIL(array_t),
00211                                            FALSE,
00212                                            FALSE,
00213                                            ((verbosity<McVerbosityMax_c)?
00214                                             0:McVerbositySome_c),
00215                                            composeIncSize,
00216                                            Part_CorrelationWithSupport);
00217   numOfAbstractModels = (array_n(absLatchNameTableArray) - 1);
00218   if (verbosity >= McVerbosityLittle_c) {
00219     fprintf(vis_stdout, 
00220             "-- DnC: scheduled total %d abs models with %d latches\n",
00221             numOfAbstractModels, numOfLatches);
00222   }
00223 
00224   if (verbosity >= McVerbositySome_c) {
00225     fprintf(vis_stdout, "-- DnC:\n");
00226     fprintf(vis_stdout, 
00227             "-- DnC: maxComposePercentage = %d\n", maxComposePercentage);
00228     fprintf(vis_stdout, 
00229             "-- DnC: numOfLatches         = %d\n", numOfLatches);
00230     fprintf(vis_stdout, 
00231             "-- DnC: composeIncSize       = %d\n", composeIncSize);
00232     fprintf(vis_stdout, 
00233             "-- DnC: numOfAbstractModels  = %d\n", numOfAbstractModels);
00234     fprintf(vis_stdout, 
00235             "-- DnC: maxLatchesToCompose  = %d\n", maxLatchesToCompose);
00236     fprintf(vis_stdout, 
00237             "-- DnC: maxSccsToEnum        = %d\n", maxSccsToEnum);
00238     fprintf(vis_stdout, "-- Dnc: \n");
00239   }
00240 
00241   exitFlag = 0;
00242   for (iter=0; iter<numOfAbstractModels; iter++) {
00243     Fsm_Fsm_t *absFsm = NIL(Fsm_Fsm_t);
00244     st_table  *absLatchNameTable = NIL(st_table);
00245     array_t   *absOnionRings;
00246     array_t   *tempArray = NIL(array_t);
00247     mdd_t     *sccClosedSet = NIL(mdd_t);
00248     mdd_t     *tempMdd = NIL(mdd_t);
00249     mdd_t     *absReachableStates = NIL(mdd_t);
00250 
00251     absLatchNameTable = array_fetch(st_table *, absLatchNameTableArray, iter);
00252     absFsm = Fsm_FsmCreateSubsystemFromNetwork(network, NIL(graph_t),
00253                                                absLatchNameTable, TRUE, 1);
00254 
00255     if (!isExactReachableStatesAvailable) {
00256       absReachableStates = Fsm_FsmComputeReachableStates(absFsm, 0, 0, 0, 0,
00257                                                          1, 0, 0,
00258                                                          Fsm_Rch_Default_c, 
00259                                                          0, 0,
00260                                                          NIL(array_t), FALSE,
00261                                                          NIL(array_t));
00262       absOnionRings = Fsm_FsmReadReachabilityOnionRings(absFsm);
00263       assert(absOnionRings);
00264       absOnionRings = mdd_array_duplicate(absOnionRings);
00265     }else {
00266       absReachableStates = McComputeAbstractStates(absFsm, reachableStates);
00267       absOnionRings = array_alloc(mdd_t *, array_n(onionRings));
00268       arrayForEachItem(mdd_t *, onionRings, i, tempMdd) {
00269         array_insert(mdd_t *, absOnionRings, i, 
00270                      McComputeAbstractStates(absFsm, tempMdd) );
00271       }
00272     }
00273 
00274     tempArray = strongSccClosedSets;
00275     strongSccClosedSets = array_alloc(mdd_t *, 0);
00276     arrayForEachItem(mdd_t *, tempArray, i, sccClosedSet) {
00277       sccClosedSet = (iter == 0)? 
00278         McComputeAbstractStates(absFsm, sccClosedSet): mdd_dup(sccClosedSet);
00279       tempMdd = mdd_and(sccClosedSet, absReachableStates, 1, 1);
00280       if (mdd_is_tautology(tempMdd, 0)) 
00281         mdd_free(tempMdd);
00282       else
00283         array_insert_last(mdd_t *, strongSccClosedSets, tempMdd);
00284       mdd_free(sccClosedSet);
00285     }
00286     mdd_array_free(tempArray);
00287 
00288     /* Refine SCC-closed sets, but up to a certain number */
00289     tempArray = strongSccClosedSets;
00290     strongSccClosedSets = array_alloc(mdd_t *, 0);
00291     Mc_FsmForEachFairScc(absFsm, sccgen, sccClosedSet, tempArray, 
00292                          strongSccClosedSets, /* new scc-closed sets */
00293                          buechiFairness, absOnionRings, FALSE,
00294                          ((verbosity<McVerbosityMax_c)?
00295                           McVerbosityNone_c:McVerbositySome_c),
00296                          (Mc_DcLevel) dcLevel) {
00297       if (SccIsStrong(mddManager, buechiFairness, sccClosedSet)) {
00298         array_insert_last(mdd_t *, strongSccClosedSets, sccClosedSet);
00299         if (maxSccsToEnum>0 && array_n(strongSccClosedSets)>maxSccsToEnum) {
00300           Mc_FsmSccGenFree(sccgen, strongSccClosedSets);
00301           break;
00302         }
00303 
00304       }else {
00305         array_t  *newCareStatesArray;
00306         newCareStatesArray = mdd_array_duplicate(modelCareStatesArray);
00307         if (!isExactReachableStatesAvailable) 
00308           array_insert_last(mdd_t *, newCareStatesArray, absReachableStates);
00309 
00310         if (verbosity >= McVerbositySome_c) 
00311           fprintf(vis_stdout, "-- DnC: search in a weak SCC-closed set\n");
00312 
00313         fairStates = McFsmRefineWeakFairSCCs(modelFsm, sccClosedSet, 
00314                                              newCareStatesArray, 
00315                                              arrayOfOnionRings, FALSE, 
00316                                              dcLevel, 
00317                          ((verbosity<McVerbosityMax_c)? 0:McVerbositySome_c) );
00318         fairInitialStates = mdd_and(initialStates, fairStates, 1, 1);
00319         mdd_free(fairStates);
00320         if (!mdd_is_tautology(fairInitialStates, 0)) { 
00321           /* Done, find a reachable fair cycle */
00322           exitFlag = 2;  
00323           if (verbosity >= McVerbosityLittle_c) 
00324             fprintf(vis_stdout, "-- DnC: find a weak SCC!\n");
00325           Mc_FsmSccGenFree(sccgen, NIL(array_t));
00326           break;
00327         }else {
00328           mdd_free(fairInitialStates); 
00329         }
00330       }
00331 
00332     }/*Mc_FsmForEachFairScc( ) {*/ 
00333     mdd_array_free(tempArray);
00334 
00335     SortMddArrayBySize(absFsm, strongSccClosedSets);
00336           
00337     if (verbosity >= McVerbosityLittle_c && exitFlag != 2) {
00338       fprintf(vis_stdout, 
00339               "-- DnC: found %d SCC-closed sets in abs model %d with %d latches\n",
00340               array_n(strongSccClosedSets), iter+1, 
00341               st_count(absLatchNameTable));
00342       if (verbosity >= McVerbositySome_c) {
00343         array_t *absPSvars = Fsm_FsmReadPresentStateVars(absFsm);
00344         array_t *PSvars = Fsm_FsmReadPresentStateVars(modelFsm);
00345         arrayForEachItem(mdd_t *, strongSccClosedSets, i, tempMdd) {
00346           fprintf(vis_stdout, "-- An SCC-closed set with %5g abs (%5g concrete) states\n",
00347                   mdd_count_onset(mddManager, tempMdd, absPSvars),
00348                   mdd_count_onset(mddManager, tempMdd, PSvars)
00349                   );
00350         }
00351       }
00352     }
00353 
00354     if(exitFlag == 0 && array_n(strongSccClosedSets) == 0) {
00355       /* Done, no reachable fair cycle exists */
00356       exitFlag = 1; 
00357     }
00358 
00359     mdd_array_free(absOnionRings);
00360     Fsm_FsmFree(absFsm);
00361 
00362     /* existFlag: 0 --> unknown;  1 --> no fair SCC; 2 --> find a fair SCC */
00363     if ( exitFlag != 0 || st_count(absLatchNameTable) > maxLatchesToCompose ) {
00364       if (!isExactReachableStatesAvailable) {
00365         array_insert_last(mdd_t *, modelCareStatesArray, absReachableStates);
00366         tempMdd = reachableStates;
00367         reachableStates = mdd_and(reachableStates, absReachableStates,1,1);
00368         mdd_free(tempMdd);
00369       }
00370       break;
00371     }
00372 
00373     mdd_free(absReachableStates);
00374         
00375   }/*for (iter=0; iter<numOfAbstractModels; iter++) {*/
00376 
00377   for (i=0; i<array_n(absLatchNameTableArray); i++) {
00378     st_free_table( array_fetch(st_table *, absLatchNameTableArray, i) );
00379   }
00380   array_free(absLatchNameTableArray);
00381 
00382 
00383   /*
00384    * Compute fair SCCs on the concrete model if necessary
00385    */
00386   if (exitFlag == 0) {
00387     array_t *tempArray;
00388     mdd_t   *sccClosedSet = NIL(mdd_t);
00389     mdd_t   *tempMdd = NIL(mdd_t);
00390 
00391     if (verbosity >= McVerbosityLittle_c) 
00392       fprintf(vis_stdout, "-- DnC: check the concrete model\n");
00393 
00394     tempArray = strongSccClosedSets;
00395     strongSccClosedSets = array_alloc(mdd_t *, 0);
00396     arrayForEachItem(mdd_t *, tempArray, i, sccClosedSet) {
00397       tempMdd = mdd_and(sccClosedSet, reachableStates, 1, 1);
00398       if (mdd_is_tautology(tempMdd, 0)) 
00399         mdd_free(tempMdd);
00400       else
00401         array_insert_last(mdd_t *, strongSccClosedSets, tempMdd);
00402       mdd_free(sccClosedSet);
00403     }
00404     array_free(tempArray);
00405 
00406     if (lockstep != MC_LOCKSTEP_OFF) {
00407       tempArray = array_alloc(mdd_t *, 0);
00408       fairStates = McFsmRefineFairSCCsByLockStep(modelFsm, lockstep,
00409                                                  tempArray, 
00410                                                  strongSccClosedSets,
00411                                                  NIL(array_t),
00412                                                  arrayOfOnionRings,
00413                                                  (Mc_VerbosityLevel) verbosity,
00414                                                  (Mc_DcLevel) dcLevel);
00415       mdd_array_free(tempArray);
00416     }else{
00417       mdd_t   *fairStates0, *sccClosedSet;
00418       array_t *EUonionRings;
00419       mdd_t   *mddOne = mdd_one(mddManager);
00420       Mc_EarlyTermination_t *earlyTermination;
00421 
00422       sccClosedSet = McMddArrayOr(strongSccClosedSets);
00423       fairStates0 = Mc_FsmEvaluateEGFormula(modelFsm, sccClosedSet,
00424                                             NIL(mdd_t), mddOne,
00425                                             modelFairness,
00426                                             modelCareStatesArray,
00427                                             MC_NO_EARLY_TERMINATION,
00428                                             NIL(array_t),
00429                                             Mc_None_c, 
00430                                             &arrayOfOnionRings,
00431                                             (Mc_VerbosityLevel) verbosity,
00432                                             (Mc_DcLevel) dcLevel,
00433                                             NIL(boolean),
00434                                             GSHschedule);
00435       mdd_free(sccClosedSet);
00436 
00437       EUonionRings = ( (arrayOfOnionRings == NIL(array_t))? 
00438                        NIL(array_t):array_alloc(mdd_t *,0) );
00439 
00440       earlyTermination = Mc_EarlyTerminationAlloc(McSome_c, initialStates);
00441       fairStates = Mc_FsmEvaluateEUFormula(modelFsm, mddOne,
00442                                            fairStates0, NIL(mdd_t), mddOne,
00443                                            modelCareStatesArray,
00444                                            earlyTermination,
00445                                            NIL(array_t), Mc_None_c,
00446                                            EUonionRings,
00447                                            (Mc_VerbosityLevel) verbosity,
00448                                            (Mc_DcLevel) dcLevel,
00449                                            NIL(boolean));
00450       mdd_free(fairStates0);
00451       mdd_free(mddOne);
00452       Mc_EarlyTerminationFree(earlyTermination);
00453 
00454       if (arrayOfOnionRings != NIL(array_t)) {
00455         int j;
00456         arrayForEachItem(array_t *, arrayOfOnionRings, i, tempArray) {
00457 #ifndef NDEBUG
00458           mdd_t *mdd1 = array_fetch_last(mdd_t *, tempArray);
00459 #endif
00460           arrayForEachItem(mdd_t *, EUonionRings, j, tempMdd) {
00461             if (j != 0) 
00462               array_insert_last(mdd_t *, tempArray, mdd_dup(tempMdd));
00463             else    
00464               assert( mdd_equal(tempMdd, mdd1) );
00465           }
00466         }
00467         mdd_array_free(EUonionRings);
00468       }
00469     }
00470 
00471     fairInitialStates = mdd_and(initialStates, fairStates, 1, 1);
00472     mdd_free(fairStates);
00473     exitFlag = mdd_is_tautology(fairInitialStates, 0)? 1:2;
00474   }
00475   
00476   /* Clean-Ups */
00477   mdd_array_free(modelCareStatesArray);
00478   mdd_array_free(strongSccClosedSets);
00479   mdd_array_free(onionRings);
00480   mdd_free(reachableStates);
00481   mdd_free(initialStates);
00482 
00483   /*
00484    * Print out the verification result (pass/fail, empty/non-empty)
00485    */
00486   if (exitFlag == 1) {
00487     if (strcmp(driverName, "LE") == 0)
00488       fprintf(vis_stdout, "# LE: language emptiness check passes\n");
00489     else
00490       fprintf(vis_stdout, "# %s: formula passed\n", driverName);
00491     if (arrayOfOnionRings != NIL(array_t))
00492       mdd_array_array_free(arrayOfOnionRings);
00493     return fairInitialStates;
00494 
00495   }else if (exitFlag == 2) {
00496     if (strcmp(driverName, "LE") == 0)
00497       fprintf(vis_stdout, "# LE: language is not empty\n");
00498     else
00499       fprintf(vis_stdout, "# %s: formula failed\n", driverName);
00500  
00501   }else {
00502     fprintf(vis_stderr, "* DnC error, result is unknown!\n");
00503     assert(0);
00504   }
00505 
00506   /*
00507    * Print out the debugging information if requested
00508    */
00509   if (dbgLevel == McDbgLevelNone_c) {
00510     if (arrayOfOnionRings != NIL(array_t)) 
00511       mdd_array_array_free(arrayOfOnionRings);
00512     return fairInitialStates;
00513 
00514   }else {
00515     mdd_t    *badStates, *aBadState, *mddOne;
00516     McPath_t *fairPath, *normalPath;
00517     array_t  *stemArray, *cycleArray;
00518     FILE     *tmpFile = vis_stdout;
00519     extern  FILE *vis_stdpipe;
00520     fprintf(vis_stdout, "# %s: generating path to fair cycle\n", driverName);
00521 
00522     /* Generate witness. */
00523     badStates = mdd_dup(fairInitialStates);
00524     aBadState = Mc_ComputeAState(badStates, modelFsm);
00525     mdd_free(badStates);
00526     
00527     mddOne = mdd_one(mddManager);
00528     fairPath = McBuildFairPath(aBadState, mddOne, arrayOfOnionRings, modelFsm,
00529                                modelCareStates, 
00530                                (Mc_VerbosityLevel) verbosity,
00531                                (Mc_DcLevel) dcLevel,
00532                                McFwd_c);
00533     mdd_free(mddOne);
00534     mdd_free(aBadState);
00535     mdd_array_array_free(arrayOfOnionRings);
00536     
00537     /* Print witness. */
00538     normalPath = McPathNormalize(fairPath);
00539     McPathFree(fairPath);
00540     
00541     stemArray = McPathReadStemArray(normalPath);
00542     cycleArray = McPathReadCycleArray(normalPath);
00543     
00544     /* we should pass dbgFile/UseMore as parameters 
00545        dbgFile = McOptionsReadDebugFile(options);*/
00546     if (dbgFile != NIL(FILE)) {
00547       vis_stdpipe = dbgFile;
00548     } else if (UseMore == TRUE) {
00549       vis_stdpipe = popen("more","w");
00550     } else {
00551       vis_stdpipe = vis_stdout;
00552     }
00553     vis_stdout = vis_stdpipe;
00554     
00555     /* We should also pass SimValue as a parameter */
00556     if (SimValue == FALSE) {
00557       (void) fprintf(vis_stdout, "# %s: path to fair cycle:\n\n", driverName);
00558       Mc_PrintPath(stemArray, modelFsm, printInputs);
00559       fprintf (vis_stdout, "\n");
00560       
00561       (void) fprintf(vis_stdout, "# %s: fair cycle:\n\n", driverName);
00562       Mc_PrintPath(cycleArray, modelFsm, printInputs);
00563       fprintf (vis_stdout, "\n");
00564     }else {
00565       array_t *completePath = McCreateMergedPath(stemArray, cycleArray);
00566       (void) fprintf(vis_stdout, "# %s: counter-example\n", driverName);
00567       McPrintSimPath(vis_stdout, completePath, modelFsm);
00568       mdd_array_free(completePath);
00569     }
00570 
00571     if (dbgFile == NIL(FILE) && UseMore == TRUE) {
00572       (void) pclose(vis_stdpipe);
00573     }  
00574     vis_stdout = tmpFile;
00575     
00576     McPathFree(normalPath);
00577   }
00578 
00579   return fairInitialStates;
00580 }
00581 
00600 array_t *
00601 Mc_CreateStaticRefinementScheduleArray(
00602   Ntk_Network_t         *network,
00603   array_t               *ctlArray,
00604   array_t               *ltlArray,
00605   array_t               *fairArray,
00606   boolean               dynamicIncrease,
00607   boolean               isLatchNameSort,
00608   int                   verbosity,
00609   int                   incrementalSize,
00610   Part_CMethod          correlationMethod)
00611 {
00612   array_t               *partitionArray;
00613   Part_Subsystem_t      *partitionSubsystem;
00614   Part_SubsystemInfo_t  *subsystemInfo; 
00615   st_table              *latchNameTable;
00616   st_table              *latchNameTableSum, *latchNameTableSumCopy;
00617   char                  *flagValue;
00618   st_generator          *stGen;
00619   char                  *name;
00620   double                affinityFactor;
00621   array_t               *scheduleArray;
00622   boolean               dynamicAndDependency = isLatchNameSort;
00623   array_t               *tempArray, *tempArray2;
00624   int                   i, count;
00625 
00626   /* affinity factor to decompose state space */
00627   flagValue = Cmd_FlagReadByName("part_group_affinity_factor");
00628   if(flagValue != NIL(char)){
00629     affinityFactor = atof(flagValue); 
00630   }
00631   else{
00632     /* default value */
00633     affinityFactor = 0.5; 
00634   }
00635 
00636   /* 
00637    * Obtain submachines as array: The first sub-system includes
00638    * variables in CTL/LTL/fair formulas and other latches are grouped
00639    * in the same way as Part_PartCreateSubsystems()
00640    */
00641   subsystemInfo = Part_PartitionSubsystemInfoInit(network);
00642   Part_PartitionSubsystemInfoSetBound(subsystemInfo, incrementalSize);
00643   Part_PartitionSubsystemInfoSetVerbosity(subsystemInfo, verbosity);
00644   Part_PartitionSubsystemInfoSetCorrelationMethod(subsystemInfo,
00645     correlationMethod); 
00646   Part_PartitionSubsystemInfoSetAffinityFactor(subsystemInfo, affinityFactor);
00647   partitionArray = Part_PartCreateSubsystemsWithCtlAndLtl(subsystemInfo,
00648                    ctlArray, ltlArray, fairArray, 
00649                    dynamicIncrease,dynamicAndDependency,FALSE);
00650   Part_PartitionSubsystemInfoFree(subsystemInfo);
00651 
00652   scheduleArray = array_alloc(st_table *, 0);
00653 
00654 
00655   /* 
00656    * For each partitioned submachines build an FSM. 
00657    */
00658   latchNameTableSum = st_init_table(strcmp, st_strhash);
00659   if (!dynamicAndDependency){
00660     for (i=0;i<array_n(partitionArray);i++){
00661       partitionSubsystem = array_fetch(Part_Subsystem_t *, partitionArray, i);
00662       if (partitionSubsystem != NIL(Part_Subsystem_t)) {
00663         latchNameTable = Part_PartitionSubsystemReadVertexTable(partitionSubsystem);
00664         st_foreach_item(latchNameTable, stGen, &name, NIL(char *)) {
00665           if (!st_lookup(latchNameTableSum, name, NIL(char *))){ 
00666             st_insert(latchNameTableSum, name, NIL(char));
00667           }
00668         }
00669         Part_PartitionSubsystemFree(partitionSubsystem);
00670       } 
00671       latchNameTableSumCopy = st_copy(latchNameTableSum);
00672       array_insert_last(st_table *, scheduleArray, latchNameTableSumCopy);
00673     }
00674   }else{
00675     partitionSubsystem = array_fetch(Part_Subsystem_t *, partitionArray, 0);
00676     latchNameTable = Part_PartitionSubsystemReadVertexTable(partitionSubsystem);
00677     st_foreach_item(latchNameTable, stGen, &name, NIL(char *)) {
00678       st_insert(latchNameTableSum, name, NIL(char));
00679     }
00680     latchNameTableSumCopy = st_copy(latchNameTableSum);
00681     array_insert_last(st_table *, scheduleArray, latchNameTableSumCopy);
00682     Part_PartitionSubsystemFree(partitionSubsystem);
00683     
00684     partitionSubsystem = array_fetch(Part_Subsystem_t *, partitionArray, 1);
00685     tempArray = array_alloc(char *, 0);    
00686     if (partitionSubsystem != NIL(Part_Subsystem_t)){
00687       latchNameTable = Part_PartitionSubsystemReadVertexTable(partitionSubsystem);
00688       st_foreach_item(latchNameTable, stGen, &name, NIL(char *)) {
00689         array_insert_last(char *, tempArray, name);
00690       }
00691       array_sort(tempArray, stringCompare);
00692       Part_PartitionSubsystemFree(partitionSubsystem);
00693     }
00694     
00695     partitionSubsystem = array_fetch(Part_Subsystem_t *, partitionArray, 2);
00696     tempArray2 = array_alloc(char *, 0);
00697     if (partitionSubsystem != NIL(Part_Subsystem_t)) {
00698       latchNameTable = Part_PartitionSubsystemReadVertexTable(partitionSubsystem);
00699       st_foreach_item(latchNameTable, stGen, &name, NIL(char *)) {
00700         array_insert_last(char *, tempArray2, name);
00701       }
00702       array_sort(tempArray2, stringCompare);
00703       Part_PartitionSubsystemFree(partitionSubsystem);
00704     }
00705 
00706     array_append(tempArray, tempArray2);
00707     array_free(tempArray2);
00708     
00709     count = 0;
00710     arrayForEachItem(char *, tempArray, i, name){   
00711       if (!st_lookup(latchNameTableSum, name, NIL(char *))){ 
00712         st_insert(latchNameTableSum, (char *)name, (char *)0);
00713         count++;
00714       }
00715       if ((count == incrementalSize) && (i < array_n(tempArray)-1)){
00716         latchNameTableSumCopy = st_copy(latchNameTableSum);
00717         array_insert_last(st_table *, scheduleArray, latchNameTableSumCopy);
00718         count = 0;
00719       }
00720     }
00721     array_free(tempArray);
00722     latchNameTableSumCopy = st_copy(latchNameTableSum);
00723     array_insert_last(st_table *, scheduleArray, latchNameTableSumCopy);
00724   }
00725   
00726   array_free(partitionArray);
00727   st_free_table(latchNameTableSum);
00728   
00729   return (scheduleArray);
00730 }
00731 
00732 
00733 /*---------------------------------------------------------------------------*/
00734 /* Definition of internal functions                                          */
00735 /*---------------------------------------------------------------------------*/
00736     
00756 mdd_t *
00757 McFsmRefineWeakFairSCCs(
00758   Fsm_Fsm_t *modelFsm, 
00759   mdd_t *sccClosedSet, 
00760   array_t *modelCareStatesArray, 
00761   array_t *arrayOfOnionRings,
00762   boolean isSccTerminal,
00763   int dcLevel, 
00764   int verbosity) 
00765 {
00766   mdd_manager *mddManager = Fsm_FsmReadMddManager(modelFsm);
00767   mdd_t *initialStates;
00768   mdd_t *mddOne, *mddEgFair, *mddEfEgFair, *fairInitStates, *mdd1;
00769   array_t *EFonionRings, *EGArrayOfOnionRings, *EGonionRings;
00770   array_t *newOnionRings;
00771   int i, j;
00772   Mc_EarlyTermination_t *earlyTermination;
00773 
00774   initialStates = Fsm_FsmComputeInitialStates(modelFsm);
00775   mddOne = mdd_one(mddManager);
00776 
00777   /* if debugging information is requested, arrayOfOnionRings!=NIL(array_t) */
00778   if (arrayOfOnionRings != NIL(array_t)) {
00779     EGArrayOfOnionRings = array_alloc(array_t *, 0);
00780     EFonionRings = array_alloc(mdd_t *, 0);
00781   }else {
00782     EGArrayOfOnionRings = NIL(array_t);
00783     EFonionRings = NIL(array_t);
00784   }
00785 
00786   if (isSccTerminal)
00787     mddEgFair = mdd_dup(sccClosedSet);
00788   else
00789     mddEgFair = Mc_FsmEvaluateEGFormula(modelFsm, sccClosedSet, 
00790                                         NIL(mdd_t), mddOne, 
00791                                         NIL(Fsm_Fairness_t),
00792                                         modelCareStatesArray, 
00793                                         NIL(Mc_EarlyTermination_t),
00794                                         NIL(array_t), Mc_None_c,
00795                                         &EGArrayOfOnionRings,
00796                                         (Mc_VerbosityLevel) verbosity,
00797                                         (Mc_DcLevel) dcLevel,
00798                                         NIL(boolean), McGSH_EL_c);
00799 
00800   earlyTermination = Mc_EarlyTerminationAlloc(McSome_c, initialStates);
00801   mddEfEgFair = Mc_FsmEvaluateEUFormula(modelFsm, mddOne,
00802                                         mddEgFair, NIL(mdd_t), mddOne,
00803                                         modelCareStatesArray,
00804                                         earlyTermination,
00805                                         NIL(array_t), Mc_None_c,
00806                                         EFonionRings,
00807                                         (Mc_VerbosityLevel) verbosity,
00808                                         (Mc_DcLevel) dcLevel,
00809                                         NIL(boolean));
00810   mdd_free(mddEgFair);
00811   Mc_EarlyTerminationFree(earlyTermination);
00812 
00813   fairInitStates = mdd_and(mddEfEgFair, initialStates, 1, 1);
00814 
00815   /* create the arrayOfOnionRings */
00816   if (arrayOfOnionRings!=NIL(array_t) && !mdd_is_tautology(fairInitStates,0)) {
00817     if (isSccTerminal) 
00818       array_insert_last(array_t *, 
00819                         arrayOfOnionRings, mdd_array_duplicate(EFonionRings));
00820     else {
00821       arrayForEachItem(array_t *, EGArrayOfOnionRings, i, EGonionRings) {
00822         newOnionRings = mdd_array_duplicate(EGonionRings);
00823         arrayForEachItem(mdd_t *, EFonionRings, j, mdd1) {
00824           if (j != 0)
00825             array_insert_last(mdd_t *, newOnionRings, mdd_dup(mdd1));
00826         }
00827         array_insert_last(array_t *, arrayOfOnionRings, newOnionRings);
00828       }
00829     }
00830   }
00831   mdd_free(fairInitStates);
00832   
00833   if (arrayOfOnionRings != NIL(array_t)) {
00834     mdd_array_free(EFonionRings);
00835     mdd_array_array_free(EGArrayOfOnionRings);
00836   }
00837 
00838   mdd_free(initialStates);
00839   mdd_free(mddOne);
00840 
00841   return mddEfEgFair;
00842 }
00843 
00844 
00857 mdd_t * 
00858 McComputeAbstractStates(
00859   Fsm_Fsm_t *absFsm, 
00860   mdd_t *states)
00861 {
00862   mdd_t       *result;
00863   mdd_manager *mddManager = Fsm_FsmReadMddManager(absFsm);
00864   array_t     *psVars = Fsm_FsmReadPresentStateVars(absFsm);
00865   array_t     *supportVars;
00866   array_t     *invisibleVars = array_alloc(long, 0);
00867   st_table    *psVarTable = st_init_table(st_numcmp, st_numhash);
00868   int         i;
00869   long        mddId;
00870 
00871   arrayForEachItem(long, psVars, i, mddId) {
00872     st_insert(psVarTable, (char *)mddId, NIL(char));
00873   }
00874   
00875   supportVars = mdd_get_support(mddManager, states);
00876   arrayForEachItem(long, supportVars, i, mddId) {
00877     if (!st_is_member(psVarTable, (char *)mddId)) 
00878       array_insert_last(long, invisibleVars, mddId);
00879   }
00880   array_free(supportVars);
00881   st_free_table(psVarTable);
00882 
00883   result = mdd_smooth(mddManager, states, invisibleVars);
00884 
00885   array_free(invisibleVars);
00886 
00887   return result;
00888 }
00889 
00890 
00902 boolean
00903 McGetDncEnabled(void)
00904 {
00905   char *flagValue;
00906   boolean result = FALSE;
00907  
00908   flagValue = Cmd_FlagReadByName("divide_and_compose");
00909   if (flagValue != NIL(char)) {
00910     if (strcmp(flagValue, "true") == 0)
00911       result = TRUE;
00912     else if (strcmp(flagValue, "false") == 0)
00913       result = FALSE;
00914     else {
00915       fprintf(vis_stderr, "** dnc error: invalid dnc_enable flag %s, dnc is disabled. \n", flagValue);
00916     }
00917   }
00918 
00919   return result;
00920 }
00921 
00922 
00923 /*---------------------------------------------------------------------------*/
00924 /* Definition of static functions                                            */
00925 /*---------------------------------------------------------------------------*/
00926 
00940 static boolean
00941 SccIsStrong(mdd_manager *mddMgr, array_t *buechiFairness, mdd_t *SCC)
00942 {
00943   boolean strength;
00944   mdd_t *LabeledAllFairness = mdd_dup(SCC);
00945   mdd_t *NotLabeledAllFairness;
00946   mdd_t *fairSet;
00947   int i;
00948     
00949   /*
00950    * check whether SCC intersects all the fairness constraints
00951    * if yes, WEAK
00952    * if no,  WEAK or STRONG
00953    */
00954   arrayForEachItem(mdd_t *, buechiFairness, i, fairSet) {
00955     mdd_t *tmpMdd = LabeledAllFairness;
00956     LabeledAllFairness = mdd_and(LabeledAllFairness, fairSet, 1,1 );
00957     mdd_free( tmpMdd );
00958   }
00959   NotLabeledAllFairness = mdd_and(SCC, LabeledAllFairness, 1, 0);
00960   mdd_free(LabeledAllFairness);
00961   
00962   if(mdd_is_tautology(NotLabeledAllFairness, 0)) {
00963     mdd_free(NotLabeledAllFairness);
00964     strength = FALSE; /* WEAK*/
00965   }
00966   else {
00967     mdd_free(NotLabeledAllFairness);
00968     strength = TRUE;
00969   }
00970   
00971   return strength;
00972 }
00973 
00983 static st_table *array_mdd_compare_table = NIL(st_table);
00984 static int 
00985 array_mdd_compare_size(
00986   const void *obj1, 
00987   const void *obj2) 
00988 {
00989   double *val1, *val2;
00990   int flag1, flag2;
00991 
00992   flag1 = st_lookup(array_mdd_compare_table, *((char **)obj1), &val1);
00993   flag2 = st_lookup(array_mdd_compare_table, *((char **)obj2), &val2);
00994   assert(flag1 && flag2);
00995 
00996   if (*val1 < *val2)
00997     return -1;
00998   else if (*val1> *val2)
00999     return +1;
01000   else 
01001     return 0;
01002 }
01003 
01016 static array_t *
01017 SortMddArrayBySize(Fsm_Fsm_t *fsm, array_t *mddArray)
01018 {
01019   mdd_manager *mddManager = Fsm_FsmReadMddManager(fsm);
01020   array_t     *psVars = Fsm_FsmReadPresentStateVars(fsm);
01021   
01022   if (array_n(psVars) < 1024) {
01023     st_table    *mddToSizeTable =st_init_table(st_ptrcmp, st_ptrhash);
01024     double      *sizes = ALLOC(double, array_n(mddArray));
01025     mdd_t       *mdd1;
01026     int         i;
01027 
01028     arrayForEachItem(mdd_t *, mddArray, i, mdd1) {
01029       *(sizes+i) = mdd_count_onset(mddManager, mdd1, psVars);
01030       st_insert(mddToSizeTable, (char *)mdd1, (char *)(sizes+i));
01031     }
01032     
01033     array_mdd_compare_table = mddToSizeTable;
01034     array_sort(mddArray, array_mdd_compare_size);
01035 
01036     FREE(sizes);
01037     st_free_table(mddToSizeTable);
01038   }
01039 
01040   return mddArray;
01041 }
01042 
01043         
01051 static int
01052 stringCompare(
01053   const void * s1,
01054   const void * s2)
01055 {
01056   return(strcmp(*(char **)s1, *(char **)s2));
01057 }
01058 
01059