double MonoNewBestFS::priority(const Structures::State *state, PQL::MonotonicityContext* context, const PetriNet& net){ double d = 0; for(size_t i = 0; i < net.numberOfBoolVariables(); i++){ if(context->goodBoolVariables()[i]) { if(state->boolValuation()[i]) d -= 1; } } std::cerr<<d<<std::endl; return d; }
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); }
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); }
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()); }
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()); }