double BestFirstReachabilitySearch::lookaheadDistance(const PetriNet& net,
													  const Structures::State* state,
													  const PQL::Condition* query,
													  int depth){
	double min = -1;
	State* ns = (State*)alloca(StateAllocator<>::stateSize(net));
	StateAllocator<>::initializeState(ns, net);
	for(unsigned int t = 0; t < net.numberOfTransitions(); t++){
		if(net.fire(t, state, ns) && !_states->contains(ns)){
			PQL::DistanceContext context(net,
										 _distanceStrategy,
										 ns->marking(),
										 ns->intValuation(),
										 ns->boolValuation(),
										 _dm);
			double d = query->distance(context);
			if(d < min || min == -1)
				min = d;
			if(depth - 1 > 0)
				d = lookaheadDistance(net, ns, query, depth-1);
			if(d < min || min == -1)
				min = d;
		}
	}
	return min;
}
Exemple #2
0
ReachabilityResult MonoDFS::reachable(const PetriNet &net,
														   const MarkVal *m0,
														   const VarVal *v0,
														   const BoolVal *b0,
														   PQL::Condition *query){
	//Do we initially satisfy query?
	if(query->evaluate(PQL::EvaluationContext(m0, v0, b0)))
		return ReachabilityResult(ReachabilityResult::Satisfied,
								  "A state satisfying the query was found");
	//Create StateSet
	MonotonicityContext context(&net,query);
	context.analyze();

	DFSStateSet states(net,&context, ModeNormal);

	StateAllocator<1000000> allocator(net);

	State* s0 = allocator.createState();
	memcpy(s0->marking(), m0, sizeof(MarkVal)*net.numberOfPlaces());
	memcpy(s0->intValuation(), v0, sizeof(VarVal)*net.numberOfIntVariables());
	memcpy(s0->boolValuation(), b0, sizeof(BoolVal)*net.numberOfBoolVariables());

	states.add(s0, 0);

	unsigned int max = 0;
	int count = 0;
	BigInt exploredStates = 0;
	BigInt expandedStates = 0;
	BigInt transitionFired = 0;
	State* ns = allocator.createState();
	while(states.waitingSize()){
		if(count++ & 1<<18){
			if(states.waitingSize() > max)
				max = states.waitingSize();
			count = 0;
			//report progress
			reportProgress((double)(max-states.waitingSize())/(double)max);
			//check abort
			if(abortRequested())
				return ReachabilityResult(ReachabilityResult::Unknown,
										"Search was aborted.");
		}

		//Take first step of the stack
		Step tstep = states.getNextStep();
		State* s = tstep.state;

		ns->setParent(s);
		bool foundSomething = false;
		for(unsigned int t = tstep.t; t < net.numberOfTransitions(); t++){
			if(net.fire(t, s->marking(), s->intValuation(),s->boolValuation(), ns->marking(), ns->intValuation(), ns->boolValuation())){
				transitionFired++;
				if(states.add(ns,t)){
					ns->setTransition(t);
					if(query->evaluate(PQL::EvaluationContext(ns->marking(), ns->intValuation(), ns->boolValuation())))
						return ReachabilityResult(ReachabilityResult::Satisfied,
									  "A state satisfying the query was found", expandedStates, exploredStates, transitionFired, states.getCountRemove(), ns->pathLength(), ns->trace());

					exploredStates++;
					foundSomething = true;
					ns = allocator.createState();
					break;
				}
			}
		}
		if(!foundSomething){
			states.popWating();
			expandedStates++;
		}
	}
	//states.writeStatistics();
	return ReachabilityResult(ReachabilityResult::NotSatisfied,
							"No state satisfying the query exists.", expandedStates, exploredStates, transitionFired, states.getCountRemove());
}
ReachabilityResult BestFirstReachabilitySearch::reachable(const PetriNet &net,
															const MarkVal *m0,
															const VarVal *v0,
															const BoolVal *ba,
															PQL::Condition *query){
	StateAllocator<> allocator(net);

	State* s0 = allocator.createState();
	memcpy(s0->marking(), m0, sizeof(MarkVal) * net.numberOfPlaces());
	memcpy(s0->intValuation(), v0, sizeof(VarVal) * net.numberOfIntVariables());
	memcpy(s0->boolValuation(), ba, sizeof(BoolVal) * net.numberOfBoolVariables());

	if(query->evaluate(*s0))
		return ReachabilityResult(ReachabilityResult::Satisfied, "Satisfied initially", 0, 0);

	//Initialize subclasses
	initialize(query, net);

	StateSet states(net);
	_states = &states;
	states.add(s0);
	//PriorityQueue<State*> queue;
	EnhancedPriorityQueue<State*> queue;
	queue.push(0, s0);

	//Allocate new state
	State* ns = allocator.createState();
	State* ns2 = allocator.createState();
	State* ns3 = allocator.createState();
	int count = 0;
	BigInt expandedStates = 0;
	BigInt exploredStates = 0;
	BigInt transitionFired  = 0;
	size_t max = 1;
	while(!queue.empty()){
		if(count++ & 1<<17){
			count = 0;
			if(queue.size() > max)
				max = queue.size();
			this->reportProgress((double)(max - queue.size()) / ((double)(max)));
			if(this->abortRequested())
				return ReachabilityResult(ReachabilityResult::Unknown,
										  "Query aborted!");
		}

		//Take something out of the queue
		State* s = queue.pop(depthFirst);
		expandedStates++;

		// Attempt to fire each transition
		for(unsigned int t = 0; t < net.numberOfTransitions(); t++){
			if(net.fire(t, s->marking(), s->intValuation(), s->boolValuation(), ns->marking(), ns->intValuation(), ns->boolValuation())){
				//If it's new
				transitionFired++;
				if(states.add(ns)){
					exploredStates++;
					//Set parent and transition for the state
					ns->setParent(s);
					ns->setTransition(t);

					//Test query
					if(query->evaluate(*ns)){
						//ns->dumpTrace(net);
						return ReachabilityResult(ReachabilityResult::Satisfied,
												  "Query was satified!", expandedStates, exploredStates, transitionFired,0 , ns->pathLength(), ns->trace());
					}

					// Insert in queue, with given priority
					double bestp = priority(ns, query, net);
					queue.push(bestp, ns);

					if(fireUntillNoBetter && net.fire(t, ns, ns2)){
						if(query->evaluate(*ns2)){
							ns2->setTransition(t);
							ns2->setParent(ns);
							return ReachabilityResult(ReachabilityResult::Satisfied,
												  "Query was satified!", expandedStates, exploredStates, transitionFired,0, ns2->pathLength(), ns2->trace());
						}
						double p = priority(ns2, query, net);
						if(p <= bestp){
							bestp = p;
							while(net.fire(t, ns2, ns3) && (p = priority(ns3, query, net)) <= bestp){
								ns3->setTransition(t);
								ns3->setParent(ns2);
								bestp = p;
								State* tmp = ns2;	//SWAP ns2 and ns3
								ns2 = ns3;
								ns3 = tmp;
								exploredStates++;
								if(query->evaluate(*ns2)){
									return ReachabilityResult(ReachabilityResult::Satisfied,
													  "Query was satisfied!", expandedStates, exploredStates, transitionFired, 0, ns2->pathLength(), ns2->trace());
								}
							}
							if(states.add(ns2)){
								queue.push(priority(ns2, query, net), ns2);
								ns2 = allocator.createState();
							}
						}
					}

					//Allocate new stake, as states take ownership
					ns = allocator.createState();
				}
			}
		}
	}

	return ReachabilityResult(ReachabilityResult::NotSatisfied,
							  "Query cannot be satisfied!", expandedStates, exploredStates, transitionFired,0);
}
Exemple #4
0
ReachabilityResult HeuristicDFS::reachable(const PetriNet& net,
										   const MarkVal* m0,
										   const VarVal* v0,
										   const BoolVal *ba,
										   PQL::Condition* query){
	//Do we initially satisfy query?
	if(query->evaluate(PQL::EvaluationContext(m0, v0, ba)))
		return ReachabilityResult(ReachabilityResult::Satisfied,
								  "A state satisfying the query was found");

	StateSet states(net);
	StateAllocator<> allocator(net);
	std::list<State*> stack;

	State* s0 = allocator.createState();
	memcpy(s0->marking(), m0, sizeof(MarkVal)*net.numberOfPlaces());
	memcpy(s0->intValuation(), v0, sizeof(VarVal)*net.numberOfIntVariables());
	memcpy(s0->boolValuation(), ba, sizeof(BoolVal)*net.numberOfBoolVariables());
	stack.push_back(s0);
	states.add(s0);

	Structures::DistanceMatrix distanceMatrix(net);

	State* ns = allocator.createState();
	unsigned int max = 0;
	int count = 0;
	BigInt expandedStates = 0;
	BigInt exploredStates = 0;
	BigInt transitionFired  = 0;
	while(!stack.empty()){
		// Progress reporting and abort checking
		if(count++ & 1<<16){
			if(stack.size() > max)
				max = stack.size();
			count = 0;
			// Report progress
			reportProgress((double)(max - stack.size())/(double)max);
			// Check abort
			if(abortRequested())
				return ReachabilityResult(ReachabilityResult::Unknown,
										"Search was aborted.");
		}

		State* s = stack.back();
		stack.pop_back();
		State* succ[net.numberOfTransitions()];
		double distances[net.numberOfTransitions()];
		memset(succ, 0, net.numberOfTransitions()*sizeof(State*));
		for(unsigned int t = 0; t < net.numberOfTransitions(); t++){
			if(net.fire(t, s, ns)){
				transitionFired++;
				if(states.add(ns)){
					exploredStates++;
					ns->setParent(s);
					ns->setTransition(t);
					if(query->evaluate(*ns))
						return ReachabilityResult(ReachabilityResult::Satisfied,
												"A state satisfying the query was found", expandedStates, exploredStates, transitionFired, 0, ns->pathLength(), ns->trace());
					PQL::DistanceContext context(net,
												 _distanceStrategy,
												 ns->marking(),
												 ns->intValuation(),
												 ns->boolValuation(),
												 &distanceMatrix);
					succ[t] = ns;
					distances[t] = query->distance(context);
					ns = allocator.createState();
				}
			}
		}

		// Pretty bobble sort of the successors
		while(true){
			bool foundSomething = false;
			unsigned int min = 0;
			for(unsigned int t = 0; t < net.numberOfTransitions(); t++){
				if(succ[t] && (!foundSomething || distances[t] < distances[min])){
					min = t;
					foundSomething = true;
				}
			}
			if(foundSomething){
				stack.push_back(succ[min]);
				succ[min] = NULL;
			}else
				break;
		}
		expandedStates++;
	}

	return ReachabilityResult(ReachabilityResult::NotSatisfied,
						"No state satisfying the query exists.", expandedStates, exploredStates, transitionFired, 0);
}
Exemple #5
0
ReachabilityResult MonoBFS::reachable(const PetriNet &net,
															 const MarkVal *m0,
															 const VarVal *v0,
															 const BoolVal *ba,
															 PQL::Condition *query){
	//Do we initially satisfy query?
	if(query->evaluate(PQL::EvaluationContext(m0, v0,ba)))
		return ReachabilityResult(ReachabilityResult::Satisfied,
								  "A state satisfying the query was found");
	//Create StateSet
	MonotonicityContext context(&net, query);
	context.analyze();

	BFSOrderableStateSet states(net,&context);

	StateAllocator<1000000> allocator(net);

	State* s0 = allocator.createState();
	memcpy(s0->marking(), m0, sizeof(MarkVal)*net.numberOfPlaces());
	memcpy(s0->intValuation(), v0, sizeof(VarVal)*net.numberOfIntVariables());
	memcpy(s0->boolValuation(), ba, sizeof(BoolVal)*net.numberOfBoolVariables());

	states.add(s0);

	unsigned int max = 0;
	int count = 0;
	BigInt expandedStates = 0;
	BigInt exploredStates = 0;
	BigInt transitionFired  = 0;
	State* ns = allocator.createState();
	State* s = states.getNextState();
	while(s){
		// Progress reporting and abort checking
		if(count++ & 1<<15){
			if(states.waitingSize() > max)
				max = states.waitingSize();
			count = 0;
			// Report progress
			reportProgress((double)(max - states.waitingSize())/(double)max);
			// Check abort
			if(abortRequested())
				return ReachabilityResult(ReachabilityResult::Unknown,
										"Search was aborted.");
		}

		for(unsigned int t = 0; t < net.numberOfTransitions(); t++){
			if(net.fire(t, s, ns)){
				transitionFired++;
				if(states.add(ns)){
					exploredStates++;
					ns->setParent(s);
					ns->setTransition(t);
					if(query->evaluate(PQL::EvaluationContext(ns->marking(), ns->intValuation(), ns->boolValuation()))){
						//ns->dumpTrace(net);
						return ReachabilityResult(ReachabilityResult::Satisfied,
												"A state satisfying the query was found", expandedStates, exploredStates, transitionFired, states.getCountRemove(), ns->pathLength(), ns->trace());
					}

					ns = allocator.createState();
				}
			}
		}
		s = states.getNextState();
		expandedStates++;
	}

	return ReachabilityResult(ReachabilityResult::NotSatisfied,
						"No state satisfying the query exists.", expandedStates, exploredStates, transitionFired, states.getCountRemove());
}
Exemple #6
0
ReachabilityResult IndexedBestFS::reachable(const PetriNet &net,
											const MarkVal *m0,
											const VarVal *v0,
											const BoolVal *ba,
											PQL::Condition *query){
	StateAllocator<> allocator(net);

	State* s0 = allocator.createState();
	memcpy(s0->marking(), m0, sizeof(MarkVal) * net.numberOfPlaces());
	memcpy(s0->intValuation(), v0, sizeof(VarVal) * net.numberOfIntVariables());
	memcpy(s0->boolValuation(), ba, sizeof(BoolVal) * net.numberOfBoolVariables());

	if(query->evaluate(*s0))
		return ReachabilityResult(ReachabilityResult::Satisfied, "Satisfied initially", 0, 0);

	//Initialize subclasses
	MonotonicityContext context(&net, query);
	context.analyze();

	//Initialise StateSet
	IndexedBestFSStateSet states(net, &context, _distanceStrategy, query, _varianceFirst);
	states.add(s0);

	//Allocate new state
	State* ns = allocator.createState();
	int count = 0;
	BigInt expandedStates = 0;
	BigInt exploredStates = 0;
	BigInt transitionFired  = 0;
	size_t max = 1;
	State* s = states.getNextState();
	while(s){
		if(count++ & 1<<16){
			count = 0;
			if(states.waitingSize() > max)
				max = states.waitingSize();
			this->reportProgress((double)(max - states.waitingSize()) / ((double)(max)));
			if(this->abortRequested())
				return ReachabilityResult(ReachabilityResult::Unknown,
										  "Query aborted!");
		}

		// Attempt to fire each transition
		for(unsigned int t = 0; t < net.numberOfTransitions(); t++){
			if(net.fire(t, s, ns)){
				//If it's new
				transitionFired++;
				if(states.add(ns)){
					exploredStates++;
					//Set parent and transition for the state
					ns->setParent(s);
					ns->setTransition(t);

					//Test query
					if(query->evaluate(*ns)){
						//ns->dumpTrace(net);
						return ReachabilityResult(ReachabilityResult::Satisfied,
												  "Query was satified!", expandedStates, exploredStates, transitionFired, states.getCountRemove(), ns->pathLength(), ns->trace());
					}

					//Allocate new state, as states take ownership
					ns = allocator.createState();
				}
			}
		}
		//Take something out of the queue
		expandedStates++;
		s = states.getNextState();
	}

	return ReachabilityResult(ReachabilityResult::NotSatisfied,
							  "Query cannot be satisfied!", expandedStates, exploredStates, transitionFired, states.getCountRemove());
}
Exemple #7
0
ReachabilityResult MagicSearch::reachable(const PetriNet &net,
										  const MarkVal *m0,
										  const VarVal *v0,
										  PQL::Condition *query){
	SmartStateAllocator<MEMORY_BOUND> allocator(net);
	SmartStateSet states(net);
	EnhancedPriorityQueue<Step> queue;

	_dm = new Structures::DistanceMatrix(net);
	{	//Compute constraints
		ConstraintAnalysisContext context(net);
		query->findConstraints(context);
		if(context.canAnalyze)
			contraints = context.retval;
	}

	//Create s0
	SmartState* s0 = allocator.createStoredState();
	memcpy(s0->marking(), m0, sizeof(MarkVal) * net.numberOfPlaces());
	memcpy(s0->valuation(), v0, sizeof(VarVal) * net.numberOfVariables());
	states.add(s0, s0->marking(), s0->valuation());
	Step step0;
	step0.depth = 0;
	step0.lastApprox = INT_MAX;
	step0.lastStored = 0;
	step0.state = s0;
	queue.push(0, step0);

	//Temporary marking and valuation to work with
	MarkVal tmpM[net.numberOfPlaces()];
	VarVal tmpV[net.numberOfVariables()];
	SmartState* ns = allocator.createStoredState();
	SmartState* ls = allocator.createState();

	//Statistics
	int lastReport = 0;
	BigInt expanded = 0, explored = 0;
	size_t max = 1;

	//Main loop
	while(!queue.empty()){
		// Report progress if needed
		if(lastReport++ & 1<<17){
			lastReport = 0;
			if(queue.size() > max)
				max = queue.size();
			this->reportProgress((double)(max - queue.size()) / ((double)(max)));
			if(this->abortRequested())
				return ReachabilityResult(ReachabilityResult::Unknown,
										  "Query aborted!");
		}

		//Pop stuff of the queue
		Step step = queue.pop(depthFirst);
		expanded++; //Cound expanded states

		// Get current state
		const MarkVal* m;
		const VarVal* v;
		if(step.state->stored()){
			m = step.state->marking();
			v = step.state->valuation();
		}else{
			step.state->getState(net, tmpM, tmpV);
			m = tmpM;
			v = tmpV;
		}

		//Attempt to exclude by over-approx
		if(step.lastApprox >= approxScale(step.depth)){
			if(canExcludeByOverApprox(net, m, v))
				continue;
			step.lastApprox = 0;
		}

		for(unsigned int t = 0; t < net.numberOfTransitions(); t++){
			//Fire the transition
			if(net.fire(t, m, v, ns->marking(), ns->valuation())){
				//Determine whether or not to store the entire state
				bool storeCurrentState = step.lastStored >= storeScale(allocator.percentMemoryUsed());// storeScale(allocator.percentMemoryUsed());
				SmartState* storeState;
				if(storeCurrentState)
					storeState = ns;
				else
					storeState = ls;
				storeState->setParent(step.state);
				storeState->setTransition(t);

				//Add it to the state set
				if(states.add(storeState, ns->marking(), ns->valuation())){
					explored++; //Count explored states

					//Test the query
					if(query->evaluate(EvaluationContext(ns->marking(), ns->valuation()))){
						printf("\nmemory usage: %f\n",allocator.percentMemoryUsed());
						return ReachabilityResult(ReachabilityResult::Satisfied,
												  "Query was satified!",
												  expanded,
												  explored,
												  storeState->pathLength(),
												  storeState->trace());
					}

					//Make the next step
					Step nextstep;
					nextstep.depth = step.depth + 1;
					nextstep.lastApprox = step.lastApprox + 1;
					if(storeState == ns)
						nextstep.lastStored = 0;
					else
						nextstep.lastStored = step.lastStored + 1;
					nextstep.state = storeState;

					//Push step on the queue
					double p = priority(ns->marking(), ns->valuation(), query, net);
					queue.push(p, nextstep);

					//Allocate new memory, depending on what was stored
					if(storeState == ns)
						ns = allocator.createStoredState();
					else
						ls = allocator.createState();
				}
			}
		}
	}
	return ReachabilityResult(ReachabilityResult::NotSatisfied,
							  "Query cannot be satisfied!",
							  expanded,
							  explored);
}