VIS
|
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 */