/** * Convert an LTL formula to a DRA. * @param ltl the LTL formula * @param options which operators are allowed * @return a shared_ptr to the DRA */ private DRA ltl2dra(LTLFormula ltl, BuchiAutomata buchiAutomata, LTL2DSTAR_Options options) { APSet ap_set = ltl.getAPSet(); LTLFormula ltl_pnf = ltl.toPNF(); if (options.allow_union && ltl_pnf.getRootNode().getType() == type_t.T_OR) { LTLFormula ltl_left = ltl_pnf.getSubFormula(ltl_pnf.getRootNode().getLeft()); LTLFormula ltl_right = ltl_pnf.getSubFormula(ltl_pnf.getRootNode().getRight()); LTL2DSTAR_Options rec_opt = options; rec_opt.recursion(); DRA dra_left = ltl2dra(ltl_left, buchiAutomata, rec_opt); DRA dra_right = ltl2dra(ltl_right, buchiAutomata, rec_opt); return(DRA.calculateUnion(dra_left, dra_right, _safra_opt.union_trueloop) as DRA); } if (options.safety) { LTLSafetyAutomata lsa = new LTLSafetyAutomata(); DRA safety_dra = lsa.ltl2dra(ltl, buchiAutomata); if (safety_dra != null) { return(safety_dra); } } DRA dra = new DRA(ap_set); NBA nba = LTL2NBA.ltl2nba(ltl_pnf, buchiAutomata); if (nba == null) { throw new Exception("Couldn't create NBA from LTL formula"); } NBA2DRA nba2dra = new NBA2DRA(_safra_opt); nba2dra.convert(nba, dra); if (options.optimizeAcceptance) { dra.optimizeAcceptanceCondition(); } if (options.bisim) { DRAOptimizations dra_optimizer = new DRAOptimizations(); dra = dra_optimizer.optimizeBisimulation(dra); } return(dra); }
/** * Convert an LTL formula to a DRA. * @param ltl the LTL formula * @param options which operators are allowed * @return a shared_ptr to the DRA */ private DRA ltl2dra(LTLFormula ltl, BuchiAutomata buchiAutomata, LTL2DSTAR_Options options) { APSet ap_set = ltl.getAPSet(); LTLFormula ltl_pnf = ltl.toPNF(); if (options.allow_union && ltl_pnf.getRootNode().getType() == type_t.T_OR) { LTLFormula ltl_left = ltl_pnf.getSubFormula(ltl_pnf.getRootNode().getLeft()); LTLFormula ltl_right = ltl_pnf.getSubFormula(ltl_pnf.getRootNode().getRight()); LTL2DSTAR_Options rec_opt = options; rec_opt.recursion(); DRA dra_left = ltl2dra(ltl_left, buchiAutomata, rec_opt); DRA dra_right = ltl2dra(ltl_right,buchiAutomata, rec_opt); return DRA.calculateUnion(dra_left, dra_right, _safra_opt.union_trueloop) as DRA; } if (options.safety) { LTLSafetyAutomata lsa = new LTLSafetyAutomata(); DRA safety_dra = lsa.ltl2dra(ltl, buchiAutomata); if (safety_dra != null) { return safety_dra; } } DRA dra = new DRA(ap_set); NBA nba = LTL2NBA.ltl2nba(ltl_pnf, buchiAutomata); if (nba == null) { throw new Exception("Couldn't create NBA from LTL formula"); } NBA2DRA nba2dra = new NBA2DRA(_safra_opt); nba2dra.convert(nba, dra); if (options.optimizeAcceptance) { dra.optimizeAcceptanceCondition(); } if (options.bisim) { DRAOptimizations dra_optimizer = new DRAOptimizations(); dra = dra_optimizer.optimizeBisimulation(dra); } return dra; }
/** * Convert an LTL formula to an NBA * @param ltl * @return a pointer to the created NBA (caller gets ownership). */ public static NBA ltl2nba(LTLFormula ltl, BuchiAutomata buchiAutomata) { // Create canonical APSet (with 'p0', 'p1', ... as AP) //LTLFormula ltl_canonical = ltl.copy(); //APSet canonical_apset = ltl.getAPSet().createCanonical(); // ltl_canonical.switchAPSet(canonical_apset); //AnonymousTempFile spin_outfile; //std::vector<std::string> arguments; //arguments.push_back("-f"); //arguments.push_back(ltl_canonical->toStringInfix()); //arguments.insert(arguments.end(), _arguments.begin(),_arguments.end()); //const char *program_path=_path.c_str(); //RunProgram spin(program_path, // arguments, // false, // 0, // &spin_outfile, // 0); //int rv=spin.waitForTermination(); //if (rv==0) { // NBA_t *result_nba(new NBA_t(canonical_apset)); // FILE *f=spin_outfile.getInFILEStream(); // if (f==NULL) { //throw Exception(""); // } // int rc=nba_parser_promela::parse(f, result_nba); // fclose(f); // if (rc!=0) { //throw Exception("Couldn't parse PROMELA file!"); // } NBA result_nba = new NBA(ltl.getAPSet()); //////////////////////////////////////////////////////////// //todo: create the NBA from the BA // // //////////////////////////////////////////////////////////// NBABuilder builder = new NBABuilder(result_nba); //int current_state = 0; //bool current_state_valid=false; //foreach (string state in buchiAutomata.States) //{ // if (buchiAutomata.InitialStates.Contains(state)) // { // int current_state = builder.findOrAddState(state); // if (buchiAutomata.InitialStates.Contains(state)) // { // builder.setStartState(current_state); // } // } //} foreach (string state in buchiAutomata.States) { //if (!buchiAutomata.InitialStates.Contains(state)) { ////s.AppendLine(state); //if (current_state_valid) { // builder.addAdditionalNameToState(state, current_state); //} //else //{ int current_state = builder.findOrAddState(state); //std::string& label=$1; //if (label.find("accept") != std::string::npos) { if (state.EndsWith(Constants.ACCEPT_STATE)) { builder.setFinal(current_state); } //if (label.find("accept_all") != std::string ::npos) //{ // // dirty hack: accept_all + skip -> trueloop // builder.setFinal(current_state); // builder.addEdge(current_state, current_state, std::string ("t")); //} if (buchiAutomata.InitialStates.Contains(state)) { builder.setStartState(current_state); } //current_state_valid = true; //} } } //s.AppendLine("Transitions"); foreach (Transition transition in buchiAutomata.Transitions) { int from = builder.findOrAddState(transition.FromState); int to = builder.findOrAddState(transition.ToState); builder.addEdge(from, to, transition.labels); } // switch back to original APSet //result_nba.switchAPSet(ltl.getAPSet()); //todo: //construct the NBA here return result_nba; }
/** * Convert an LTL formula to an NBA * @param ltl * @return a pointer to the created NBA (caller gets ownership). */ public static NBA ltl2nba(LTLFormula ltl, BuchiAutomata buchiAutomata) { // Create canonical APSet (with 'p0', 'p1', ... as AP) //LTLFormula ltl_canonical = ltl.copy(); //APSet canonical_apset = ltl.getAPSet().createCanonical(); // ltl_canonical.switchAPSet(canonical_apset); //AnonymousTempFile spin_outfile; //std::vector<std::string> arguments; //arguments.push_back("-f"); //arguments.push_back(ltl_canonical->toStringInfix()); //arguments.insert(arguments.end(), _arguments.begin(),_arguments.end()); //const char *program_path=_path.c_str(); //RunProgram spin(program_path, // arguments, // false, // 0, // &spin_outfile, // 0); //int rv=spin.waitForTermination(); //if (rv==0) { // NBA_t *result_nba(new NBA_t(canonical_apset)); // FILE *f=spin_outfile.getInFILEStream(); // if (f==NULL) { //throw Exception(""); // } // int rc=nba_parser_promela::parse(f, result_nba); // fclose(f); // if (rc!=0) { //throw Exception("Couldn't parse PROMELA file!"); // } NBA result_nba = new NBA(ltl.getAPSet()); //////////////////////////////////////////////////////////// //todo: create the NBA from the BA // // //////////////////////////////////////////////////////////// NBABuilder builder = new NBABuilder(result_nba); //int current_state = 0; //bool current_state_valid=false; //foreach (string state in buchiAutomata.States) //{ // if (buchiAutomata.InitialStates.Contains(state)) // { // int current_state = builder.findOrAddState(state); // if (buchiAutomata.InitialStates.Contains(state)) // { // builder.setStartState(current_state); // } // } //} foreach (string state in buchiAutomata.States) { //if (!buchiAutomata.InitialStates.Contains(state)) { ////s.AppendLine(state); //if (current_state_valid) { // builder.addAdditionalNameToState(state, current_state); //} //else //{ int current_state = builder.findOrAddState(state); //std::string& label=$1; //if (label.find("accept") != std::string::npos) { if (state.EndsWith(Constants.ACCEPT_STATE)) { builder.setFinal(current_state); } //if (label.find("accept_all") != std::string ::npos) //{ // // dirty hack: accept_all + skip -> trueloop // builder.setFinal(current_state); // builder.addEdge(current_state, current_state, std::string ("t")); //} if (buchiAutomata.InitialStates.Contains(state)) { builder.setStartState(current_state); } //current_state_valid = true; //} } } //s.AppendLine("Transitions"); foreach (Transition transition in buchiAutomata.Transitions) { int from = builder.findOrAddState(transition.FromState); int to = builder.findOrAddState(transition.ToState); builder.addEdge(from, to, transition.labels); } // switch back to original APSet //result_nba.switchAPSet(ltl.getAPSet()); //todo: //construct the NBA here return(result_nba); }