Example #1
0
/** Procedure for testing PeTe without Qt dependencies */
int test(int argc, char* argv[]){

	bool genRandState = false;
	bool listformulas = false;
	string queryname,
		   strategy,
		   filename,
		   queryString;

	for(int i = 1; i < argc; i++){
		if(strcmp(argv[i], "--query") == 0){
			queryname = argv[++i];
		}else if(strcmp(argv[i], "--strategies") == 0){
			std::vector<std::string> strats = ReachabilitySearchStrategy::listStrategies();
			for(size_t i = 0; i < strats.size(); i++)
				printf("%s\n",strats[i].c_str());
		}else if(strcmp(argv[i], "--literal-query") == 0){
			queryString = argv[++i];
		}else if(strcmp(argv[i],"--strategy") == 0){
			strategy = argv[++i];
		}else if(strcmp(argv[i], "--list-queries") == 0){
			listformulas = true;
		} else if(strcmp(argv[i],"--gen-query") == 0){
			genRandState = true;
		} else if(strcmp(argv[i],"--help") == 0){
			printf("Usage: pete [net] [--query <query>] [--query-sumo <query>] [--help] [--strategies] [--strategy <strategy>]\n");
		} else
			filename = argv[i];
	}

	PetriNet* net = NULL;
	MarkVal* m0 = NULL;
	VarVal* v0 = NULL;
	std::vector<PNMLParser::Query> queries;
	{
		//Load the model
		ifstream modelfile(filename, ifstream::in);
		if(!modelfile){
			fprintf(stderr, "Argument Error: Model file \"%s\" couldn't be opened\n", filename.c_str());
			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();
		queries = parser.getQueries();

		// Close the file
		modelfile.close();
	}

	// List queries in file
	if(listformulas){
		for(std::vector<PNMLParser::Query>::iterator it = queries.begin(); it != queries.end(); it++)
			printf("%s\n",(*it).name.c_str());
		return 0;
	}

	// If generate random state
	if(genRandState){
		//RandomDFS dfs;
		//dfs.reachable(*net, m0, v0, NULL);
		RandomQueryGenerator rng;
		cout<<rng.gen(*net, m0, v0)<<"\n";
		return 0;
	}


	// Find the query
	if(queryString.empty()){
		for(std::vector<PNMLParser::Query>::iterator it = queries.begin(); it != queries.end(); it++){
			if((*it).name == queryname){
				queryString = (*it).text;
				break;
			}
		}
	}

	// Parse query and analyze
	PQL::Condition* query = PQL::ParseQuery(queryString);
	AnalysisContext context(*net);
	query->analyze(context);

	//Load up reachability engine
	ReachabilitySearchStrategy* strat;
	strat = ReachabilitySearchStrategy::createStrategy(strategy);
	ReachabilityResult result;

	clock_t startClock = clock();
	result = strat->reachable(*net, m0, v0, query);
	float finishTime = ((float)(clock() - startClock)) / (float)CLOCKS_PER_SEC;

	delete query;
	query = NULL;
	delete strat;
	strat = NULL;

	// Trim file name incase of alternate folder
	string name;
	bool chop = false;
	int index = 0;
	for(int i = 0; i < filename.size(); i++){
		if(filename.at(i) == '/'){
			chop = true;
			index = i;
		}
	}
	if(chop)
		name = filename.substr(index+1,filename.length()-1);

	delete query;
	query = NULL;
	delete strat;
	strat = NULL;
	//Print result
	std::string r;
	if(result.result() == ReachabilityResult::Satisfied)
		r = "Satisfied";
	else if(result.result() == ReachabilityResult::NotSatisfied)
		r = "Not satisfiable";
	else{
		r = "Unknown";
	}
	std::cout<<name
			 <<",\t"<<queryname
			 <<",\t"<<strategy
			 <<",\t"<<r
			 <<",\t"<<finishTime
			 <<",\t"<<result.expandedStates()
			 <<",\t"<<result.exploredStates()
			 <<",\t"<<result.pathLength()
			 <<std::endl;
	return result.result() == ReachabilityResult::Satisfied ? 0 : 1;
}
Example #2
0
bool ValidationBuilder::validate(){
	//Check for duplicate identifiers
	set<string> reportedDuplicates;	//Use a set to avoid reporting them more than once
	//Check variable names
	for(size_t i = 0; i < _varNames.size(); i++){
		const string& id = _varNames[i];
		int count = countMatchingIds(id);
		assert(count >= 1);
		if(count > 1 && reportedDuplicates.count(id) == 0){
			reportedDuplicates.insert(id);
			_errors.push_back(ValidationError(id,
											  "The identifiers must be unique, \""
											  + id + "\" is shared by "
											  + int2string(count) + " entities"));
		}
	}
	//Check bool variable names
	for(size_t i = 0; i < _boolVarNames.size(); i++){
		const string& id = _boolVarNames[i];
		int count = countMatchingIds(id);
		assert(count >= 1);
		if(count > 1 && reportedDuplicates.count(id) == 0){
			reportedDuplicates.insert(id);
			_errors.push_back(ValidationError(id,
											  "The identifiers must be unique, \""
											  + id + "\" is shared by "
											  + int2string(count) + " entities"));
		}
	}
	//Check place names
	for(size_t i = 0; i < _placeNames.size(); i++){
		const string& id = _placeNames[i];
		int count = countMatchingIds(id);
		assert(count >= 1);
		if(count > 1 && reportedDuplicates.count(id) == 0){
			reportedDuplicates.insert(id);
			_errors.push_back(ValidationError(id,
											  "The identifiers must be unique, \""
											  + id + "\" is shared by "
											  + int2string(count) + " entities"));
		}
	}
	//Check transition names
	for(size_t i = 0; i < _transitionNames.size(); i++){
		const string& id = _transitionNames[i];
		int count = countMatchingIds(id);
		assert(count >= 1);
		if(count > 1 && reportedDuplicates.count(id) == 0){
			reportedDuplicates.insert(id);
			_errors.push_back(ValidationError(id,
											  "The identifiers must be unique, \""
											  + id + "\" is shared by "
											  + int2string(count) + " entities"));
		}
	}

	//Check all input arcs
	for(size_t i = 0; i < _inputArcs.size(); i++){
		const Arc& arc = _inputArcs[i];
		bool foundPlace = false;
		bool foundTransition = false;
		//Look for place
		for(size_t j = 0; j < _placeNames.size(); j++){
			foundPlace |= _placeNames[j] == arc.start;
			if(foundPlace) break;
		}
		//Look for transition
		for(size_t j = 0; j < _transitionNames.size(); j++){
			foundTransition |= _transitionNames[j] == arc.end;
			if(foundTransition) break;
		}
		//Report error
		if(!foundPlace || !foundTransition){
			string msg;
			if(!foundPlace && !foundTransition)
				msg = "Neigther end-points found";
			else if(!foundPlace)
				msg = "Start-place \"" + arc.start + "\" not found";
			else
				msg = "End-transition \"" + arc.end + "\" not found";
			_errors.push_back(ValidationError(arc.start,
											  arc.end,
											  msg));
		}
	}
	//Check all output arcs
	for(size_t i = 0; i < _outputArcs.size(); i++){
		const Arc& arc = _outputArcs[i];
		bool foundPlace = false;
		bool foundTransition = false;
		//Look for transition
		for(size_t j = 0; j < _transitionNames.size(); j++){
			foundTransition |= _transitionNames[j] == arc.start;
			if(foundTransition) break;
		}
		//Look for place
		for(size_t j = 0; j < _placeNames.size(); j++){
			foundPlace |= _placeNames[j] == arc.end;
			if(foundPlace) break;
		}
		//Report error
		if(!foundPlace || !foundTransition){
			string msg;
			if(!foundPlace && !foundTransition)
				msg = "Neither end-points found";
			else if(!foundPlace)
				msg = "End-place \"" + arc.end + "\" not found";
			else
				msg = "Start-transition \"" + arc.start + "\" not found";
			_errors.push_back(ValidationError(arc.start,
											  arc.end,
											  msg));
		}
	}

	//Attempt to parse all non-empty conditions
	for(size_t i = 0; i < _conditions.size(); i++){
		if(_conditions[i].empty()) continue;
		//PQL::Condition* cond = PQL::ParseQuery(_conditions[i]);
		PQL::Condition* cond = PQL::ParseCondition(_conditions[i]);
		if(cond){
			PQL::AnalysisContext context(_placeNames, _varNames, _boolVarNames);
			cond->analyze(context);
			for(size_t j = 0; j < context.errors().size(); j++){
				_errors.push_back(ValidationError(_transitionNames[i],
												  context.errors()[j],
												  true));
			}
			delete cond;
			cond = NULL;
		}else
			_errors.push_back(ValidationError(_transitionNames[i],
											  "Unable to parse non-empty condition"));
	}
	//Attempt to parse all non-empty assignments
	for(size_t i = 0; i < _assignments.size(); i++){
		if(_assignments[i].empty()) continue;
		//PQL::AssignmentExpression* a = PQL::ParseAssignment(_assignments[i]);
		PQL::AssignmentExpression* a = PQL::ParseConditionAssignment(_assignments[i]);
		if(a){
			PQL::AnalysisContext context(_placeNames, _varNames, _boolVarNames);
			a->analyze(context);
			for(size_t j = 0; j < context.errors().size(); j++){
				_errors.push_back(ValidationError(_transitionNames[i],
												  context.errors()[j],
												  false));
			}
			delete a;
			a = NULL;
		}else
			_errors.push_back(ValidationError(_transitionNames[i],
											  "Unable to parse non-empty assignment"));
	}

	return _errors.empty();
}