2
* File: ColoredPetriNetBuilder.cpp
5
* Created on 17. februar 2018, 16:25
8
#include "PetriEngine/Colored/ColoredPetriNetBuilder.h"
11
namespace PetriEngine {
12
ColoredPetriNetBuilder::ColoredPetriNetBuilder() {
15
ColoredPetriNetBuilder::ColoredPetriNetBuilder(const ColoredPetriNetBuilder& orig) {
18
ColoredPetriNetBuilder::~ColoredPetriNetBuilder() {
21
void ColoredPetriNetBuilder::addPlace(const std::string& name, int tokens, double x, double y) {
23
_ptBuilder.addPlace(name, tokens, x, y);
27
void ColoredPetriNetBuilder::addPlace(const std::string& name, Colored::ColorType* type, Colored::Multiset&& tokens, double x, double y) {
28
if(_placenames.count(name) == 0)
30
uint32_t next = _placenames.size();
31
_places.emplace_back(Colored::Place {name, type, tokens});
32
_placenames[name] = next;
36
void ColoredPetriNetBuilder::addTransition(const std::string& name, double x, double y) {
38
_ptBuilder.addTransition(name, x, y);
42
void ColoredPetriNetBuilder::addTransition(const std::string& name, const Colored::GuardExpression_ptr& guard, double x, double y) {
43
if(_transitionnames.count(name) == 0)
45
uint32_t next = _transitionnames.size();
46
_transitions.emplace_back(Colored::Transition {name, guard});
47
_transitionnames[name] = next;
51
void ColoredPetriNetBuilder::addInputArc(const std::string& place, const std::string& transition, bool inhibitor, int weight) {
53
_ptBuilder.addInputArc(place, transition, inhibitor, weight);
57
void ColoredPetriNetBuilder::addInputArc(const std::string& place, const std::string& transition, const Colored::ArcExpression_ptr& expr) {
58
addArc(place, transition, expr, true);
61
void ColoredPetriNetBuilder::addOutputArc(const std::string& transition, const std::string& place, int weight) {
63
_ptBuilder.addOutputArc(transition, place, weight);
67
void ColoredPetriNetBuilder::addOutputArc(const std::string& transition, const std::string& place, const Colored::ArcExpression_ptr& expr) {
68
addArc(place, transition, expr, false);
71
void ColoredPetriNetBuilder::addArc(const std::string& place, const std::string& transition, const Colored::ArcExpression_ptr& expr, bool input) {
72
if(_transitionnames.count(transition) == 0)
74
std::cout << "Transition '" << transition << "' not found. Adding it." << std::endl;
75
addTransition(transition,0.0,0.0);
77
if(_placenames.count(place) == 0)
79
std::cout << "Place '" << place << "' not found. Adding it." << std::endl;
80
addPlace(place,0,0,0);
82
uint32_t p = _placenames[place];
83
uint32_t t = _transitionnames[transition];
85
assert(t < _transitions.size());
86
assert(p < _places.size());
91
assert(expr != nullptr);
92
arc.expr = std::move(expr);
94
_transitions[t].arcs.push_back(std::move(arc));
97
void ColoredPetriNetBuilder::addColorType(const std::string& id, Colored::ColorType* type) {
101
void ColoredPetriNetBuilder::sort() {
105
PetriNetBuilder& ColoredPetriNetBuilder::unfold() {
106
if (_stripped) assert(false);
107
if (_isColored && !_unfolded) {
108
auto start = std::chrono::high_resolution_clock::now();
109
for (auto& place : _places) {
113
for (auto& transition : _transitions) {
114
unfoldTransition(transition);
118
auto end = std::chrono::high_resolution_clock::now();
119
_time = (std::chrono::duration_cast<std::chrono::microseconds>(end - start).count())*0.000001;
125
void ColoredPetriNetBuilder::unfoldPlace(Colored::Place& place) {
126
for (size_t i = 0; i < place.type->size(); ++i) {
127
std::string name = place.name + ";" + std::to_string(i);
128
const Colored::Color* color = &place.type->operator[](i);
129
_ptBuilder.addPlace(name, place.marking[color], 0.0, 0.0);
130
_ptplacenames[place.name][color->getId()] = std::move(name);
135
void ColoredPetriNetBuilder::unfoldTransition(Colored::Transition& transition) {
136
BindingGenerator gen(transition, _arcs, _colors);
138
for (auto& b : gen) {
139
std::string name = transition.name + ";" + std::to_string(i++);
140
_ptBuilder.addTransition(name, 0.0, 0.0);
141
_pttransitionnames[transition.name].push_back(name);
143
for (auto& arc : transition.arcs) {
144
unfoldArc(arc, b, name);
149
void ColoredPetriNetBuilder::unfoldArc(Colored::Arc& arc, Colored::ExpressionContext::BindingMap& binding, std::string& tName) {
150
Colored::ExpressionContext context {binding, _colors};
151
auto ms = arc.expr->eval(context);
153
for (const auto& color : ms) {
154
if (color.second == 0) {
157
const std::string& pName = _ptplacenames[_places[arc.place].name][color.first->getId()];
159
_ptBuilder.addInputArc(pName, tName, false, color.second);
161
_ptBuilder.addOutputArc(tName, pName, color.second);
167
PetriNetBuilder& ColoredPetriNetBuilder::stripColors() {
168
if (_unfolded) assert(false);
169
if (_isColored && !_stripped) {
170
for (auto& place : _places) {
171
_ptBuilder.addPlace(place.name, place.marking.size(), 0.0, 0.0);
174
for (auto& transition : _transitions) {
175
_ptBuilder.addTransition(transition.name, 0.0, 0.0);
176
for (auto& arc : transition.arcs) {
179
_ptBuilder.addInputArc(_places[arc.place].name, _transitions[arc.transition].name, false,
182
_ptBuilder.addOutputArc(_transitions[arc.transition].name, _places[arc.place].name,
185
} catch (Colored::WeightException& e) {
186
std::cerr << "Exception on arc: " << arcToString(arc) << std::endl;
187
std::cerr << "In expression: " << arc.expr->toString() << std::endl;
188
std::cerr << e.what() << std::endl;
201
std::string ColoredPetriNetBuilder::arcToString(Colored::Arc& arc) const {
202
return !arc.input ? "(" + _transitions[arc.transition].name + ", " + _places[arc.place].name + ")" :
203
"(" + _places[arc.place].name + ", " + _transitions[arc.transition].name + ")";
206
BindingGenerator::Iterator::Iterator(BindingGenerator* generator)
207
: _generator(generator)
211
bool BindingGenerator::Iterator::operator==(Iterator& other) {
212
return _generator == other._generator;
215
bool BindingGenerator::Iterator::operator!=(Iterator& other) {
216
return _generator != other._generator;
219
BindingGenerator::Iterator& BindingGenerator::Iterator::operator++() {
220
_generator->nextBinding();
221
if (_generator->isInitial()) _generator = nullptr;
225
const Colored::ExpressionContext::BindingMap BindingGenerator::Iterator::operator++(int) {
226
auto prev = _generator->currentBinding();
231
Colored::ExpressionContext::BindingMap& BindingGenerator::Iterator::operator*() {
232
return _generator->currentBinding();
235
BindingGenerator::BindingGenerator(Colored::Transition& transition,
236
const std::vector<Colored::Arc>& arcs,
237
ColoredPetriNetBuilder::ColorTypeMap& colorTypes)
238
: _colorTypes(colorTypes)
240
_expr = transition.guard;
241
std::set<Colored::Variable*> variables;
242
if (_expr != nullptr) {
243
_expr->getVariables(variables);
245
for (auto arc : transition.arcs) {
246
assert(arc.expr != nullptr);
247
arc.expr->getVariables(variables);
249
for (auto var : variables) {
250
_bindings[var->name] = &var->colorType->operator[](0);
257
bool BindingGenerator::eval() {
258
if (_expr == nullptr)
261
Colored::ExpressionContext context {_bindings, _colorTypes};
262
return _expr->eval(context);
265
Colored::ExpressionContext::BindingMap& BindingGenerator::nextBinding() {
268
for (auto& _binding : _bindings) {
269
_binding.second = &_binding.second->operator++();
270
if (_binding.second->getId() != 0) {
283
Colored::ExpressionContext::BindingMap& BindingGenerator::currentBinding() {
287
bool BindingGenerator::isInitial() const {
288
for (auto& b : _bindings) {
289
if (b.second->getId() != 0) return false;
294
BindingGenerator::Iterator BindingGenerator::begin() {
298
BindingGenerator::Iterator BindingGenerator::end() {