int main(int argc, char* argv[]){ // Test procedure if(argc > 1 && strcmp(argv[1], "--test") == 0) return test(argc-1, argv+1); // Commandline arguments bool listformulas = false; char* model = NULL; char* queryname = NULL; char* queryfile = NULL; // Parse command line arguments for(int i = 1; i < argc; i++){ if(strcmp(argv[i], "--model") == 0){ model = argv[++i]; }else if(strcmp(argv[i], "--query") == 0){ queryname = argv[++i]; }else if(strcmp(argv[i], "--query-file") == 0){ queryfile = argv[++i]; }else if(strcmp(argv[i], "--list-queries") == 0){ listformulas = true; } } // Validate command line arguments if(!model && !listformulas){ fprintf(stderr, "Argument Error: Model must be provided using --model\n"); return ErrorCode; } if(!queryname && !listformulas){ fprintf(stderr, "Argument Error: Query name must be provided using --query\n"); return ErrorCode; } if(!queryfile){ fprintf(stderr, "Argument Error: Query file must be provided using --query-file\n"); return ErrorCode; } //----------------------- Queries -----------------------// //Condition to check Condition* query = NULL; bool isInvariant = false; //Parse query file, begin scope to release memory from the stack { map<string, SUMoQuery> queries; // Load formulas ifstream formulafile(queryfile, ifstream::in); if(!formulafile){ fprintf(stderr, "Argument Error: Formula file \"%s\" couldn't be opened\n", queryfile); return ErrorCode; } // Parse queries into map while(!formulafile.eof()){ string queryString; getline(formulafile, queryString); if(queryString == "") continue; //Parse queries SUMoQuery q = ParseSUMoQuery(queryString); if(!q.query){ fprintf(stderr, "Argument Error: Failed to parse query \"%s\" in file \"%s\"", queryString.c_str(), queryfile); return ErrorCode; } queries[q.name] = q; } formulafile.close(); // List possible formulas, then terminate if(listformulas){ typedef map<string, SUMoQuery>::iterator iter; for(iter it = queries.begin(); it != queries.end(); it++){ fprintf(stdout, "%s\n", (*it).second.name.c_str()); } return SuccessCode; } // Assign queries and invariant string formula(queryname); query = queries[formula].query; isInvariant = queries[formula].isInvariant; //Cleanup typedef map<string, SUMoQuery>::iterator iter; for(iter it = queries.begin(); it != queries.end(); it++){ if((*it).first != formula) delete (*it).second.query; } } //----------------------- Models -----------------------// //Load the model, begin scope to release memory from the stack PetriNet* net = NULL; MarkVal* m0 = NULL; VarVal* v0 = NULL; { //Load the model ifstream modelfile(model, ifstream::in); if(!modelfile){ fprintf(stderr, "Argument Error: Model file \"%s\" couldn't be opened\n", model); return ErrorCode; } //Read everything stringstream buffer; buffer << modelfile.rdbuf(); //Parse and build the petri net PetriNetBuilder builder(false); PNMLParser parser; parser.parse(buffer.str(), &builder); parser.makePetriNet(); //Build the petri net net = builder.makePetriNet(); m0 = builder.makeInitialMarking(); v0 = builder.makeInitialAssignment(); // Close the file modelfile.close(); } //----------------------- Reachability -----------------------// //Begin reachability search, begin scope to release memory from the stack { //Fallback strategy int flags = DistanceContext::AndSum | DistanceContext::OrExtreme; BestFirstReachabilitySearch fallback((DistanceContext::DistanceStrategy)flags); //Linear Approximation LinearOverApprox strategy(&fallback); //Context analysis { AnalysisContext context(*net); query->analyze(context); for(size_t i = 0; i < context.errors().size(); i++){ fprintf(stderr, "Query Context Analysis Error: %s\n", context.errors()[i].toString().c_str()); } if(context.errors().size() > 0) return ErrorCode; } ReachabilityResult result = strategy.reachable(*net, m0, v0, query); //TODO: Double check technique print.. I don't really know what to put here string techniques("EXPLICIT HEURISTIC"); if(result.result() == ReachabilityResult::Satisfied){ string resultText = isInvariant ? "FALSE" : "TRUE"; fprintf(stdout, "FORMULA %s %s %s\n", queryname, resultText.c_str(), techniques.c_str()); return FailedCode; }else if(result.result() == ReachabilityResult::NotSatisfied){ string resultText = isInvariant ? "TRUE" : "FALSE"; fprintf(stdout, "FORMULA %s %s %s\n", queryname, resultText.c_str(), techniques.c_str()); return SuccessCode; } else { //Unknown. Could not compute. fprintf(stdout, "CANNOT_COMPUTE\n"); return UnknownCode; } } return UnknownCode; }