1
/* VerifyPN - TAPAAL Petri Net Engine
2
* Copyright (C) 2016 Peter Gjøl Jensen <root@petergjoel.dk>
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation, either version 3 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19
#include <unordered_map>
22
#include "AlignedEncoder.h"
23
#include "ptrie_stable.h"
24
#include "ptrie_map.h"
25
#include "binarywrapper.h"
26
#include "../errorcodes.h"
29
namespace PetriEngine {
30
namespace Structures {
32
class StateSetInterface
35
StateSetInterface(const PetriNet& net, uint32_t kbound) :
36
_encoder(net.numberOfPlaces(), kbound), _net(net)
41
_maxPlaceBound = std::vector<uint32_t>(_net.numberOfPlaces(), 0);
42
_sp = binarywrapper_t(sizeof(uint32_t)*_net.numberOfPlaces()*8);
45
virtual std::pair<bool, size_t> add(State& state) = 0;
47
virtual void decode(State& state, size_t id) = 0;
49
const PetriNet& net() { return _net;}
51
virtual void setHistory(size_t id, size_t transition) = 0;
53
virtual std::pair<size_t, size_t> getHistory(size_t markingid) = 0;
59
std::vector<uint32_t> _maxPlaceBound;
60
AlignedEncoder _encoder;
64
std::vector<uint32_t*> _dbg;
67
void _decode(State& state, size_t id, T& _trie)
69
_trie.unpack(id, _encoder.scratchpad().raw());
70
_encoder.decode(state.marking(), _encoder.scratchpad().raw());
73
assert(memcmp(state.marking(), _dbg[id], sizeof(uint32_t)*_net.numberOfPlaces()) == 0);
78
std::pair<bool, size_t> _add(State& state, T& _trie) {
82
if(_discovered % 1000000 == 0) std::cout << "Found number " << _discovered << std::endl;
90
markingStats(state.marking(), sum, allsame, val, active, last);
95
//Check that we're within k-bound
96
if (_kbound != 0 && sum > _kbound)
97
return std::pair<bool, size_t>(false, std::numeric_limits<size_t>::max());
99
unsigned char type = _encoder.getType(sum, active, allsame, val);
102
size_t length = _encoder.encode(state.marking(), type);
103
binarywrapper_t w = binarywrapper_t(_encoder.scratchpad().raw(), length*8);
104
auto tit = _trie.insert(w);
109
return std::pair<bool, size_t>(false, std::numeric_limits<size_t>::max());
113
_dbg.push_back(new uint32_t[_net.numberOfPlaces()]);
114
memcpy(_dbg.back(), state.marking(), _net.numberOfPlaces()*sizeof(uint32_t));
115
decode(state, _trie.size() - 1);
118
// update the max token bound for each place in the net (only for newly discovered markings)
119
for (uint32_t i = 0; i < _net.numberOfPlaces(); i++)
121
_maxPlaceBound[i] = std::max<MarkVal>( state.marking()[i],
126
if(_trie.size() % 100000 == 0) std::cout << "Inserted " << _trie.size() << std::endl;
128
return std::pair<bool, size_t>(true, tit.second);
132
size_t discovered() const {
136
uint32_t maxTokens() const {
140
std::vector<MarkVal> maxPlaceBound() const {
141
return _maxPlaceBound;
146
void markingStats(const uint32_t* marking, MarkVal& sum, bool& allsame, uint32_t& val, uint32_t& active, uint32_t& last)
150
for (uint32_t i = 0; i < _net.numberOfPlaces(); i++)
156
last = std::max(last, i);
157
val = std::max(marking[i], val);
158
if(old != 0 && marking[i] != old) allsame = false;
166
#define STATESET_BUCKETS 1000000
167
class StateSet : public StateSetInterface {
169
using wrapper_t = ptrie::binarywrapper_t;
170
using ptrie_t = ptrie::set_stable<>;
173
using StateSetInterface::StateSetInterface;
175
virtual std::pair<bool, size_t> add(State& state) override
177
return _add(state, _trie);
180
virtual void decode(State& state, size_t id) override
182
_decode(state, id, _trie);
186
virtual void setHistory(size_t id, size_t transition) override {}
188
virtual std::pair<size_t, size_t> getHistory(size_t markingid) override
191
return std::make_pair(0,0);
198
class TracableStateSet : public StateSetInterface
204
ptrie::uint transition;
208
using ptrie_t = ptrie::map<traceable_t>;
211
using StateSetInterface::StateSetInterface;
213
virtual std::pair<bool, size_t> add(State& state) override
216
size_t tmppar = _parent; // we might change this while debugging.
218
auto res = _add(state, _trie);
225
virtual void decode(State& state, size_t id) override
228
_decode(state, id, _trie);
231
virtual void setHistory(size_t id, size_t transition) override
233
traceable_t& t = _trie.get_data(id);
235
t.transition = transition;
238
virtual std::pair<size_t, size_t> getHistory(size_t markingid) override
240
traceable_t& t = _trie.get_data(markingid);
241
return std::pair<size_t, size_t>(t.parent, t.transition);