/**CFile*********************************************************************** FileName [ctlspCmd.c] PackageName [ctlsp] Synopsis [Command to read in a file containing CTL* formulas.] Author [Mohammad Awedh] Copyright [This file was created at the University of Colorado at Boulder. The University of Colorado at Boulder makes no warranty about the suitability of this software for any purpose. It is presented on an AS IS basis.] ******************************************************************************/ #include "ctlspInt.h" /**AutomaticStart*************************************************************/ /*---------------------------------------------------------------------------*/ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ static int CommandCtlspTest(Hrc_Manager_t ** hmgr, int argc, char ** argv); static int CommandLtlToSNF(Hrc_Manager_t ** hmgr, int argc, char ** argv); static int FormulaArrayCountSubformulae(array_t *formulaArray); static void FormulaVisitUnvisitedSubformulae(Ctlsp_Formula_t *formula, int *ptr); /**AutomaticEnd***************************************************************/ /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ /*---------------------------------------------------------------------------*/ /**Function******************************************************************** Synopsis [Initializes the CTL* parser package.] SideEffects [] SeeAlso [Ctlsp_End] ******************************************************************************/ void Ctlsp_Init(void) { Cmd_CommandAdd("_ctlsp_test", CommandCtlspTest, 0); Cmd_CommandAdd("ltl2snf", CommandLtlToSNF, 0); } /**Function******************************************************************** Synopsis [Ends the CTL* parser package.] SideEffects [] SeeAlso [Ctlsp_Init] ******************************************************************************/ void Ctlsp_End(void) { } /*---------------------------------------------------------------------------*/ /* Definition of internal functions */ /*---------------------------------------------------------------------------*/ /**Function******************************************************************** Synopsis [Sets the field states in every subformula of CTL* formula to NULL.] Description [The function sets the field states in every subformula of CTL* formula to NULL.] SideEffects [] ******************************************************************************/ void CtlspFormulaSetStatesToNULL( Ctlsp_Formula_t *formula) { if(formula!=NIL(Ctlsp_Formula_t)) { formula->states = NIL(mdd_t); if(formula->type != Ctlsp_ID_c) { CtlspFormulaSetStatesToNULL(formula->left); CtlspFormulaSetStatesToNULL(formula->right); } } } /*---------------------------------------------------------------------------*/ /* Definition of static functions */ /*---------------------------------------------------------------------------*/ /**Function******************************************************************** Synopsis [Implements the _ctlsp_test command.] Description [Implements the _ctlsp_test command. This command is only meant to test the CTL* command parser.] CommandName [_ctlsp_test] CommandSynopsis [test the CTL* parser] CommandArguments [\[-h\] <file_name>] CommandDescription [Test the CTL* parser. If the entire file of CTL* formulas is successfully parsed, then each formula is printed to stdout, followed by the equivalent existential normal form formula. The formulas read are not stored. For the input file containing:
 AG(foo=bar); 
the following is produced:
 original
  formula: AG(foo=bar) => equivalent existential formula: !(E(TRUE U
  !(foo=bar))) 
For the syntax of CTL formulas, refer to the VIS CTL and LTL syntax manual. Command options:

