VIS

src/imc/imcCmd.c

Go to the documentation of this file.
00001 
00017 #include "imcInt.h"
00018 #include "fsm.h"
00019 
00020 static char rcsid[] UNUSED = "$Id: imcCmd.c,v 1.24 2002/09/10 04:07:38 fabio Exp $";
00021 
00022 
00023 /*---------------------------------------------------------------------------*/
00024 /* Constant declarations                                                     */
00025 /*---------------------------------------------------------------------------*/
00026 
00027 /*---------------------------------------------------------------------------*/
00028 /* Structure declarations                                                    */
00029 /*---------------------------------------------------------------------------*/
00030 
00031 /*---------------------------------------------------------------------------*/
00032 /* Type declarations                                                         */
00033 /*---------------------------------------------------------------------------*/
00034 
00035 /*---------------------------------------------------------------------------*/
00036 /* Variable declarations                                                     */
00037 /*---------------------------------------------------------------------------*/
00038 
00039 static jmp_buf timeOutEnv;
00040 
00041 /*---------------------------------------------------------------------------*/
00042 /* Macro declarations                                                        */
00043 /*---------------------------------------------------------------------------*/
00044 
00047 /*---------------------------------------------------------------------------*/
00048 /* Static function prototypes                                                */
00049 /*---------------------------------------------------------------------------*/
00050 
00051 static int CommandImc(Hrc_Manager_t ** hmgr, int argc, char ** argv);
00052 static void IterativeModelCheckUsage(void);
00053 static void TimeOutHandle(void);
00054 
00058 /*---------------------------------------------------------------------------*/
00059 /* Definition of exported functions                                          */
00060 /*---------------------------------------------------------------------------*/
00061 
00071 void
00072 Imc_Init(void)
00073 {
00074   Cmd_CommandAdd("iterative_model_check", CommandImc, 0);
00075 }
00076 
00077 
00087 void
00088 Imc_End(void)
00089 {
00090 }
00091 
00092 
00093 /*---------------------------------------------------------------------------*/
00094 /* Definition of internal functions                                          */
00095 /*---------------------------------------------------------------------------*/
00096 
00097 
00098 /*---------------------------------------------------------------------------*/
00099 /* Definition of static functions                                            */
00100 /*---------------------------------------------------------------------------*/
00101 
00225 static int
00226 CommandImc(
00227   Hrc_Manager_t ** hmgr,
00228   int  argc,
00229   char ** argv)
00230 {
00231   static int          timeOutPeriod;      /* CPU seconds allowed */
00232   char                *ctlFileName;       /* Name of file containing formulas */
00233   FILE                *ctlFile;           /* File to read the formulas from */
00234   Ntk_Network_t       *network;           /* Pointer to the current network */
00235   array_t             *ctlFormulaArray;   /* Array of read ctl formulas */
00236   array_t             *ctlNormalForm;     /* Array of normal ctl formulas */
00237   Ctlp_Formula_t      *formula;           /* Formula being verified */
00238   Ctlp_Formula_t      *orgFormula; 
00239   Ctlp_Formula_t      *currentFormula; 
00240   char                *modelName;
00241   Hrc_Node_t          *currentNode;
00242   int                 c, i;
00243   array_t             *dagFormula;
00244   Imc_RefineMethod    refine;             /* Refine Method */
00245   mdd_t               *careStates;        /* Care States */
00246   Imc_DcLevel         dcLevel;            /* Don't Care Level */
00247   Imc_VerbosityLevel  verbosity;          /* Verbosity level */
00248   Fsm_Fsm_t           *reducedFsm;
00249   Fsm_Fsm_t           *exactFsm;
00250   int                 incrementalSize;
00251   int                 option;
00252   Fsm_ArdcOptions_t   *ardcOptions;
00253   Imc_GraphType       graphType;
00254   Imc_LowerMethod     lowerMethod;
00255   Imc_UpperMethod     upperMethod;
00256   boolean             needLower, needUpper;
00257   boolean             computeExact;
00258   Imc_PartMethod      partMethod;
00259   graph_t             *partition;
00260 
00261   long globalTimeStart;
00262   long globalTimeEnd;
00263   long initialTime;
00264   long finalTime;
00265 
00266 
00267   /* Initialize Default Values */
00268   timeOutPeriod    = 0;
00269   ctlFileName      = NIL(char);
00270   verbosity        = Imc_VerbosityNone_c;
00271   dcLevel          = Imc_DcLevelNone_c;
00272   incrementalSize  = 4;
00273   lowerMethod      = Imc_LowerUniversalQuantification_c;
00274   upperMethod      = Imc_UpperExistentialQuantification_c;
00275   computeExact     = FALSE;
00276   partMethod       = Imc_PartAll_c;
00277   refine           = Imc_RefineLatchRelation_c;
00278   graphType        = Imc_GraphMOG_c;
00279 
00280   /*
00281    * Parse command line options.
00282    */
00283   util_getopt_reset();
00284   while ((c = util_getopt(argc, argv, "hxt:r:i:l:p:v:D:g:")) != EOF) {
00285     switch(c) {
00286       case 'h':
00287         IterativeModelCheckUsage();
00288         return 1;
00289       case 'x':
00290         computeExact = TRUE;
00291         break;
00292       case 't':
00293         timeOutPeriod = atoi(util_optarg);
00294         if (timeOutPeriod < 0){
00295           fprintf(vis_stdout,"** imc warning : Timeout Option -t %s is not defined.\n",
00296                   util_optarg);
00297           IterativeModelCheckUsage();
00298           return 1;
00299         }
00300               break;
00301       case 'r':
00302         option = atoi(util_optarg);
00303         if (option == 0) refine = Imc_RefineSort_c;
00304         else if (option == 1) refine = Imc_RefineLatchRelation_c;
00305         else{
00306           fprintf(vis_stdout,"** imc warning : Refine option -r %d is not defined.\n",
00307                   option);
00308           IterativeModelCheckUsage();
00309           return 1;
00310         }
00311         break;
00312       case 'i':
00313         incrementalSize = atoi(util_optarg);
00314         if (incrementalSize<1){
00315           fprintf(vis_stdout,"** imc warning : Incremental size option -i %d",
00316                   incrementalSize);
00317           fprintf(vis_stdout," is not defined.\n");
00318           IterativeModelCheckUsage();
00319           return 1;
00320         }
00321         break;
00322       case 'l':
00323         option = atoi(util_optarg);
00324         if (option==0){
00325           lowerMethod = Imc_LowerSubsetTR_c;
00326         }else if (option==1){
00327           lowerMethod = Imc_LowerUniversalQuantification_c;
00328         }else{
00329           fprintf(vis_stdout,"** imc warning : Lower bound option option -l %d",
00330                   option);
00331           fprintf(vis_stdout," is not defined.\n");
00332           IterativeModelCheckUsage();
00333           return 1;
00334         }
00335         break;
00336       case 'p':
00337         option = atoi(util_optarg);
00338         if (option==0){
00339           partMethod = Imc_PartAll_c;
00340         }else if (option==1){
00341           partMethod = Imc_PartDepend_c;
00342         }else if (option==2){
00343           partMethod = Imc_PartInc_c;
00344         }else{
00345           fprintf(vis_stdout,"** imc warning : Partition option -p %d",
00346                   option);
00347           fprintf(vis_stdout," is not defined.\n");
00348           IterativeModelCheckUsage();
00349           return 1;
00350         }
00351         break;
00352       case 'v':
00353         option = atoi(util_optarg);
00354         if (option == 0) verbosity = Imc_VerbosityNone_c;
00355         else if (option == 1) verbosity = Imc_VerbosityMin_c;
00356               else if (option == 2) verbosity = Imc_VerbosityMax_c;
00357         else{
00358                 fprintf(vis_stdout,"** imc warning : Verbosity option -v %d",
00359                         option);
00360                 fprintf(vis_stdout, " is not defined.\n");
00361           IterativeModelCheckUsage();
00362           return 1;
00363               }
00364         break;
00365       case 'D':
00366         option = atoi(util_optarg);
00367               if (option == 0) dcLevel = Imc_DcLevelNone_c;
00368         else if (option == 1) dcLevel = Imc_DcLevelRch_c;
00369               else if (option == 2) dcLevel = Imc_DcLevelMax_c;
00370               else if (option == 3) dcLevel = Imc_DcLevelArdc_c;
00371         else{
00372                 fprintf(vis_stdout,"** imc warning : Don't care option -D %d",
00373                         option);
00374                 fprintf(vis_stdout, " is not defined.\n");
00375           IterativeModelCheckUsage();
00376           return 1;
00377               }
00378         break;
00379       case 'g':
00380         option = atoi(util_optarg);
00381         if (option == 0) graphType = Imc_GraphNDOG_c;
00382         else if (option == 1) graphType = Imc_GraphPDOG_c;
00383         else if (option == 2) graphType = Imc_GraphMOG_c;
00384         else{
00385                 fprintf(vis_stdout,"** imc warning : Graph type option -g %d",
00386                         option);
00387                 fprintf(vis_stdout," is not defined.\n");
00388           IterativeModelCheckUsage();
00389           return 1;
00390               }
00391         break;    
00392       default:
00393               IterativeModelCheckUsage();
00394               return 1;
00395     }
00396   }
00397 
00398   /* Make sure the CTL file has been provided */
00399   if (argc == util_optind) {
00400     IterativeModelCheckUsage();
00401     return 1;
00402   }
00403   else {
00404     ctlFileName = argv[util_optind];
00405   }
00406 
00407   /* 
00408    * Obtain the network from the hierarchy manager 
00409    */
00410   network = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
00411   if (network == NIL(Ntk_Network_t)) {
00412     return 1;
00413   }
00414 
00415   /* 
00416    * Read in the array of CTL formulas provided in ctlFileName 
00417    */
00418   ctlFile = Cmd_FileOpen(ctlFileName, "r", NIL(char *), 0);
00419   if (ctlFile == NIL(FILE)) {
00420     return 1;
00421   }
00422   ctlFormulaArray = Ctlp_FileParseFormulaArray(ctlFile);
00423   fclose(ctlFile);
00424 
00425   if (ctlFormulaArray == NIL(array_t)) {
00426     fprintf(vis_stderr, "** imc error: Error while parsing ctl formulas in file.\n");
00427     return 1;
00428   } 
00429 
00430   /* 
00431    * Start the timer. 
00432    */
00433   if (timeOutPeriod > 0) {
00434     (void) signal(SIGALRM, (void(*)(int))TimeOutHandle);
00435     (void) alarm(timeOutPeriod);
00436 
00437     /* The second time setjmp is called, it returns here !!*/
00438     if (setjmp(timeOutEnv) > 0) {
00439       (void) fprintf(vis_stdout, "IMC: Timeout occurred after %d seconds.\n",
00440                      timeOutPeriod);
00441       alarm(0);
00442 
00443       /* Note that there is a huge memory leak here. */
00444       Ctlp_FormulaArrayFree(ctlFormulaArray);
00445       return 1;
00446     } 
00447   }
00448 
00449   currentNode = Hrc_ManagerReadCurrentNode(*hmgr);
00450   modelName = Hrc_NodeReadModelName(currentNode);
00451   partition = Part_NetworkReadPartition(network);
00452 
00453   exactFsm = NIL(Fsm_Fsm_t);
00454   reducedFsm = NIL(Fsm_Fsm_t);
00455   careStates = NIL(mdd_t);
00456 
00457   if ((computeExact)&&(partMethod == Imc_PartInc_c)){
00458     partMethod = Imc_PartDepend_c;
00459   }
00460 
00461   if ((dcLevel != Imc_DcLevelNone_c) && (partMethod == Imc_PartInc_c)){
00462     partMethod = Imc_PartDepend_c;
00463   }
00464 
00465   if (partition == NIL(graph_t) && (partMethod != Imc_PartInc_c)){
00466     if (partMethod == Imc_PartAll_c){
00467 
00468       partition = Part_NetworkCreatePartition(network, currentNode, modelName,
00469                                           (lsList)0, (lsList)0, NIL(mdd_t),
00470                                           Part_InOut_c, (lsList)0, FALSE,
00471                                           verbosity, 0);
00472       Ntk_NetworkAddApplInfo(network, PART_NETWORK_APPL_KEY,
00473                           (Ntk_ApplInfoFreeFn) Part_PartitionFreeCallback,
00474                           (void *) partition);
00475 
00476     }else if (partMethod == Imc_PartDepend_c){
00477       partition = Part_PartCreatePartitionWithCTL(hmgr, Part_InOut_c, verbosity, 
00478                                       0, FALSE, ctlFormulaArray, NIL(array_t));
00479       /* Register the partition in the network if any */
00480       Ntk_NetworkAddApplInfo(network, PART_NETWORK_APPL_KEY,
00481                           (Ntk_ApplInfoFreeFn) Part_PartitionFreeCallback,
00482                           (void *) partition);
00483     }
00484   }
00485  
00486   if (partition != NIL(graph_t)){ 
00487     exactFsm = Fsm_NetworkReadOrCreateFsm(network); 
00488     reducedFsm = Mc_ConstructReducedFsm(network, ctlFormulaArray);
00489     if (reducedFsm==NIL(Fsm_Fsm_t)){
00490       reducedFsm = exactFsm;
00491     }
00492 
00493     /*
00494      * Check whether the fairness was read. Fairnedd is ignored.
00495      */
00496     {
00497       Fsm_Fairness_t *fairCons =  Fsm_FsmReadFairnessConstraint(exactFsm);
00498       int numOfConj     = Fsm_FairnessReadNumConjunctsOfDisjunct(fairCons, 0);
00499       if (numOfConj > 1) {
00500         /* Buchi */
00501         fprintf(vis_stdout, "** imc warning : Fairness Constraint is not supported.");
00502         fprintf(vis_stdout, " Fairness Constraint is ignored.\n");
00503       }else if (numOfConj == 1){
00504         /* check if fairness is simply default fairness formula, which is TRUE */
00505         Ctlp_Formula_t *formula = Fsm_FairnessReadFinallyInfFormula(fairCons, 0, 0);
00506         if (Ctlp_FormulaReadType(formula) != Ctlp_TRUE_c){
00507           fprintf(vis_stdout, "** imc warning : Fairness Constraint is not supported.");
00508           fprintf(vis_stdout, " Fairness Constraint is ignored.\n");
00509         }
00510       }
00511     }
00512   } 
00513 
00514   globalTimeStart = util_cpu_time();
00515 
00516   if (partition != NIL(graph_t)){
00517 
00518     if (dcLevel == Imc_DcLevelArdc_c){
00519       if (verbosity != Imc_VerbosityNone_c){
00520         fprintf(vis_stdout, "IMC: Computing approximate reachable states.\n");
00521       }
00522       ardcOptions = Fsm_ArdcAllocOptionsStruct();
00523       Fsm_ArdcGetDefaultOptions(ardcOptions); 
00524       initialTime = util_cpu_time();
00525       (void) Fsm_ArdcComputeOverApproximateReachableStates(
00526         reducedFsm, 0, verbosity, 0, 0, 0, 0, 0, 0, ardcOptions);
00527       finalTime = util_cpu_time();
00528       if (verbosity != Imc_VerbosityNone_c) {
00529         Fsm_ArdcPrintReachabilityResults(reducedFsm, finalTime - initialTime);
00530       }
00531       /* CW::user is responsible to free Fsm_ArdcGetMdd...
00532       careStates
00533         = mdd_dup(Fsm_ArdcGetMddOfOverApproximateReachableStates(reducedFsm));
00534       */
00535       careStates
00536         = Fsm_ArdcGetMddOfOverApproximateReachableStates(reducedFsm);
00537       
00538     }else if (dcLevel >= Imc_DcLevelRch_c){
00539       if (verbosity != Imc_VerbosityNone_c){
00540          fprintf(vis_stdout, "IMC: Computing exact reachable states.\n");
00541       }
00542       initialTime = util_cpu_time();
00543       careStates = Fsm_FsmComputeReachableStates(reducedFsm,
00544                                          0, 1, 0, 0, 0, 0, 0,
00545                                          Fsm_Rch_Default_c, 0, 0,
00546                                          NIL(array_t), FALSE, NIL(array_t));
00547       finalTime = util_cpu_time();
00548       if (verbosity != Imc_VerbosityNone_c) {
00549         Fsm_FsmReachabilityPrintResults(reducedFsm, finalTime - initialTime,
00550                                       Fsm_Rch_Default_c);
00551       }
00552     }else{
00553       careStates = NIL(mdd_t);
00554     }
00555   
00556     if (reducedFsm != NIL(Fsm_Fsm_t) && 
00557         Fsm_FsmReadImageInfo(reducedFsm) != NIL(Img_ImageInfo_t)) {
00558       Fsm_FsmFreeImageInfo(reducedFsm);
00559     }
00560   }
00561 
00562   ctlNormalForm = Ctlp_FormulaArrayConvertToSimpleExistentialFormTree(
00563                   ctlFormulaArray);
00564 
00565   /* 
00566    * Loop over every CTL formula in the array 
00567    */
00568   arrayForEachItem(Ctlp_Formula_t *, ctlNormalForm, i, currentFormula) {
00569     Ctlp_FormulaClass formulaClass;    
00570     array_t * singleFormulaArray = array_alloc(Ctlp_Formula_t *, 1);
00571 
00572     array_insert(Ctlp_Formula_t *, singleFormulaArray, 0, currentFormula);
00573     dagFormula = Ctlp_FormulaArrayConvertToDAG(singleFormulaArray);
00574     array_free(singleFormulaArray);
00575     formula = array_fetch(Ctlp_Formula_t *, dagFormula, 0);
00576     array_free(dagFormula);
00577 
00578     formulaClass = Ctlp_CheckClassOfExistentialFormula(formula);
00579 
00580     /*
00581      * Type of approximation needed for verification
00582      *
00583      *       pDOG  nDOG  MOG
00584      * ---------------------
00585      * ACTL    L     U    B
00586      * ECTL    U     L    B
00587      * Mixed   B     B    B
00588      */
00589 
00590     if ((formulaClass == Ctlp_Mixed_c) || (graphType == Imc_GraphMOG_c)){
00591       needLower = TRUE;
00592       needUpper = TRUE;
00593 
00594     }else if (((formulaClass == Ctlp_ACTL_c) && (graphType == Imc_GraphPDOG_c)) ||
00595         ((formulaClass == Ctlp_ECTL_c) && (graphType == Imc_GraphNDOG_c))){
00596       needLower = TRUE;
00597       needUpper = FALSE;      
00598 
00599     }else{
00600       needLower = FALSE;
00601       needUpper = TRUE;
00602     }            
00603 
00604     if (!Mc_FormulaStaticSemanticCheckOnNetwork(formula,network,FALSE)){
00605       (void) fprintf(vis_stdout, "\n** imc error: Error in parsing formula:\n%s\n", 
00606                      error_string());
00607       error_init();
00608       continue;
00609     }
00610 
00611     error_init();
00612     initialTime = util_cpu_time();
00613    
00614     orgFormula = array_fetch(Ctlp_Formula_t *, ctlFormulaArray, i);
00615 
00616     Imc_ImcEvaluateFormulaLinearRefine(network, orgFormula, formula, 
00617       formulaClass, incrementalSize, verbosity, refine, careStates, reducedFsm,
00618       dcLevel, graphType, lowerMethod, upperMethod, computeExact, needLower, 
00619       needUpper, partMethod, currentNode, modelName);
00620 
00621     finalTime = util_cpu_time();
00622     if(verbosity != Imc_VerbosityNone_c) {
00623       (void) fprintf(vis_stdout, "%-20s%10ld\n\n",
00624                      "IMC: Verification time for this formula =",
00625                      (finalTime - initialTime) / 1000);
00626     }
00627     fprintf(vis_stdout, "\n");
00628     
00629   } /* End of arrayForEachItem in ctlFormulaArray */
00630 
00631   if (careStates)
00632     mdd_free(careStates); /* FIXED */
00633 
00634   globalTimeEnd = util_cpu_time();
00635 
00636   if (verbosity != Imc_VerbosityNone_c) {
00637      (void) fprintf(vis_stdout, "%-20s%10ld\n\n",
00638                     "IMC: Total verification time =",
00639                     (globalTimeEnd - globalTimeStart) / 1000);
00640   } 
00641   
00642   /* Deactivate the alarm */
00643   alarm(0);
00644 
00645   if ((reducedFsm != NIL(Fsm_Fsm_t)) && (exactFsm != reducedFsm)){
00646     Fsm_FsmFree(reducedFsm);
00647   }
00648 
00649   Ctlp_FormulaArrayFree(ctlFormulaArray);
00650   Ctlp_FormulaArrayFree(ctlNormalForm);
00651   error_cleanup();
00652 
00653   /* normal exit */
00654   return 0;
00655 }
00656 
00666 static void
00667 IterativeModelCheckUsage(void)
00668 {
00669   fprintf(vis_stderr, "usage: iterative_model_check [-h] [-x]");
00670   fprintf(vis_stderr, "[-t <secs>] [-v <number>] [-D <number>] [-r <number>]");
00671   fprintf(vis_stderr, "[-i <number] [-l <number] [-p <number] [-g <number] ctlfile\n");
00672   fprintf(vis_stderr, "   -h        print the command usage\n");
00673   fprintf(vis_stderr, "   -x        Exact verification\n");
00674   fprintf(vis_stderr, "   -t secs   Seconds allowed for computation\n");
00675   fprintf(vis_stderr, "   -v number verbosity level (0:none, 1:mid, 2:max)\n");
00676   fprintf(vis_stderr, "   -D number Don't care level. DC's are used to\n");
00677   fprintf(vis_stderr, "             reduce transition relation\n");
00678   fprintf(vis_stderr, "        0    No don't care (default)\n");
00679   fprintf(vis_stderr, "        1    Exact reachable states\n");
00680   fprintf(vis_stderr, "        2    Aggressively use DC's\n");
00681   fprintf(vis_stderr, "        3    Approximate reachable states\n");
00682   fprintf(vis_stderr, "   -r number Refinement method\n");
00683   fprintf(vis_stderr, "        0    Static scheduling by name sorting\n");
00684   fprintf(vis_stderr, "        1    Static scheduling by latch affinity (defualt)\n");
00685   fprintf(vis_stderr, "   -i number Incremental size (default = 4)\n");
00686   fprintf(vis_stderr, "   -l number Type of lower-bound approximation method\n");
00687   fprintf(vis_stderr, "        0    Take a subset of each transition sub-relation\n");
00688   fprintf(vis_stderr, "        1    Take a subset by universal quantification (default)\n");
00689   fprintf(vis_stderr, "   -p number Type of partition method\n");
00690   fprintf(vis_stderr, "        0    Build all next state functions (default)\n");
00691   fprintf(vis_stderr, "        1    Build the next state functions related to formulas\n");
00692   fprintf(vis_stderr, "        2    Build the next state functions incrementally\n");
00693   fprintf(vis_stderr, "   -g number Type of operational graph\n");
00694   fprintf(vis_stderr, "        0    Negative Operational Graph\n");
00695   fprintf(vis_stderr, "        1    Positive Operational Graph\n");
00696   fprintf(vis_stderr, "        2    Mixed Operational Graph (default)\n");  
00697   fprintf(vis_stderr, "   ctlfile   File containing the ctl formulas\n");
00698 
00699   return;
00700 } /* End of IterativeModelCheckUsage */
00701 
00702 
00715 static void
00716 TimeOutHandle(void)
00717 {
00718   longjmp(timeOutEnv, 1);
00719 } /* End of TimeOutHandle */