コード例 #1
0
ファイル: peter.cpp プロジェクト: jonasfj/PeTe
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;
}