-h
Print the command usage.
] SideEffects [] ******************************************************************************/ static int CommandCtlspTest( Hrc_Manager_t ** hmgr, int argc, char ** argv) { int c; int i; FILE *fp; array_t *formulaArray; array_t *CtlformulaArray; array_t *LTLformulaArray; array_t *convertedArray; /* in DAG format */ /* * Parse command line options. */ util_getopt_reset(); while ((c = util_getopt(argc, argv, "h")) != EOF) { switch(c) { case 'h': goto usage; default: goto usage; } } /* * Open the ctl file. */ if (argc - util_optind == 0) { (void) fprintf(vis_stderr, "** CTL* error: ctl* file not provided\n"); goto usage; } else if (argc - util_optind > 1) { (void) fprintf(vis_stderr, "** CTL* error: too many arguments\n"); goto usage; } fp = Cmd_FileOpen(argv[util_optind], "r", NIL(char *), 0); if (fp == NIL(FILE)) { (void)fprintf(vis_stderr, "** CTL* error: Cannot open the file %s\n", argv[util_optind]); return 1; } /* * Parse the CTL* formulas in the file. */ formulaArray = Ctlsp_FileParseFormulaArray(fp); (void) fclose(fp); if (formulaArray == NIL(array_t)) { fflush(vis_stdout); fflush(vis_stderr); return 1; } convertedArray = Ctlsp_FormulaArrayConvertToDAG(formulaArray); /* array_free(formulaArray); */ /* * Print each original formula and its corresponding converted formula. */ for (i = 0; i < array_n(convertedArray); i++) { Ctlsp_Formula_t *formula; formula = array_fetch(Ctlsp_Formula_t *, convertedArray, i); (void) fprintf(vis_stdout, "original formula: "); Ctlsp_FormulaPrint(vis_stdout, formula); (void) fprintf(vis_stdout, " [CTL* "); if (Ctlsp_isCtlFormula(formula)){ (void) fprintf(vis_stdout, ",CTL "); } if (Ctlsp_isLtlFormula(formula)){ (void) fprintf(vis_stdout, ",LTL "); } (void) fprintf(vis_stdout, "]\n"); } (void)fprintf(vis_stdout, "No. of subformulae (including formulae) = %d\n", FormulaArrayCountSubformulae(convertedArray)); /* Converts array of CTL* formula to CTL */ CtlformulaArray = Ctlsp_FormulaArrayConvertToCTL(formulaArray); if (CtlformulaArray != NIL(array_t)){ for (i = 0; i < array_n(CtlformulaArray); i++) { Ctlp_Formula_t *newFormula; newFormula = array_fetch(Ctlp_Formula_t *, CtlformulaArray, i); (void) fprintf(vis_stdout, "CTL formula: "); Ctlp_FormulaPrint(vis_stdout, newFormula); (void) fprintf(vis_stdout, "\n"); } array_free(CtlformulaArray); } LTLformulaArray = Ctlsp_FormulaArrayConvertToLTL(formulaArray); if (LTLformulaArray != NIL(array_t)){ for (i = 0; i < array_n(LTLformulaArray); i++) { Ctlsp_Formula_t *newFormula; newFormula = array_fetch(Ctlsp_Formula_t *, LTLformulaArray, i); (void) fprintf(vis_stdout, "LTL formula: "); Ctlsp_FormulaPrint(vis_stdout, newFormula); (void) fprintf(vis_stdout, "\n"); } array_free(LTLformulaArray); } else { (void) fprintf(vis_stdout, "No LTL \n"); } array_free(formulaArray); Ctlsp_FormulaArrayFree(convertedArray); fflush(vis_stdout); fflush(vis_stderr); return 0; /* normal exit */ usage: (void) fprintf(vis_stderr, "usage: _ctlsp_test file [-h]\n"); (void) fprintf(vis_stderr, " -h print the command usage\n"); return 1; /* error exit */ } /**Function******************************************************************** Synopsis [Implements the ltl2snf command.] Description [Implements the ltl2snf command.] CommandName [ltl2snf] CommandSynopsis [Trnalate LTL formula into Separated Normal Form.] CommandArguments [\[-h\] <file_name>] CommandDescription [ Command options:

-f <ltl_file>
The input file containing LTL formulae.
-n
Negate the formulae.
-h
Print the command usage.
] SideEffects [] ******************************************************************************/ static int CommandLtlToSNF( Hrc_Manager_t ** hmgr, int argc, char ** argv) { int c, i; FILE *fp; array_t *formulaArray; array_t *LTLformulaArray; char *ltlFileName = (char *)0; int negateFormula = 0; /* * Parse command line options. */ util_getopt_reset(); while ((c = util_getopt(argc, argv, "hf:n")) != EOF) { switch(c) { case 'h': goto usage; case 'f': ltlFileName = util_strsav(util_optarg); break; case 'n': negateFormula = 1; break; default: goto usage; } } if (!ltlFileName){ (void) fprintf(vis_stderr, "** ltl2snf error: ltl file not provided\n"); goto usage; } fp = Cmd_FileOpen(ltlFileName, "r", NIL(char *), 0); FREE(ltlFileName); if (fp == NIL(FILE)) { (void) fprintf(vis_stdout, "** ltl2snf error: error in opening file %s\n", ltlFileName); return 1; } /* * Parse the CTL* formulas in the file. */ formulaArray = Ctlsp_FileParseFormulaArray(fp); (void) fclose(fp); if (formulaArray == NIL(array_t)) { fflush(vis_stdout); fflush(vis_stderr); return 1; } LTLformulaArray = Ctlsp_FormulaArrayConvertToLTL(formulaArray); if (LTLformulaArray != NIL(array_t)){ for (i = 0; i < array_n(LTLformulaArray); i++) { Ctlsp_Formula_t *newFormula; newFormula = array_fetch(Ctlsp_Formula_t *, LTLformulaArray, i); (void) fprintf(vis_stdout, "LTL formula: "); Ctlsp_FormulaPrint(vis_stdout, newFormula); (void) fprintf(vis_stdout, "\n"); if(negateFormula){ newFormula = Ctlsp_LtllFormulaNegate(newFormula); (void) fprintf(vis_stdout, "Negated LTL formula: "); Ctlsp_FormulaPrint(vis_stdout, newFormula); (void) fprintf(vis_stdout, "\n"); } printf("SNF \n"); Ctlsp_LtlTranslateIntoSNF(newFormula); } array_free(LTLformulaArray); } else { (void) fprintf(vis_stdout, "No LTL \n"); } array_free(formulaArray); fflush(vis_stdout); fflush(vis_stderr); return 0; /* normal exit */ usage: (void) fprintf(vis_stderr, "usage: ltl2snf <-f ltl_file> [-h]\n"); (void) fprintf(vis_stderr, " -f \n"); (void) fprintf(vis_stderr, " -n negate formula\n"); (void) fprintf(vis_stderr, " -h print the command usage\n"); return 1; /* error exit */ } /**Function******************************************************************** Synopsis [Counts the number of subformulae in formulaArray.] Description [The function counts the number of subformulae in formulaArray (including the formulae themselves) by traversing the DAG. It uses the field states in Ctlsp_Formula_t to mark the visited states.] SideEffects [The field states is set to 1.] ******************************************************************************/ static int FormulaArrayCountSubformulae( array_t *formulaArray) { int num, i; Ctlsp_Formula_t *formula; int count = 0; num = array_n(formulaArray); for(i=0; istates == NIL(mdd_t)) { (*ptr)++; formula->states = (mdd_t *) 1; if(formula->type != Ctlsp_ID_c) { FormulaVisitUnvisitedSubformulae(formula->left, ptr); FormulaVisitUnvisitedSubformulae(formula->right, ptr); } } } }