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 "RandomDFS.h"
20
#include "../PQL/PQL.h"
21
#include "../PQL/Contexts.h"
22
#include "../Structures/StateSet.h"
23
#include "../Structures/LimitedStateAllocator.h"
31
using namespace PetriEngine::PQL;
32
using namespace PetriEngine::Structures;
34
namespace PetriEngine{ namespace Reachability {
36
ReachabilityResult RandomDFS::reachable(const PetriNet &net,
39
PQL::Condition *query){
40
//Do we initially satisfy query?
41
if(query && query->evaluate(PQL::EvaluationContext(m0, v0)))
42
return ReachabilityResult(ReachabilityResult::Satisfied,
43
"A state satisfying the query was found");
46
LimitedStateAllocator<> allocator(net, _memorylimit);
47
std::list<State*> stack;
48
srand(time(0)); // Chosen by fair dice roll
50
State* s0 = allocator.createState();
52
return ReachabilityResult(ReachabilityResult::Unknown,
53
"Memory bound exceeded");
54
memcpy(s0->marking(), m0, sizeof(MarkVal)*net.numberOfPlaces());
55
memcpy(s0->valuation(), v0, sizeof(VarVal)*net.numberOfVariables());
59
State* ns = allocator.createState();
61
return ReachabilityResult(ReachabilityResult::Unknown,
62
"Memory bound exceeded");
64
int countdown = rand() % 800000;
67
BigInt exploredStates = 0;
68
BigInt expandedStates = 0;
70
while(!stack.empty()){
71
// Progress reporting and abort checking
73
if(stack.size() > max)
77
reportProgress((double)(max - stack.size())/(double)max);
80
return ReachabilityResult(ReachabilityResult::Unknown,
81
"Search was aborted.");
87
//Hack for when query is null and we're look to print a random state
88
if(!query && countdown-- <= 0){
89
//TODO: Remove this hack or copy the code for random state generation, if we need that feature...
90
printf("%s == %i ", net.placeNames()[0].c_str(), s->marking()[0]);
91
for(int p = 1; p < net.numberOfPlaces(); p++)
92
printf(" and %s == %i ", net.placeNames()[p].c_str(), s->marking()[p]);
93
for(int x = 0; x < net.numberOfVariables(); x++)
94
printf(" and %s == %i ", net.variableNames()[x].c_str(), s->valuation()[x]);
95
return ReachabilityResult();
98
State* succ[net.numberOfTransitions()];
99
memset(succ, 0, net.numberOfTransitions()*sizeof(State*));
100
for(unsigned int t = 0; t < net.numberOfTransitions(); t++){
101
if(net.fire(t, s, ns, 1, _kbound)){
105
ns->setTransition(t);
106
if(query && query->evaluate(*ns))
107
return ReachabilityResult(ReachabilityResult::Satisfied,
108
"A state satisfying the query was found", expandedStates, exploredStates, ns->pathLength(), ns->trace());
110
ns = allocator.createState();
112
return ReachabilityResult(ReachabilityResult::Unknown,
113
"Memory bound exceeded",
114
expandedStates, exploredStates);
118
// Randomly sorts states into the stack
123
random = rand() % net.numberOfTransitions();
127
stack.push_back(succ[t]);
132
t = (t+1) % net.numberOfTransitions();
133
} while(t != random);
134
} while(t != random);
137
//Hack for when query is null and we're look to print a random state
139
printf("%s == %i ", net.placeNames()[0].c_str(), s->marking()[0]);
140
for(int p = 1; p < net.numberOfPlaces(); p++)
141
printf(" and %s == %i ", net.placeNames()[p].c_str(), s->marking()[p]);
142
for(int x = 0; x < net.numberOfVariables(); x++)
143
printf(" and %s == %i ", net.variableNames()[x].c_str(), s->valuation()[x]);
147
return ReachabilityResult(ReachabilityResult::NotSatisfied,
148
"No state satisfying the query exists.", expandedStates, exploredStates);