2
* To change this license header, choose License Headers in Project Properties.
3
* To change this template file, choose Tools | Templates
4
* and open the template in the editor.
8
* File: ColoredPetriNetBuilder.cpp
11
* Created on 17. februar 2018, 16:25
14
#include "ColoredPetriNetBuilder.h"
17
namespace PetriEngine {
18
ColoredPetriNetBuilder::ColoredPetriNetBuilder() {
21
ColoredPetriNetBuilder::ColoredPetriNetBuilder(const ColoredPetriNetBuilder& orig) {
24
ColoredPetriNetBuilder::~ColoredPetriNetBuilder() {
27
void ColoredPetriNetBuilder::addPlace(const std::string& name, int tokens, double x, double y) {
29
_ptBuilder.addPlace(name, tokens, x, y);
33
void ColoredPetriNetBuilder::addPlace(const std::string& name, Colored::ColorType* type, Colored::Multiset tokens, double x, double y) {
34
if(_placenames.count(name) == 0)
36
uint32_t next = _placenames.size();
37
_places.push_back(Colored::Place {name, type, tokens});
38
_placenames[name] = next;
42
void ColoredPetriNetBuilder::addTransition(const std::string& name, double x, double y) {
44
_ptBuilder.addTransition(name, x, y);
48
void ColoredPetriNetBuilder::addTransition(const std::string& name, Colored::GuardExpression_ptr guard, double x, double y) {
49
if(_transitionnames.count(name) == 0)
51
uint32_t next = _transitionnames.size();
52
_transitions.push_back(Colored::Transition {name, guard});
53
_transitionnames[name] = next;
57
void ColoredPetriNetBuilder::addInputArc(const std::string& place, const std::string& transition, bool inhibitor, int weight) {
59
_ptBuilder.addInputArc(place, transition, inhibitor, weight);
63
void ColoredPetriNetBuilder::addInputArc(const std::string& place, const std::string& transition, Colored::ArcExpression_ptr expr) {
64
addArc(place, transition, expr, true);
67
void ColoredPetriNetBuilder::addOutputArc(const std::string& transition, const std::string& place, int weight) {
69
_ptBuilder.addOutputArc(transition, place, weight);
73
void ColoredPetriNetBuilder::addOutputArc(const std::string& transition, const std::string& place, Colored::ArcExpression_ptr expr) {
74
addArc(place, transition, expr, false);
77
void ColoredPetriNetBuilder::addArc(const std::string& place, const std::string& transition, Colored::ArcExpression_ptr expr, bool input) {
78
if(_transitionnames.count(transition) == 0)
80
std::cout << "Transition '" << transition << "' not found. Adding it." << std::endl;
81
addTransition(transition,0.0,0.0);
83
if(_placenames.count(place) == 0)
85
std::cout << "Place '" << place << "' not found. Adding it." << std::endl;
86
addPlace(place,0,0,0);
88
uint32_t p = _placenames[place];
89
uint32_t t = _transitionnames[transition];
91
assert(t < _transitions.size());
92
assert(p < _places.size());
94
//std::set<Colored::Variable*> variables;
99
assert(expr != nullptr);
102
_transitions[t].arcs.push_back(_arcs.size());
103
_arcs.push_back(arc);
104
// assert(_transitions[t].arcs.back() == &_arcs.back());
107
void ColoredPetriNetBuilder::addColorType(const std::string& id, Colored::ColorType* type) {
111
void ColoredPetriNetBuilder::sort() {
115
PetriNetBuilder& ColoredPetriNetBuilder::unfold() {
116
if (_stripped) assert(false);
117
if (_isColored && !_unfolded) {
118
auto start = std::chrono::high_resolution_clock::now();
119
for (auto& place : _places) {
123
for (auto& transition : _transitions) {
124
unfoldTransition(transition);
127
for (auto& arc : _arcs) {
131
auto end = std::chrono::high_resolution_clock::now();
132
_time = (std::chrono::duration_cast<std::chrono::microseconds>(end - start).count())*0.000001;
138
void ColoredPetriNetBuilder::unfoldPlace(Colored::Place& place) {
139
//std::cout << place.name << std::endl;
140
for (size_t i = 0; i < place.type->size(); ++i) {
141
//std::cout << c.toString() << std::endl;
142
std::string name = place.name + ";" + std::to_string(i);
143
const Colored::Color* color = &(*place.type)[i];
144
//std::cout << name << std::endl;
145
_ptBuilder.addPlace(name, place.marking[color], 0.0, 0.0);
146
_ptplacenames[place.name][color->getId()] = name;
151
void ColoredPetriNetBuilder::unfoldTransition(Colored::Transition& transition) {
152
//std::cout << transition.name << std::endl;
153
BindingGenerator gen(transition, _arcs, _colors);
154
for (auto& b : gen) {
155
size_t i = transition.bindings.size();
156
std::unordered_map<std::string, const Colored::Color*> binding;
157
for (auto& elem : b) {
158
binding[elem.var->name] = elem.color;
160
transition.bindings.push_back(binding);
161
std::string name = transition.name + ";" + std::to_string(i);
162
_ptBuilder.addTransition(name, 0.0, 0.0);
163
_pttransitionnames[transition.name].push_back(name);
168
void ColoredPetriNetBuilder::unfoldArc(Colored::Arc& arc) {
169
Colored::Transition& transition = _transitions[arc.transition];
170
for (size_t i = 0; i < transition.bindings.size(); ++i) {
171
// for (auto& b : transition.bindings[i]) {
172
// printf("Binding var '%s'\n", b.first.c_str());
174
Colored::ExpressionContext context {transition.bindings[i], _colors};
175
Colored::Multiset ms = arc.expr->eval(context);
176
// std::cout << "Before clean: " << ms.toString() << std::endl;
178
// std::cout << "After clean: " << ms.toString() << std::endl;
180
// std::cout << "Arc from place '" << _places[arc.place].name << "' to transition '" << transition.name;
182
// std::cout << "Arc from transition '" << transition.name << "' to place '" << _places[arc.place].name;
184
// std::cout << "' under binding '" << i << "' has " << ms.distinctSize() << " distinct elements" << std::endl;
185
for (auto color : ms) {
186
if (color.second == 0) {
189
std::string pName = _ptplacenames[_places[arc.place].name][color.first->getId()];
190
std::string tName = _pttransitionnames[transition.name][i];
191
// if (pName.empty()) {
192
// std::cout << "place: " << _places[arc.place].name << " color: " << color.first->toString() << std::endl;
193
// for (auto& col : _ptplacenames[_places[arc.place].name]) {
194
// std::cout << "\tPossible color: " << col.first << std::endl;
198
// std::cout << "Arc from place '" << _places[arc.place].name << "' to transition '" << transition.name;
200
// std::cout << "Arc from transition '" << transition.name << "' to place '" << _places[arc.place].name;
202
// std::cout << "' under binding '" << i << "' with color '" << color.first->toString() << "' with " << color.second << " tokens" << std::endl;
204
_ptBuilder.addInputArc(pName, tName, false, color.second);
206
_ptBuilder.addOutputArc(tName, pName, color.second);
213
PetriNetBuilder& ColoredPetriNetBuilder::stripColors() {
214
if (_unfolded) assert(false);
215
if (_isColored && !_stripped) {
216
for (auto& place : _places) {
217
_ptBuilder.addPlace(place.name, place.marking.size(), 0.0, 0.0);
220
for (auto& transition : _transitions) {
221
_ptBuilder.addTransition(transition.name, 0.0, 0.0);
224
for (auto& arc : _arcs) {
226
_ptBuilder.addInputArc(_places[arc.place].name, _transitions[arc.transition].name, false, arc.expr->weight());
228
_ptBuilder.addOutputArc(_transitions[arc.transition].name, _places[arc.place].name, arc.expr->weight());
238
BindingGenerator::Iterator::Iterator(BindingGenerator* generator)
239
: _generator(generator)
243
bool BindingGenerator::Iterator::operator==(Iterator& other) {
244
return _generator == other._generator;
247
bool BindingGenerator::Iterator::operator!=(Iterator& other) {
248
return _generator != other._generator;
251
BindingGenerator::Iterator& BindingGenerator::Iterator::operator++() {
252
_generator->nextBinding();
253
if (_generator->isInitial()) _generator = nullptr;
257
std::vector<Colored::Binding> BindingGenerator::Iterator::operator++(int) {
258
auto prev = _generator->currentBinding();
263
std::vector<Colored::Binding>& BindingGenerator::Iterator::operator*() {
264
return _generator->currentBinding();
267
BindingGenerator::BindingGenerator(Colored::Transition& transition,
268
const std::vector<Colored::Arc>& arcs,
269
ColoredPetriNetBuilder::ColorTypeMap& colorTypes)
270
: _colorTypes(colorTypes)
272
//std::cout << "Generating bindings on: " << transition.name << std::endl;
273
_expr = transition.guard;
274
std::set<Colored::Variable*> variables;
275
if (_expr != nullptr) {
276
_expr->getVariables(variables);
278
for (auto ai : transition.arcs) {
279
auto& arc = arcs[ai];
280
//arc->expr->expressionType();
281
assert(arc.expr != nullptr);
282
arc.expr->getVariables(variables);
284
for (auto var : variables) {
285
//printf("BindingGen var: %s\n", var->name.c_str());
286
_bindings.push_back(Colored::Binding {var, &(*var->colorType)[0]});
293
bool BindingGenerator::eval() {
294
if (_expr == nullptr)
297
std::unordered_map<std::string, const Colored::Color*> binding;
298
for (auto& elem : _bindings) {
299
//printf("Evaluating var '%s' with color '%s'\n", elem.var->name.c_str(), elem.color->toString().c_str());
300
binding[elem.var->name] = elem.color;
302
Colored::ExpressionContext context {binding, _colorTypes};
303
return _expr->eval(context);
306
std::vector<Colored::Binding>& BindingGenerator::nextBinding() {
309
for (size_t i = 0; i < _bindings.size(); ++i) {
310
_bindings[i].color = &++(*_bindings[i].color);
311
if (_bindings[i].color->getId() != 0) {
324
std::vector<Colored::Binding>& BindingGenerator::currentBinding() {
328
bool BindingGenerator::isInitial() const {
329
for (auto& b : _bindings) {
330
if (b.color->getId() != 0) return false;
335
BindingGenerator::Iterator BindingGenerator::begin() {
336
return Iterator(this);
339
BindingGenerator::Iterator BindingGenerator::end() {
340
return Iterator(nullptr);