VIS

src/abs/absCmd.c

Go to the documentation of this file.
00001 
00017 #include "absInt.h"
00018 
00019 static char rcsid[] UNUSED = "$Id: absCmd.c,v 1.37 2002/09/08 22:13:50 fabio Exp $";
00020 
00021 /*---------------------------------------------------------------------------*/
00022 /* Type declarations                                                         */
00023 /*---------------------------------------------------------------------------*/
00024 
00025 /*---------------------------------------------------------------------------*/
00026 /* Structure declarations                                                    */
00027 /*---------------------------------------------------------------------------*/
00028 
00029 /*---------------------------------------------------------------------------*/
00030 /* Macro declarations                                                        */
00031 /*---------------------------------------------------------------------------*/
00032 
00033 /*---------------------------------------------------------------------------*/
00034 /* Variable declarations                                                     */
00035 /*---------------------------------------------------------------------------*/
00036 static jmp_buf timeOutEnv;
00037 static int absTimeOut;
00038 static long alarmLap;
00039 
00042 /*---------------------------------------------------------------------------*/
00043 /* Static function prototypes                                                */
00044 /*---------------------------------------------------------------------------*/
00045 
00046 static int CommandAbsCtl(Hrc_Manager_t **hmgr, int argc, char **argv);
00047 static AbsOptions_t * ParseAbsCtlOptions(int argc, char **argv);
00048 static void TimeOutHandle(int sigType);
00049 
00053 /*---------------------------------------------------------------------------*/
00054 /* Definition of exported functions                                          */
00055 /*---------------------------------------------------------------------------*/
00056 
00057 
00065 void
00066 Abs_Init(void)
00067 {
00068   Cmd_CommandAdd("incremental_ctl_verification", CommandAbsCtl, 0);
00069 }
00070 
00071 
00079 void
00080 Abs_End(void)
00081 {
00082 }
00083 
00084 
00085 /*---------------------------------------------------------------------------*/
00086 /* Definition of internal functions                                          */
00087 /*---------------------------------------------------------------------------*/
00088 
00089 /*---------------------------------------------------------------------------*/
00090 /* Definition of static functions                                            */
00091 /*---------------------------------------------------------------------------*/
00263 static int
00264 CommandAbsCtl(
00265   Hrc_Manager_t **hmgr,
00266   int argc,
00267   char **argv)
00268 {
00269   AbsVerificationResult_t formulaResult;
00270   Abs_VerificationInfo_t  *absInfo;
00271   AbsVertexInfo_t         *formulaPtr;
00272   Ctlp_Formula_t          *ctlFormula;
00273   AbsOptions_t            *options;
00274   Ntk_Network_t           *network;
00275   array_t                 *ctlArray;
00276   array_t                 *existCtlArray;
00277   array_t                 *fairArray;
00278   array_t                 *existFairArray;
00279   array_t                 *graphArray;
00280   array_t                 *resultArray;
00281   FILE                    *formulaFile;
00282   boolean                 correctSemantics;
00283   Fsm_Fsm_t               *fsm;
00284   Fsm_Fairness_t          *fairness;
00285   long                    cpuTime;
00286   int                     status;
00287   int                     i;
00288   int                     numConjuncts;
00289 
00290   /* Initialize some variables */
00291   graphArray = NIL(array_t);
00292   resultArray = NIL(array_t);
00293   options = NIL(AbsOptions_t);
00294   ctlArray = NIL(array_t);
00295   existCtlArray = NIL(array_t);
00296   fairArray = NIL(array_t);
00297   existFairArray = NIL(array_t);
00298   absInfo = NIL(Abs_VerificationInfo_t);
00299 
00300   if (bdd_get_package_name() != CUDD) {
00301     fprintf(vis_stderr, "** abs error : incremental_ctl_verification ");
00302     fprintf(vis_stderr, "is currently supported by only CUDD.\n");
00303     status = 1;
00304     goto cleanup;
00305   }
00306 
00307   error_init();
00308 
00309   /* Parse the options */
00310   options = ParseAbsCtlOptions(argc, argv);
00311 
00312   /* Check if there has been any error parsing the options */
00313   if (!options) {
00314     status = 1;
00315     goto cleanup;
00316   }
00317 
00318   /* Obtain the network */
00319   network = Ntk_HrcManagerReadCurrentNetwork( *hmgr );
00320   if ( network == NIL( Ntk_Network_t)) {
00321     (void) fprintf(vis_stdout, "%s\n", error_string());
00322     error_init();
00323     status = 1;
00324     goto cleanup;
00325   }
00326 
00327   /* Open the file with the ctl formulas */
00328   formulaFile = Cmd_FileOpen(AbsOptionsReadFileName(options), "r", 
00329                              NIL(char *), 0);
00330   if (formulaFile == NIL(FILE)) {
00331     status = 1;
00332     goto cleanup;
00333   }
00334 
00335   /* Parse the formulas and close the file */
00336   ctlArray = Ctlp_FileParseFormulaArray(formulaFile);
00337   fclose(formulaFile);
00338 
00339   if (ctlArray == NIL(array_t)) {
00340     (void) fprintf(vis_stderr, 
00341                    "** abs error: Error while parsing CTL formulas\n");
00342     status = 1;
00343     goto cleanup;
00344   }
00345 
00346   /* Read the fairness constraints */
00347   fsm = Fsm_HrcManagerReadCurrentFsm(*hmgr);
00348   if (fsm != NIL(Fsm_Fsm_t)){
00349     fairness = Fsm_FsmReadFairnessConstraint(fsm);
00350     if (fairness != NIL(Fsm_Fairness_t)){
00351       fairArray = array_alloc(Ctlp_Formula_t *,0);
00352       numConjuncts = Fsm_FairnessReadNumConjunctsOfDisjunct(fairness, 0);
00353       for (i = 0; i < numConjuncts; i++) {
00354         ctlFormula = Fsm_FairnessReadFinallyInfFormula(fairness, 0, i);
00355         if ((Ctlp_FormulaReadType(ctlFormula) != Ctlp_TRUE_c) &&
00356             (Ctlp_FormulaReadType(ctlFormula) != Ctlp_FALSE_c)){
00357           array_insert_last(Ctlp_Formula_t *, fairArray, 
00358                             Ctlp_FormulaDup(ctlFormula));
00359         }
00360       }
00361       if (array_n(fairArray) == 0){
00362         array_free(fairArray);
00363         fairArray = NIL(array_t);
00364       }
00365     }
00366   }
00367 
00368   /* Verify that the formulas are semantically correct */
00369   correctSemantics = TRUE;
00370 
00371   /* Check the semantics of the temporal formulas */
00372   arrayForEachItem(Ctlp_Formula_t *, ctlArray, i, ctlFormula) {
00373     if (!Mc_FormulaStaticSemanticCheckOnNetwork(ctlFormula, network, FALSE)) {
00374       (void) fprintf(vis_stdout, 
00375                  "** abs error: Inconsistency detected in formula number %d.\n",
00376                      i);
00377       (void) fprintf(vis_stdout, "ABS: %s\n", error_string());
00378       error_init();
00379       correctSemantics = FALSE;
00380     }
00381   }
00382 
00383   /* Check the fairness constraints */
00384   if (fairArray != NIL(array_t)) {
00385     arrayForEachItem(Ctlp_Formula_t *, fairArray, i, ctlFormula) {
00386       if (!Mc_FormulaStaticSemanticCheckOnNetwork(ctlFormula, network, FALSE)) {
00387         (void) fprintf(vis_stdout, 
00388                        "** abs error: Inconsistency detected in fairness ");
00389         (void) fprintf(vis_stdout, "constraint number %d.\n", i);
00390         (void) fprintf(vis_stdout, "ABS: %s\n", error_string());
00391         error_init();
00392         correctSemantics = FALSE;
00393       }
00394     }
00395   }
00396 
00397   /* If there is any inconsistency, do not execute the command */
00398   if (!correctSemantics) {
00399     status = 1;
00400     goto cleanup;
00401   }
00402 
00403   /* Replace XORs and EQs with equivalent subtrees. We insist on having
00404    * only monotonic operators. */
00405   Ctlp_FormulaArrayMakeMonotonic(ctlArray);
00406   Ctlp_FormulaArrayMakeMonotonic(fairArray);
00407 
00408   /* Translate the ctl formulas and fairness constraints to existential form */
00409   existCtlArray = Ctlp_FormulaArrayConvertToExistentialFormTree(ctlArray);
00410   if (fairArray != NIL(array_t)) {
00411     existFairArray = Ctlp_FormulaArrayConvertToExistentialFormTree(fairArray);
00412   }
00413 
00414   /* Compute the information related to the system being verified */
00415   absInfo = Abs_VerificationComputeInfo(network);
00416   if (absInfo == NIL(Abs_VerificationInfo_t)) {
00417     (void) fprintf(vis_stdout, "** abs error: Error computing the information required ");
00418     (void) fprintf(vis_stdout, "for verification.\n");
00419     status = 1;
00420     goto cleanup;
00421   }
00422 
00423   /* Store the options */
00424   AbsVerificationInfoSetOptions(absInfo, options);
00425 
00426   /* Translate the array of CTL formulas to operational graphs */
00427   graphArray = AbsCtlFormulaArrayTranslate(absInfo, existCtlArray, 
00428                                            existFairArray);
00429 
00430   if (graphArray == NIL(array_t)) {
00431     (void) fprintf(vis_stderr, 
00432                    "** abs error: Error translating CTL formulas.\n");
00433     (void) fprintf(vis_stderr, "** abs error: Aborting command.\n");
00434     status = 1;
00435     goto cleanup;
00436   }
00437 
00438   /* Program the timeOut if pertinent */
00439   if (AbsOptionsReadTimeOut(options) > 0) {
00440     /* Set the static variables */
00441     absTimeOut = AbsOptionsReadTimeOut(options);
00442     alarmLap = util_cpu_time();
00443 
00444     /* Set the handler */
00445     (void) signal(SIGALRM, TimeOutHandle);
00446     (void) alarm(AbsOptionsReadTimeOut(options));
00447     
00448     /* Set the jump for the timeout */
00449     if (setjmp(timeOutEnv) > 0) {
00450       (void) fprintf(vis_stdout,
00451                      "# ABS: Timeout occurred after %7.1f CPU seconds\n",
00452                      (util_cpu_time() - alarmLap)/1000.0);
00453       (void) fprintf(vis_stdout, "# ABS: data may be corrupted.\n");
00454       alarm(0);
00455       return 1;
00456     }
00457   }
00458 
00459   /* Print the graph in DOT format */
00460   if (AbsOptionsReadVerbosity(options) & ABS_VB_PRDOT) {
00461       AbsVertexPrintDot(vis_stdout, graphArray);
00462   }
00463 
00464   /* Set the cpu-time lap */
00465   cpuTime = util_cpu_time();
00466 
00467   /* Verify every formula */
00468   resultArray = AbsFormulaArrayVerify(absInfo, graphArray);
00469 
00470   /* Print out the execution time*/
00471   (void) fprintf(vis_stdout, "ABS: Total Verification Time: %7.1f secs\n",
00472                  (util_cpu_time() - cpuTime)/1000.0);
00473   
00474   /* Print out the results */
00475   /* RB changed this to take into account multiple initial states in negtd
00476      formulas */
00477   arrayForEachItem(AbsVerificationResult_t, resultArray, i, formulaResult) {
00478     (void) fprintf(vis_stdout, "# ABS: formula ");
00479     switch (formulaResult) {
00480     case trueVerification_c:
00481       (void) fprintf(vis_stdout, "passed --- ");
00482       break;
00483     case falseVerification_c:
00484       (void) fprintf(vis_stdout, "failed --- ");
00485       break;
00486     case inconclusiveVerification_c:
00487       (void) fprintf(vis_stdout, "undecided --- ");
00488     }
00489     if (AbsOptionsReadNegateFormula(options))
00490       fprintf(vis_stdout, "NOT[ ");
00491     Ctlp_FormulaPrint(vis_stdout, 
00492                       array_fetch(Ctlp_Formula_t *, ctlArray, i));
00493     if (AbsOptionsReadNegateFormula(options))
00494       fprintf(vis_stdout, " ]\n");
00495     else
00496       fprintf(vis_stdout, "\n");
00497   }
00498   
00499   /* Print the stats if selected by command line option */
00500   if (AbsOptionsReadPrintStats(options)) {
00501     int i;
00502     
00503     AbsStatsPrintReport(vis_stdout, AbsVerificationInfoReadStats(absInfo));
00504     
00505     (void) fprintf(vis_stdout, "# ABS: -- Command Line Options --\n");
00506     (void) fprintf(vis_stdout, "# ABS: ");
00507     for (i=0; i<argc; i++) {
00508       (void) fprintf(vis_stdout, "%s ", argv[i]);
00509     }
00510     (void) fprintf(vis_stdout, "\n");
00511   }
00512   
00513   /* Disconnect the alarm */
00514   alarm(0);
00515   
00516   status = 0;
00517   
00518   /* Clean up the memory and return */
00519   cleanup:
00520   if (graphArray != NIL(array_t)) {
00521     arrayForEachItem(AbsVertexInfo_t *, graphArray, i, formulaPtr) {
00522       AbsVertexFree(AbsVerificationInfoReadCatalog(absInfo), formulaPtr,
00523                     NIL(AbsVertexInfo_t));
00524     }
00525     array_free(graphArray);
00526   }
00527   if (resultArray != NIL(array_t)) {
00528     array_free(resultArray);
00529   }
00530   if (options != NIL(AbsOptions_t)) {
00531     AbsOptionsFree(options);
00532   }
00533   if (ctlArray != NIL(array_t)) {
00534     Ctlp_FormulaArrayFree(ctlArray);
00535   }
00536   if (existCtlArray != NIL(array_t)) {
00537     Ctlp_FormulaArrayFree(existCtlArray);
00538   }
00539   if (fairArray != NIL(array_t)) {
00540     Ctlp_FormulaArrayFree(fairArray);
00541   }
00542   if (existFairArray != NIL(array_t)) {
00543     Ctlp_FormulaArrayFree(existFairArray);
00544   }
00545   if (absInfo != NIL(Abs_VerificationInfo_t)) {
00546     AbsVerificationInfoFree(absInfo);
00547   }
00548   
00549   return status;
00550 } /* End of CommandAbsCtl */
00551 
00562 static AbsOptions_t *
00563 ParseAbsCtlOptions(
00564   int argc,
00565   char **argv)
00566 {
00567   AbsOptions_t *result;
00568   char *fileName;
00569   boolean reachability;
00570   boolean envelope;
00571   boolean exact;
00572   boolean printStats;
00573   boolean minimizeIterate;
00574   boolean negateFormula;
00575   boolean partApprox;
00576   boolean DFlag, eFlag, nFlag, pFlag, sFlag, tFlag, vFlag, xFlag;
00577   long verbosity;
00578   int intVerbosity;
00579   int timeOut;
00580   int dcValue;
00581   int c;
00582   unsigned int i;
00583 
00584   /* Default Options */
00585   DFlag = eFlag = nFlag = pFlag = sFlag = tFlag = FALSE;
00586   vFlag = xFlag = FALSE;
00587   reachability = FALSE;
00588   envelope = FALSE;
00589   exact = FALSE;
00590   printStats = FALSE;
00591   minimizeIterate = FALSE;
00592   negateFormula = FALSE;
00593   partApprox = FALSE;
00594   verbosity = 0;
00595   intVerbosity = 0;
00596   timeOut = -1;
00597   dcValue = 0;
00598 
00599   util_getopt_reset();
00600   while ((c = util_getopt(argc, argv, "D:ehnpst:v:V:x")) != EOF) {
00601     switch(c) {
00602       case 'D':
00603         dcValue = atoi(util_optarg);
00604         if (DFlag || (dcValue < 0) || (dcValue > 2)) {
00605           goto usage;
00606         }
00607         if (dcValue > 0) {
00608           reachability = TRUE;
00609         }
00610         if (dcValue > 1) {
00611           minimizeIterate = TRUE;
00612         }
00613         DFlag = TRUE;
00614         break;
00615       case 'e':
00616         if (eFlag) {
00617           goto usage;
00618         }
00619         envelope = TRUE;
00620         eFlag = TRUE;
00621         break;
00622       case 'h':
00623         goto usage;
00624       case 'n':
00625         if (nFlag) {
00626           goto usage;
00627         }
00628         negateFormula = TRUE;
00629         nFlag = TRUE;
00630         break;
00631       case 'p':
00632         if (pFlag) {
00633           goto usage;
00634         }
00635         partApprox = TRUE;
00636         pFlag = TRUE;
00637         break;
00638       case 's':
00639         if (sFlag) {
00640           goto usage;
00641         }
00642         printStats = TRUE;
00643         sFlag = TRUE;
00644         break;
00645       case 't':
00646         if (tFlag) {
00647           goto usage;
00648         }
00649         timeOut = atoi(util_optarg);
00650         tFlag = TRUE;
00651         break;
00652       case 'v':
00653         if (vFlag) {
00654           goto usage;
00655         }
00656         intVerbosity =  atoi(util_optarg);
00657         if (intVerbosity == 1){
00658           verbosity = 131849;
00659         }else if (intVerbosity == 2){
00660           verbosity = 8388607;
00661         }else{
00662           verbosity = 0;
00663         }
00664         vFlag = TRUE;
00665         break;
00666       case 'V':
00667         if (vFlag) {
00668           goto usage;
00669         }
00670         for(i=0;i<strlen(util_optarg)-1;i++){
00671           if (util_optarg[i] != '0' && util_optarg[i] != '1'){
00672              goto usage;
00673           }
00674         }
00675         verbosity =  strtol(util_optarg, NIL(char *), 2);
00676         vFlag = TRUE;
00677         break;
00678       case 'x':
00679         if (xFlag) {
00680           goto usage;
00681         }
00682         exact = TRUE;
00683         xFlag = TRUE;
00684         break;
00685       default:
00686         goto usage;
00687     }
00688   }
00689 
00690   /* Check if there is still one parameter left */
00691   if (argc - util_optind != 1) {
00692     goto usage;
00693   }
00694 
00695   /* Obtain the filename from the end of the command line */
00696   fileName = util_strsav(argv[util_optind]);
00697   
00698   /* Store the options  */
00699   result = AbsOptionsInitialize();
00700   
00701   AbsOptionsSetVerbosity(result, verbosity);
00702   AbsOptionsSetTimeOut(result, timeOut);
00703   AbsOptionsSetReachability(result, reachability);
00704   AbsOptionsSetEnvelope(result, envelope);
00705   AbsOptionsSetFileName(result, fileName);
00706   AbsOptionsSetExact(result, exact);
00707   AbsOptionsSetPrintStats(result, printStats);
00708   AbsOptionsSetMinimizeIterate(result, minimizeIterate);
00709   AbsOptionsSetNegateFormula(result, negateFormula);
00710   AbsOptionsSetPartApprox(result, partApprox);
00711 
00712   return result;
00713 
00714  usage:
00715   fprintf(vis_stderr,"usage: incremental_ctl_verification [-D <number>] [-e] [-h] [-n] [-s]\n");
00716   fprintf(vis_stderr,"[-t <seconds>] [-v <number>] [-V <number>] [-x] <ctlfile>\n");
00717   fprintf(vis_stderr,"\n");
00718   fprintf(vis_stderr,"Command options:\n");
00719   fprintf(vis_stderr,"-D <number>\n");
00720   fprintf(vis_stderr,"   Specify extent to which don't cares are used to simplify\n");
00721   fprintf(vis_stderr,"   the MDDs.\n");
00722   fprintf(vis_stderr,"   0: No Don't Cares used.\n");
00723   fprintf(vis_stderr,"   1: Use reachability information to compute the don't-care\n");
00724   fprintf(vis_stderr,"     set. Reachability is performed by formula. This is different from\n");
00725   fprintf(vis_stderr,"     mc, where reachability is performed only once.\n");
00726   fprintf(vis_stderr,"   2: Use reachability information, and minimize the transition relation\n");
00727   fprintf(vis_stderr,"     with respect to the `frontier set' (aggresive minimization).\n");
00728   fprintf(vis_stderr,"-e\n");
00729   fprintf(vis_stderr,"   Compute the set of fair states (those satisfying the formula\n");
00730   fprintf(vis_stderr,"   EGfair TRUE) before the verification process and use the result\n");
00731   fprintf(vis_stderr,"   as care set.\n");
00732   fprintf(vis_stderr,"-h\n");
00733   fprintf(vis_stderr,"   Print the command usage.\n");
00734   fprintf(vis_stderr,"-n\n");
00735   fprintf(vis_stderr,"   Try to prove the negation of every formula\n");
00736   fprintf(vis_stderr,"-s\n");
00737   fprintf(vis_stderr,"   Print a summary of statistics after the verification.\n");
00738   fprintf(vis_stderr,"-t <secs>\n");
00739   fprintf(vis_stderr,"   Time in seconds allowed to spend in the verification.\n");
00740   fprintf(vis_stderr,"-v <number>\n");
00741   fprintf(vis_stderr,"   Specify verbosity level. Use 0 for no feedback (default), 1 for\n");
00742   fprintf(vis_stderr,"   more and 2 for maximum feedback. This option can not be used\n");
00743   fprintf(vis_stderr,"   in conjunction with -V.\n");
00744   fprintf(vis_stderr,"-V <number>\n");
00745   fprintf(vis_stderr,"   Mask specifying type of information to be printed out while\n");
00746   fprintf(vis_stderr,"   verifying the formulas. See the help page.\n");
00747   fprintf(vis_stderr,"-x\n");
00748   fprintf(vis_stderr,"   Perform the verification exactly. No approximation is done.\n");
00749   fprintf(vis_stderr,"<ctlfile>\n");
00750   fprintf(vis_stderr,"   File containing the CTL formulas to be verified.\n");
00751   return NIL(AbsOptions_t);
00752 } /* End of ParseAbsCtlOptions */
00753 
00766 static void
00767 TimeOutHandle(
00768   int sigType)
00769 {
00770   long seconds;
00771 
00772   seconds = (util_cpu_time() - alarmLap) / 1000;
00773   
00774   if (seconds < absTimeOut) {
00775     unsigned slack;
00776 
00777     slack = absTimeOut - seconds;
00778     (void) signal(SIGALRM, TimeOutHandle);
00779     (void) alarm(slack);
00780   }
00781   else {
00782     longjmp(timeOutEnv, 1);
00783   }
00784 } /* End of TimeOutHandle */