VIS

src/bmc/bmcCmd.c

Go to the documentation of this file.
00001 
00017 #include "bmcInt.h"
00018 
00019 static char rcsid[] UNUSED = "$Id: bmcCmd.c,v 1.83 2010/04/09 23:50:57 fabio Exp $";
00020 
00021 /*---------------------------------------------------------------------------*/
00022 /* Constant declarations                                                     */
00023 /*---------------------------------------------------------------------------*/
00024 
00025 /*---------------------------------------------------------------------------*/
00026 /* Type declarations                                                         */
00027 /*---------------------------------------------------------------------------*/
00028 
00029 
00030 /*---------------------------------------------------------------------------*/
00031 /* Structure declarations                                                    */
00032 /*---------------------------------------------------------------------------*/
00033 
00034 
00035 /*---------------------------------------------------------------------------*/
00036 /* Variable declarations                                                     */
00037 /*---------------------------------------------------------------------------*/
00038 static jmp_buf timeOutEnv;
00039 static int bmcTimeOut;          /* timeout value */
00040 static long alarmLapTime;       /* starting CPU time for timeout */
00041 
00044 /*---------------------------------------------------------------------------*/
00045 /* Static function prototypes                                                */
00046 /*---------------------------------------------------------------------------*/
00047 
00048 static BmcOption_t * ParseBmcOptions(int argc, char **argv);
00049 static int CommandBmc(Hrc_Manager_t ** hmgr, int argc, char ** argv);
00050 static void TimeOutHandle(void);
00051 static void DispatchBmcCommand(Ntk_Network_t *network, Ctlsp_Formula_t *ltlFormula, array_t *constraintArray, BmcOption_t *options);
00052 static int CommandCnfSat(Hrc_Manager_t ** hmgr, int argc, char ** argv);
00053 
00057 /*---------------------------------------------------------------------------*/
00058 /* Definition of exported functions                                          */
00059 /*---------------------------------------------------------------------------*/
00060 
00070 void
00071 Bmc_Init(void)
00072 {
00073   Cmd_CommandAdd("bounded_model_check", CommandBmc, /* doesn't change network */  0);
00074   
00075   Cmd_CommandAdd("cnf_sat", CommandCnfSat, /* doesn't change network */  0); 
00076 }
00077 
00087 void
00088 Bmc_End(void)
00089 {
00090 }
00091 
00092 /*---------------------------------------------------------------------------*/
00093 /* Definition of internal functions                                          */
00094 /*---------------------------------------------------------------------------*/
00095 
00096 
00106 static BmcOption_t *
00107 ParseBmcOptions(
00108   int argc,
00109   char **argv)
00110 {
00111   BmcOption_t  *options = BmcOptionAlloc();
00112   char *ltlFileName     = NIL(char);
00113   unsigned int i;
00114   int          c;
00115   
00116   if (!options){
00117     return NIL(BmcOption_t);
00118   }
00119   
00120   options->dbgOut = 0;
00121   /*
00122    * Parse command line options.
00123    */
00124   util_getopt_reset();
00125   while ((c = util_getopt(argc, argv, "E:C:S:F:O::I:hiv:m:k:s:o:t:d:r:e")) != EOF) {
00126     switch(c) {
00127     case 'F':
00128       options->fairFile = Cmd_FileOpen(util_optarg, "r", NIL(char *), 0);
00129       if (options->fairFile == NIL(FILE)) {
00130         (void) fprintf(vis_stdout,
00131                        "** bmc error: Cannot open the file %s\n",
00132                        util_optarg);
00133         BmcOptionFree(options);
00134         return NIL(BmcOption_t);
00135       }
00136       break;
00137     case 'O':
00138       options->dbgOut = Cmd_FileOpen(util_optarg, "w", NIL(char *), 0);
00139       if(options->dbgOut == NIL(FILE)) {
00140         (void) fprintf(vis_stdout, "**bmc error: Cannot open %s for debug information.\n", util_optarg);
00141          BmcOptionFree(options);
00142          return NIL(BmcOption_t);
00143       } 
00144       break;
00145     case 'm':
00146       for (i = 0; i < strlen(util_optarg); i++) {
00147         if (!isdigit((int)util_optarg[i])) {
00148           goto usage;
00149         }
00150       }
00151       options->minK = atoi(util_optarg);
00152       break;
00153     case 'k':
00154       for (i = 0; i < strlen(util_optarg); i++) {
00155         if (!isdigit((int)util_optarg[i])) {
00156           goto usage;
00157         }
00158       }
00159       options->maxK = atoi(util_optarg);
00160       break;
00161     case 's':
00162       for (i = 0; i < strlen(util_optarg); i++) {
00163         if (!isdigit((int)util_optarg[i])) {
00164           goto usage;
00165         }
00166       }
00167       options->step = atoi(util_optarg);
00168       break;
00169     case 'r':
00170       for (i = 0; i < strlen(util_optarg); i++) {
00171         if (!isdigit((int)util_optarg[i])) {
00172           goto usage;
00173         }
00174       }
00175       options->inductiveStep = atoi(util_optarg);
00176       break;
00177     case 'e':
00178       options->earlyTermination = TRUE;
00179       break;    
00180     case 'd':
00181       for (i = 0; i < strlen(util_optarg); i++) {
00182         if (!isdigit((int)util_optarg[i])) {
00183           goto usage;
00184         }
00185       }
00186       options->dbgLevel = atoi(util_optarg);
00187       break;    
00188     case 't' :
00189       options->timeOutPeriod = atoi(util_optarg);
00190         break;
00191     case 'i':
00192       options->printInputs = TRUE;
00193       break;    
00194     case 'h':
00195       goto usage;
00196     case 'v':
00197       for (i = 0; i < strlen(util_optarg); i++) {
00198         if (!isdigit((int)util_optarg[i])) {
00199           goto usage;
00200         }
00201       }
00202       options->verbosityLevel = (Bmc_VerbosityLevel) atoi(util_optarg);
00203       break;
00204     case 'o':
00205       options->cnfFileName = util_strsav(util_optarg);
00206       break;    
00207     case 'I' :
00208       options->incremental = atoi(util_optarg);
00209       break;
00210     case 'E':
00211       for (i = 0; i < strlen(util_optarg); i++) {
00212         if (!isdigit((int)util_optarg[i])) {
00213           goto usage;
00214         }
00215       }
00216       options->encoding = atoi(util_optarg);
00217       if((options->encoding < 0) || (options->encoding > 2)){
00218         goto usage;
00219       }
00220       break;
00221     case 'S':
00222       for (i = 0; i < strlen(util_optarg); i++) {
00223         if (!isdigit((int)util_optarg[i])) {
00224           goto usage;
00225         }
00226       }
00227       options->satSolver = atoi(util_optarg);
00228       if((options->satSolver < 0) || (options->satSolver > 1)){
00229         goto usage;
00230       }
00231       break;
00232     case 'C':
00233       for (i = 0; i < strlen(util_optarg); i++) {
00234         if (!isdigit((int)util_optarg[i])) {
00235           goto usage;
00236         }
00237       }
00238       options->clauses = atoi(util_optarg);
00239       if((options->clauses < 0) || (options->clauses > 2)){
00240         goto usage;
00241       }
00242       break;
00243     default:
00244       goto usage;
00245     }
00246   }
00247   if (options->minK > options->maxK){
00248     (void) fprintf(vis_stderr, "** bmc error: value for -m option must not be greater than vlaue for -k option\n");    
00249     goto usage;
00250   }
00251   /*
00252    * Open the ltl file.
00253    */
00254   if (argc - util_optind == 0) {
00255     (void) fprintf(vis_stderr, "** bmc error: file containing ltl formulae not provided\n");
00256     goto usage;
00257   }
00258   else if (argc - util_optind > 1) {
00259     (void) fprintf(vis_stderr, "** bmc error: too many arguments\n");
00260     goto usage;
00261   }
00262   ltlFileName = util_strsav(argv[util_optind]);
00263   
00264   /* Read LTL Formulae */
00265   if (!ltlFileName) 
00266       goto usage;
00267 
00268   options->ltlFile = Cmd_FileOpen(ltlFileName, "r", NIL(char *), 0);
00269   if (options->ltlFile == NIL(FILE)) {
00270     (void) fprintf(vis_stdout,"** bmc error: Cannot open the file %s\n", ltlFileName);
00271     FREE(ltlFileName);
00272     BmcOptionFree(options);
00273     return NIL(BmcOption_t);
00274   }
00275   FREE(ltlFileName);
00276   /* create SAT Solver input file */
00277   if (options->cnfFileName == NIL(char)) {
00278     options->satInFile = BmcCreateTmpFile(); 
00279     if (options->satInFile == NIL(char)){
00280       BmcOptionFree(options);
00281       return NIL(BmcOption_t);
00282     }
00283   } else {
00284     options->satInFile = options->cnfFileName;
00285   }
00286   /* create SAT Solver output file */
00287   options->satOutFile = BmcCreateTmpFile();
00288   if (options->satOutFile == NIL(char)){
00289     BmcOptionFree(options);
00290     return NIL(BmcOption_t);
00291   }
00292   return options;
00293   
00294  usage:
00295   (void) fprintf(vis_stderr, "usage: bmc [-h][-m minimum_length][-k maximum_length][-s step][-r inductive_step][-e][-F <fairness_file>][-d debug_level][-E <encoding>][-C <clauses>][-S <sat_solver>][-O <debug_file>][-I <level>][-v verbosity_level][-t period][-o <cnf_file>] <ltl_file>\n");
00296   (void) fprintf(vis_stderr, "   -h \tprint the command usage\n");
00297   (void) fprintf(vis_stderr, "   -m \tminimum length of counterexample to be checked (default is 0)\n");  
00298   (void) fprintf(vis_stderr, "   -k \tmaximum length of counterexample to be checked (default is 1)\n");
00299   (void) fprintf(vis_stderr, "   -s \tincrementing value of counterexample length (default is 1)\n");
00300   (void) fprintf(vis_stderr, "   -r \tUse check for termination at each inductive_step to check if the property passes (default is 0).\n");
00301   (void) fprintf(vis_stderr, "   -e \tUse early termination to check if the property passes. Valid only with -r \n"); 
00302   (void) fprintf(vis_stderr, "   -F <fairness_file>\n");
00303   (void) fprintf(vis_stderr, "   -d <debug_level>\n");
00304   (void) fprintf(vis_stderr, "       debug_level = 0 => No debugging performed (Default)\n");
00305   (void) fprintf(vis_stderr, "       debug_level = 1 => Debugging with minimal output: generate counter-example if the LTL formula fails.\n");
00306   (void) fprintf(vis_stderr, "       debug_level = 2 => Debugging with full output in Aiger format: generate counter-example if the LTL formula fails.\n");
00307   (void) fprintf(vis_stderr, "   -O <debug_file>\n");
00308   (void) fprintf(vis_stderr, "   -i \tPrint input values in debug traces.\n");
00309   (void) fprintf(vis_stderr, "   -v <verbosity_level>\n");
00310   (void) fprintf(vis_stderr, "       verbosity_level = 0 => no feedback (Default)\n");
00311   (void) fprintf(vis_stderr, "       verbosity_level = 1 => code status\n");
00312   (void) fprintf(vis_stderr, "       verbosity_level = 2 => code status and CPU usage profile\n");
00313   (void) fprintf(vis_stderr, "   -t <period> time out period\n");
00314   (void) fprintf(vis_stderr, "   -E <encoding>\n");
00315   (void) fprintf(vis_stderr, "       encoding = 0 => Original BMC encoding (Default)\n");
00316   (void) fprintf(vis_stderr, "       encoding = 1 => SNF encoding\n");
00317   (void) fprintf(vis_stderr, "       encoding = 2 => Fixpoint encoding\n");
00318   /*
00319   (void) fprintf(vis_stderr, "       encoding = 3 => FNF encoding\n");
00320   */
00321   (void) fprintf(vis_stderr, "   -S <sat_solver>\n");
00322   (void) fprintf(vis_stderr, "       sat_solver = 0 => CirCUs (Default)\n");
00323   (void) fprintf(vis_stderr, "       sat_solver = 1 => cusp\n");
00324   (void) fprintf(vis_stderr, "   -C <clauses>\n");
00325   (void) fprintf(vis_stderr, "       clauses = 0 => Apply CirCUs on circuit (Default)\n");
00326   (void) fprintf(vis_stderr, "       clauses = 1 => Apply SAT solver on CNF (new)\n");
00327   (void) fprintf(vis_stderr, "       clauses = 2 => Apply SAT solver on CNF (old)\n");
00328   (void) fprintf(vis_stderr, "   -I <level>\n");
00329   (void) fprintf(vis_stderr, "       level = 1 => Trace Objective\n");
00330   (void) fprintf(vis_stderr, "       level = 2 => Distill\n");
00331   (void) fprintf(vis_stderr, "       level = 3 => Trace Objective + Distill\n");
00332   (void) fprintf(vis_stderr, "   -o <cnf_file> contains CNF of the counterexample\n");
00333   (void) fprintf(vis_stderr, "   <ltl_file> The input file containing LTL formulae to be checked.\n");
00334 
00335   BmcOptionFree(options);
00336   return NIL(BmcOption_t);
00337 }
00338 
00347 BmcOption_t *
00348 BmcOptionAlloc(void)
00349 {
00350   BmcOption_t *result = ALLOC(BmcOption_t, 1);
00351   
00352   if (!result){
00353     return result;
00354   }
00355   result->ltlFile = NIL(FILE);
00356   result->fairFile = NIL(FILE);
00357   result->cnfFileName = NIL(char);
00358   result->minK = 0;
00359   result->maxK = 1;
00360   result->step = 1;
00361   result->timeOutPeriod  = 0;
00362   result->startTime = 0;
00363   result->verbosityLevel = BmcVerbosityNone_c;
00364   result->dbgLevel       = 0;
00365   result->inductiveStep  = 0;
00366   result->printInputs    = FALSE;
00367   result->satSolverError = FALSE;
00368   result->satInFile  = NIL(char);
00369   result->satOutFile = NIL(char);
00370   result->incremental = 0;
00371   result->earlyTermination = 0;
00372   result->satSolver = CirCUs;  /* default is 0 */
00373   result->clauses   = 0;  /* default is 0 */
00374   result->encoding  = 0;  /* default is 0 */
00375   return result;
00376 }
00377 
00386 void
00387 BmcOptionFree(
00388   BmcOption_t *result)
00389 {
00390   if (result->ltlFile != NIL(FILE)){
00391     fclose(result->ltlFile);
00392   }
00393   if (result->cnfFileName != NIL(char)){
00394     FREE(result->cnfFileName);
00395   } else if (result->satInFile != NIL(char)) {
00396     unlink(result->satInFile);
00397     FREE(result->satInFile);
00398   }
00399   if (result->fairFile != NIL(FILE)){
00400     fclose(result->fairFile);
00401   }
00402   if (result->satOutFile != NIL(char)) {
00403     unlink(result->satOutFile);
00404     FREE(result->satOutFile);
00405   }
00406   FREE(result);
00407 }
00408 
00418 char *
00419 BmcCreateTmpFile(void)
00420 {
00421 #if HAVE_MKSTEMP && HAVE_CLOSE  
00422   char   cnfFileName[] = "/tmp/vis.XXXXXX";
00423   int    fd;
00424 #else
00425   char   *cnfFileName;
00426   char   buffer[512];
00427 #endif
00428 
00429 #if HAVE_MKSTEMP && HAVE_CLOSE    
00430   fd = mkstemp(cnfFileName);
00431   if (fd == -1){
00432 #else
00433   cnfFileName = util_strsav(tmpnam(buffer));
00434   if (cnfFileName == NIL(char)){
00435 #endif       
00436     (void)fprintf(vis_stderr,"** bmc error: Can not create temporary file. ");
00437     (void)fprintf(vis_stderr,"Clean up /tmp and try again.\n");
00438     return NIL(char);
00439   }
00440 #if HAVE_MKSTEMP && HAVE_CLOSE
00441   close(fd);
00442 #endif   
00443   return util_strsav(cnfFileName);
00444 } /* createTmpFile() */
00445 
00446 /*---------------------------------------------------------------------------*/
00447 /* Definition of static functions                                            */
00448 /*---------------------------------------------------------------------------*/
00449 
00450 
00601 static int
00602 CommandBmc(
00603   Hrc_Manager_t ** hmgr,
00604   int              argc,
00605   char          ** argv)
00606 {
00607   Ntk_Network_t     *network;
00608   BmcOption_t       *options;
00609   int               i;
00610   array_t           *formulaArray;
00611   array_t           *LTLformulaArray;
00612   bAig_Manager_t    *manager;
00613   array_t           *constraintArray = NIL(array_t);
00614 
00615   /*
00616    * Parse command line options.
00617    */
00618   if ((options = ParseBmcOptions(argc, argv)) == NIL(BmcOption_t)) {
00619       return 1;
00620   }
00621   /*
00622    * Read the network
00623    */
00624   network = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
00625   if (network == NIL(Ntk_Network_t)) {
00626     (void) fprintf(vis_stdout, "** bmc error: No network\n");
00627     BmcOptionFree(options);
00628     return 1;
00629   }
00630   manager = Ntk_NetworkReadMAigManager(network);
00631   if (manager == NIL(mAig_Manager_t)) {
00632     (void) fprintf(vis_stdout, "** bmc error: run build_partition_maigs command first\n");
00633     BmcOptionFree(options);
00634     return 1;
00635   }
00636   /*
00637     We need the bdd when building the transition relation of the automaton
00638   */
00639   if(options->inductiveStep !=0){
00640     Fsm_Fsm_t *designFsm = NIL(Fsm_Fsm_t);
00641  
00642     designFsm = Fsm_HrcManagerReadCurrentFsm(*hmgr);
00643     if (designFsm == NIL(Fsm_Fsm_t)) {
00644       return 1;
00645     }
00646   }
00647   /* time out */
00648   if (options->timeOutPeriod > 0) {
00649     /* Set the static variables used by the signal handler. */
00650     bmcTimeOut = options->timeOutPeriod;
00651     alarmLapTime = options->startTime = util_cpu_ctime();
00652     (void) signal(SIGALRM, (void(*)(int))TimeOutHandle);
00653     (void) alarm(options->timeOutPeriod);
00654     if (setjmp(timeOutEnv) > 0) {
00655       (void) fprintf(vis_stdout,
00656                      "\n# BMC: timeout occurred after %d seconds.\n",
00657                      options->timeOutPeriod);
00658       (void) fprintf(vis_stdout, "# BMC: data may be corrupted.\n");
00659       BmcOptionFree(options);
00660       alarm(0);
00661       return 1;
00662     }
00663   }
00664   formulaArray  = Ctlsp_FileParseFormulaArray(options->ltlFile);
00665   if (formulaArray == NIL(array_t)) {
00666     (void) fprintf(vis_stderr,
00667                    "** bmc error: error in parsing CTL* Fromula from file\n");
00668     BmcOptionFree(options);
00669     return 1;
00670   }
00671   if (array_n(formulaArray) == 0) {
00672     (void) fprintf(vis_stderr, "** bmc error: No formula in file\n");
00673     BmcOptionFree(options);
00674     Ctlsp_FormulaArrayFree(formulaArray);
00675     return 1;
00676   }
00677   LTLformulaArray = Ctlsp_FormulaArrayConvertToLTL(formulaArray);
00678   Ctlsp_FormulaArrayFree(formulaArray);
00679   if (LTLformulaArray ==  NIL(array_t)){
00680     (void) fprintf(vis_stdout, "** bmc error: Invalid LTL formula\n");
00681     BmcOptionFree(options);
00682     return 1;
00683   }
00684   if (options->fairFile != NIL(FILE)) {
00685     constraintArray = BmcReadFairnessConstraints(options->fairFile);
00686     if(constraintArray == NIL(array_t)){
00687       Ctlsp_FormulaArrayFree(LTLformulaArray);
00688       BmcOptionFree(options);
00689       return 1;
00690     }
00691     if(!Ctlsp_LtlFormulaArrayIsPropositional(constraintArray)){
00692       Ctlsp_FormulaArrayAddLtlFairnessConstraints(LTLformulaArray,
00693                                                   constraintArray);
00694       Ctlsp_FormulaArrayFree(constraintArray);
00695       constraintArray = NIL(array_t);
00696     }
00697   }
00698   /*
00699     Call a proper BMC function based on LTL formula.
00700   */
00701   for (i = 0; i < array_n(LTLformulaArray); i++) { 
00702     Ctlsp_Formula_t *ltlFormula     = array_fetch(Ctlsp_Formula_t *,
00703                                                   LTLformulaArray, i);
00704     
00705     DispatchBmcCommand(network, ltlFormula, constraintArray, options);
00706   }
00707   /*
00708     Free used memeory
00709   */
00710   if (constraintArray != NIL(array_t)){
00711     Ctlsp_FormulaArrayFree(constraintArray);
00712   }
00713   Ctlsp_FormulaArrayFree(LTLformulaArray);
00714   BmcOptionFree(options);
00715   fflush(vis_stdout);
00716   fflush(vis_stderr);
00717   alarm(0);
00718   return 0;
00719 
00720 }/* CommandBmc() */
00721 
00734 static void
00735 TimeOutHandle(void)
00736 {
00737   int seconds = (int) ((util_cpu_ctime() - alarmLapTime) / 1000);
00738 
00739   if (seconds < bmcTimeOut) {
00740     unsigned slack = (unsigned) (bmcTimeOut - seconds);
00741     (void) signal(SIGALRM, (void(*)(int)) TimeOutHandle);
00742     (void) alarm(slack);
00743   } else {
00744     longjmp(timeOutEnv, 1);
00745   }
00746 } /* TimeOutHandle */
00747 
00748 
00765 static void
00766 DispatchBmcCommand(
00767   Ntk_Network_t   *network,
00768   Ctlsp_Formula_t *ltlFormula,
00769   array_t         *constraintArray,
00770   BmcOption_t     *options)
00771 {
00772   Ctlsp_Formula_t *negLtlFormula = Ctlsp_LtllFormulaNegate(ltlFormula);
00773   st_table        *CoiTable      = st_init_table(st_ptrcmp, st_ptrhash);
00774 
00775   assert(ltlFormula != NIL(Ctlsp_Formula_t));
00776   assert(network != NIL(Ntk_Network_t));
00777  
00778   /*
00779     print out the given LTL formula
00780   */
00781   fprintf(vis_stdout, "Formula: ");
00782   Ctlsp_FormulaPrint(vis_stdout, ltlFormula);
00783   fprintf(vis_stdout, "\n");
00784   if (options->verbosityLevel >= BmcVerbosityMax_c){
00785     fprintf(vis_stdout, "Negated formula: ");
00786     Ctlsp_FormulaPrint(vis_stdout, negLtlFormula);
00787     fprintf(vis_stdout, "\n");
00788   }
00789   /*
00790     Compute the cone of influence of the LTL formula
00791   */
00792   BmcGetCoiForLtlFormula(network, negLtlFormula, CoiTable);
00793 
00794   if(options->clauses == 2){
00795     /*
00796       Generate clauses for each time frame.  This is the old way of generating
00797       clauses in BMC.
00798     */
00799     if (constraintArray != NIL(array_t)){
00800       BmcLtlVerifyGeneralLtl(network, negLtlFormula, CoiTable,
00801                              constraintArray, options);
00802     } else /*
00803              If the LTL formula is propositional.
00804            */
00805       if(Ctlsp_isPropositionalFormula(negLtlFormula)){
00806         BmcLtlVerifyProp(network, negLtlFormula, CoiTable, options);
00807       } else /*
00808                If the LTL formula is of type G(p) (its negation is
00809                of type F(q)), where p and q are propositional.
00810              */
00811         if(Ctlsp_LtlFormulaIsFp(negLtlFormula)){
00812           BmcLtlVerifyGp(network, negLtlFormula, CoiTable, options);
00813         } else /*
00814                  If the LTL formula is of type F(p) (its negation is
00815                  of type G(q)), where p and q are propositional.
00816                */
00817           if (Ctlsp_LtlFormulaIsGp(negLtlFormula)){
00818             BmcLtlVerifyFp(network, negLtlFormula, CoiTable, options);
00819           } else /*
00820                    If the depth of the LTL formula (the maximum level
00821                    of nesting temporal operators) = 1
00822                  */
00823             /*
00824             if (Ctlsp_LtlFormulaDepth(negLtlFormula) == 1){
00825               BmcLtlVerifyUnitDepth(network, negLtlFormula, CoiTable, options);
00826             } else
00827             */
00828               /* 
00829                  If the LTL formula is of type FG(p) (its negation is
00830                  of type GF(q)), where p and q are propositional.
00831               */
00832               if(Ctlsp_LtlFormulaIsGFp(negLtlFormula)){
00833                 BmcLtlVerifyFGp(network, negLtlFormula, CoiTable, options);
00834               } else
00835                 /*
00836                   All other LTL formulae
00837                 */
00838                 BmcLtlVerifyGeneralLtl(network, negLtlFormula, CoiTable,
00839                                        NIL(array_t), options);
00840   } else {
00841     /*
00842      Build AIG for each time frame.
00843      */
00844     if (constraintArray != NIL(array_t)){
00845       if(options->encoding == 0){
00846        BmcCirCUsLtlVerifyGeneralLtl(network, negLtlFormula,
00847                                     CoiTable,
00848                                    constraintArray, options, 0);
00849       } else 
00850         if(options->encoding == 1){
00851           BmcCirCUsLtlVerifyGeneralLtl(network, negLtlFormula,
00852                                           CoiTable,
00853                                           constraintArray, options, 1);
00854         } else 
00855           if(options->encoding == 2){
00856             BmcCirCUsLtlVerifyGeneralLtlFixPoint(network, negLtlFormula,
00857                                                  CoiTable,
00858                                                  constraintArray, options);
00859           }
00860     } else
00861       /*
00862         If the LTL formula is propositional.
00863       */
00864       if(Ctlsp_isPropositionalFormula(negLtlFormula)){
00865         BmcCirCUsLtlVerifyProp(network, negLtlFormula, CoiTable, options);
00866       } else
00867         /*
00868           If the LTL formula is of type G(p) (its negation is
00869           of type F(q)), where p and q are propositional.
00870         */
00871         if(Ctlsp_LtlFormulaIsFp(negLtlFormula)){
00872           BmcCirCUsLtlVerifyGp(network, negLtlFormula, CoiTable, options);
00873         } else
00874           /*
00875             If the LTL formula is of type F(p) (its negation is
00876             of type G(q)), where p and q are propositional.
00877           */
00878           if (Ctlsp_LtlFormulaIsGp(negLtlFormula)){
00879             BmcCirCUsLtlVerifyFp(network, negLtlFormula, CoiTable, options);
00880           } else
00881             /*
00882               If the depth of the LTL formula (the maximum level
00883               of nesting temporal operators) = 1
00884               
00885               if (Ctlsp_LtlFormulaDepth(negLtlFormula) == 1){
00886               BmcLtlVerifyUnitDepth(network, negLtlFormula, CoiTable, options);
00887               } else
00888                
00889               If the LTL formula is of type FG(p) (its negation is
00890               of type GF(q)), where p and q are propositional.
00891             */
00892             if(Ctlsp_LtlFormulaIsGFp(negLtlFormula)){
00893               BmcCirCUsLtlVerifyFGp(network, negLtlFormula, CoiTable, options);
00894             } else
00895               if(Ctlsp_LtlFormulaTestIsSyntacticallyCoSafe(negLtlFormula) ||
00896                  (Ltl_AutomatonGetStrength(BmcAutLtlToAutomaton(network,ltlFormula)) == 0))
00897                 {
00898                   BmcCirCUsLtlCheckSafety(network, negLtlFormula, options, CoiTable);
00899                 }
00900               else {
00901                 /*
00902                   All other LTL formulae
00903                 */
00904                 if(options->encoding == 0){
00905                   BmcCirCUsLtlVerifyGeneralLtl(network, negLtlFormula,
00906                                                CoiTable,
00907                                                NIL(array_t), options, 0);
00908                 } else 
00909                   if(options->encoding == 1){
00910                     BmcCirCUsLtlVerifyGeneralLtl(network, negLtlFormula,
00911                                                     CoiTable,
00912                                                     NIL(array_t), options, 1);
00913                   } else 
00914                     if(options->encoding == 2){
00915                       BmcCirCUsLtlVerifyGeneralLtlFixPoint(network, negLtlFormula,
00916                                                  CoiTable,
00917                                                            NIL(array_t), options);
00918                     }
00919               } 
00920   }
00921   
00922   st_free_table(CoiTable);
00923   Ctlsp_FormulaFree(negLtlFormula);
00924 } /* DispatchBmcCommand() */
00925 
00926 
00976 static int
00977 CommandCnfSat(
00978   Hrc_Manager_t ** hmgr,
00979   int  argc,
00980   char ** argv)
00981 {
00982   satOption_t *option;
00983   char *filename, c;
00984   char *forcedAssignFilename;
00985   int timeOutPeriod, i;
00986 
00987   option = sat_InitOption();
00988   timeOutPeriod = -1;
00989   forcedAssignFilename = 0;
00990   util_getopt_reset();
00991   while ((c = util_getopt(argc, argv, "a:bf:ht:v:c:")) != EOF) {
00992     switch(c) {
00993       case 'h':
00994         goto usage;
00995       case 'b' :
00996         option->BDDMonolithic = 1;
00997         break;
00998       case 'f' :
00999         option->outFilename = strdup(util_optarg);
01000         break;
01001       case 'a' :
01002         forcedAssignFilename = strdup(util_optarg);
01003         break;
01004       case 't' :
01005         timeOutPeriod = atoi(util_optarg);
01006         break;
01007       case 'v':
01008         for (i = 0; i < (int)(strlen(util_optarg)); i++) {
01009           if (!isdigit((int)util_optarg[i])) {
01010             goto usage;
01011           }
01012         }
01013         option->verbose = (Bmc_VerbosityLevel) atoi(util_optarg);
01014         break;
01015 
01016         //Bing: for unsat core
01017       case 'c':
01018         option->coreGeneration = 1;
01019         option->unsatCoreFileName = strdup(util_optarg);
01020         option->minimizeConflictClause = 0;
01021         option->clauseDeletionHeuristic = 0;
01022         break;
01023       default:
01024         goto usage;
01025     }
01026   }
01027 
01028   if (argc - util_optind == 0) {
01029     (void) fprintf(vis_stderr, "** ERROR : file containing cnf file not provided\n");
01030     goto usage;
01031   }
01032   else if (argc - util_optind > 1) {
01033     (void) fprintf(vis_stderr, "** ERROR : too many arguments\n");
01034     goto usage;
01035   }
01036   filename = util_strsav(argv[util_optind]);
01037 
01038   if(forcedAssignFilename)
01039     option->forcedAssignArr = sat_ReadForcedAssignment(forcedAssignFilename);
01040 
01041   if (timeOutPeriod > 0) {
01042     bmcTimeOut = timeOutPeriod;
01043     alarmLapTime = util_cpu_ctime();
01044     (void) signal(SIGALRM, (void(*)(int))TimeOutHandle);
01045     (void) alarm(timeOutPeriod);
01046     if (setjmp(timeOutEnv) > 0) {
01047       (void) fprintf(vis_stderr,
01048                 "** ERROR : timeout occurred after %d seconds.\n", timeOutPeriod);
01049       alarm(0);
01050       return 1;
01051     }
01052   }
01053 
01054   sat_CNFMain(option, filename);
01055 
01056   return 0;
01057 
01058   usage:
01059   (void) fprintf(vis_stderr, "usage: cnf_sat [-h] [-v verboseLevel] [-t timeout] <cnf_file>\n");
01060   (void) fprintf(vis_stderr, "   -h \tprint the command usage\n");
01061   (void) fprintf(vis_stderr, "   -a <filename> \tto make forced assignment\n");
01062   (void) fprintf(vis_stderr, "   -f <filename> \twrite log to the file\n");
01063   (void) fprintf(vis_stderr, "   -b \tuse BDD based method\n");
01064   (void) fprintf(vis_stderr, "   -v <verbosity_level>\n");
01065   (void) fprintf(vis_stderr, "   -t <period> time out period\n");
01066   (void) fprintf(vis_stderr, "   -c <filename> UNSAT core generation\n");
01067   (void) fprintf(vis_stderr, "   <cnf_file> CNF file to be checked.\n");
01068   return 1;
01069 }
01070 
01071 
01072 #if 0
01073 
01185 int
01186 CommandBddSat(
01187   Hrc_Manager_t ** hmgr,
01188   int              argc,
01189   char          ** argv)
01190 {
01191   Ntk_Network_t     *network;
01192   BmcOption_t       *options;
01193   array_t           *formulaArray;
01194   bAig_Manager_t    *mAigManager;
01195   Fsm_Fsm_t         *fsm;
01196   mdd_manager       *mddManager;
01197   int               startTime;
01198 
01199 
01200   /*
01201    * Parse command line options.
01202    */
01203   if ((options = ParseBmcOptions(argc, argv)) == NIL(BmcOption_t)) {
01204       return 1;
01205   }
01206   /* Read the network */
01207   network = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
01208   if (network == NIL(Ntk_Network_t)) {
01209     (void) fprintf(vis_stdout, "** bdd_sat error: No network\n");
01210     BmcOptionFree(options);
01211     return 1;
01212   }
01213   /* read fsm */
01214   fsm = Fsm_NetworkReadOrCreateFsm(network);
01215   if (fsm == NIL(Fsm_Fsm_t)) {
01216     (void) fprintf(vis_stdout, "** bdd_sat error: Can't read or create fsm\n");
01217     BmcOptionFree(options);
01218     return 1;
01219   }
01220   mddManager = Fsm_FsmReadMddManager(fsm); /* mdd manager */
01221   
01222   mAigManager = Ntk_NetworkReadMAigManager(network);
01223   if (mAigManager == NIL(mAig_Manager_t)) {
01224     (void) fprintf(vis_stdout, "** bdd_sat error: run build_partition_maigs command first\n");
01225     BmcOptionFree(options);
01226     return 1;
01227   }
01228   formulaArray = Ctlsp_FileParseFormulaArray(options->ltlFile);
01229   if (formulaArray == NIL(array_t)) {
01230     (void) fprintf(vis_stderr,
01231                    "** bdd_sat error: Error in parsing CTL* Fromula from file\n");
01232     BmcOptionFree(options);
01233     return 1;
01234   }
01235   if (array_n(formulaArray) == 0) {
01236     (void) fprintf(vis_stderr, "** bdd_sat error: No formula in file\n");
01237     BmcOptionFree(options);
01238     array_free(formulaArray);
01239     return 1;
01240   }
01241   /* time out */
01242   if (options->timeOutPeriod > 0) {
01243     /* Set the static variables used by the signal handler. */
01244     bmcTimeOut = options->timeOutPeriod;
01245     alarmLapTime = options->startTime = util_cpu_ctime();
01246     (void) signal(SIGALRM, (void(*)(int))TimeOutHandle);
01247     (void) alarm(options->timeOutPeriod);
01248     if (setjmp(timeOutEnv) > 0) {
01249       (void) fprintf(vis_stdout,
01250                      "\n# bdd_sat: timeout occurred after %d seconds.\n",
01251                      options->timeOutPeriod);
01252       (void) fprintf(vis_stdout, "# bdd_sat: data may be corrupted.\n");
01253       BmcOptionFree(options);
01254       alarm(0);
01255       return 1;
01256     }
01257   }
01258   /* bdd and sat to model check the LTL property.*/
01259   BmcBddSat(network, formulaArray, options);
01260 
01261   Ctlsp_FormulaArrayFree(formulaArray);
01262   fflush(vis_stdout);
01263   fflush(vis_stderr);
01264   BmcOptionFree(options);
01265   alarm(0);
01266   return 0; /* normal exit */
01267 }/* CommandBddSat() */
01268 #endif