1
/* PeTe - Petri Engine exTremE
2
* Copyright (C) 2011 Jonas Finnemann Jensen <jopsen@gmail.com>,
3
* Thomas Søndersø Nielsen <primogens@gmail.com>,
4
* Lars Kærlund Østergaard <larsko@gmail.com>,
6
* This program is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19
#include "BestFSCooling.h"
21
#include "../PQL/PQL.h"
22
#include "../PQL/Contexts.h"
23
#include "../Structures/PriorityQueue.h"
24
#include "../Structures/EnhancedPriorityQueue.h"
25
#include "../Structures/StateSet.h"
26
#include "../Structures/StateAllocator.h"
32
using namespace PetriEngine::Structures;
33
using namespace PetriEngine::PQL;
35
namespace PetriEngine{
36
namespace Reachability{
38
ReachabilityResult BestFSCooling::reachable(const PetriNet &net,
41
PQL::Condition *query){
42
StateAllocator<> allocator(net);
44
State* s0 = allocator.createState();
45
memcpy(s0->marking(), m0, sizeof(MarkVal) * net.numberOfPlaces());
46
memcpy(s0->valuation(), v0, sizeof(VarVal) * net.numberOfVariables());
48
if(query->evaluate(*s0))
49
return ReachabilityResult(ReachabilityResult::Satisfied, "Satisfied initially", 0, 0);
51
//Initialize subclasses
52
initialize(query, net);
57
//PriorityQueue<State*> queue;
58
EnhancedPriorityQueue<State*> queue;
62
State* ns = allocator.createState();
63
State* ns2 = allocator.createState();
66
BigInt expandedStates = 0;
67
BigInt exploredStates = 0;
69
while(!queue.empty()){
72
if(queue.size() > max)
74
this->reportProgress((double)(max - queue.size()) / ((double)(max)));
75
if(this->abortRequested())
76
return ReachabilityResult(ReachabilityResult::Unknown,
80
//Take something out of the queue
81
double topP = queue.topPriority();
82
State* s = queue.pop(depthFirst);
85
int heatFactor = (int)floor(topP / net.numberOfPlaces());
87
// Attempt to fire each transition
88
for(unsigned int t = 0; t < net.numberOfTransitions(); t++){
89
if(net.fire(t, s->marking(), s->valuation(), ns->marking(), ns->valuation())){
93
//Set parent and transition for the state
98
if(query->evaluate(*ns))
99
return ReachabilityResult(ReachabilityResult::Satisfied,
100
"Query was satified!",
106
// Insert in queue, with given priority
107
double bestp = priority(ns, query, net);
108
queue.push(bestp, ns);
111
if(heatFactor > 1 && net.fire(t, s, ns2, heatFactor)){
113
ns2->setTransition(t, heatFactor);
114
queue.push(priority(ns2, query, net), ns2);
115
ns2 = allocator.createState();
120
//Allocate new stake, as states take ownership
121
ns = allocator.createState();
127
return ReachabilityResult(ReachabilityResult::NotSatisfied,
128
"Query cannot be satisfied!", expandedStates, exploredStates);
131
double BestFSCooling::priority(const Structures::State *state,
132
const PQL::Condition *query,
133
const PetriNet& net){
134
PQL::DistanceContext context(net,
139
double d = query->distance(context);
141
double d2 = lookaheadDistance(net, state, query, _lookahead);
147
void BestFSCooling::initialize(const PQL::Condition*,
148
const PetriNet& net){
149
_dm = new Structures::DistanceMatrix(net);
152
double BestFSCooling::lookaheadDistance(const PetriNet& net,
153
const Structures::State* state,
154
const PQL::Condition* query,
157
char d[StateAllocator<>::stateSize(net)];
158
State* ns = (State*)d;
159
StateAllocator<>::initializeState(ns, net);
160
for(unsigned int t = 0; t < net.numberOfTransitions(); t++){
161
if(net.fire(t, state, ns) && !_states->contains(ns)){
162
PQL::DistanceContext context(net,
167
double d = query->distance(context);
168
if(d < min || min == -1)
171
d = lookaheadDistance(net, ns, query, depth-1);
172
if(d < min || min == -1)