3#include <unordered_map>
5#include <boost/lexical_cast.hpp>
14 return ttId | (1ull << ((
sizeof(ttId) * CHAR_BIT) - 1));
22 return (tId << 1) >> 1;
31 std::shared_ptr<storm::expressions::ExpressionManager>
const& exprManager,
32 std::map<storm::expressions::Variable, storm::expressions::Expression>
const& constantsSubstitution)
35 immediateTransitions(itransitions),
36 timedTransitions(ttransitions),
37 partitions(partitions),
38 exprManager(exprManager),
39 constantsSubstitution(constantsSubstitution) {}
46 return immediateTransitions.size();
50 return timedTransitions.size();
54 return this->timedTransitions;
58 return this->immediateTransitions;
65std::shared_ptr<storm::gspn::Marking>
GSPN::getInitialMarking(std::map<uint64_t, uint64_t>& numberOfBits, uint64_t
const& numberOfTotalBits)
const {
66 auto m = std::make_shared<storm::gspn::Marking>(
getNumberOfPlaces(), numberOfBits, numberOfTotalBits);
68 m->setNumberOfTokensAt(place.getID(), place.getNumberOfInitialTokens());
78 if (
id < places.size()) {
79 assert(places.at(
id).getID() ==
id);
80 return &places.at(
id);
86 if (
id < places.size()) {
87 assert(places.at(
id).getID() ==
id);
88 return &places.at(
id);
94 for (
auto& place : places) {
95 if (place.getName() == name) {
103 for (
auto& place : places) {
104 if (place.getName() == name) {
112 for (
auto& trans : timedTransitions) {
113 if (name == trans.getName()) {
121 for (
auto& trans : immediateTransitions) {
122 if (name == trans.getName()) {
131 if (trans !=
nullptr) {
143 return constantsSubstitution;
147 for (
auto const& entry : mapping) {
149 STORM_LOG_THROW(place !=
nullptr, storm::exceptions::InvalidArgumentException,
"No place with name " << entry.first);
155 outStream <<
"digraph " << this->
getName() <<
" {\n";
158 outStream <<
"\t" <<
"node [shape=ellipse]\n";
160 outStream <<
"\t" << place.getName() <<
" [label=\"" << place.getName() <<
"(" << place.getNumberOfInitialTokens();
161 outStream <<
")\"];\n";
165 outStream <<
"\t" <<
"node [shape=box]\n";
168 outStream <<
"\t" << trans.getName() <<
" [fontcolor=white, style=filled, fillcolor=black, label=<" << trans.getName()
169 <<
"<br/><FONT POINT-SIZE=\"10\"> π = " + std::to_string(trans.getPriority()) <<
"</FONT>>];\n";
173 outStream <<
"\t" << trans.getName() <<
" [label=\"" << trans.getName();
174 outStream <<
"(" << trans.getRate() <<
")\"];\n";
175 STORM_LOG_WARN_COND(trans.hasSingleServerSemantics(),
"Unable to export non-trivial transition semantics");
180 for (
auto const& inEntry : trans.getInputPlaces()) {
181 if (trans.getOutputPlaces().count(inEntry.first) == 0) {
182 outStream <<
"\t" << places.at(inEntry.first).getName() <<
" -> " << trans.getName() <<
"[label=\""
183 << (inEntry.second > 1 ? std::to_string(inEntry.second) :
"") <<
"\"];\n";
187 for (
auto const& inhEntry : trans.getInhibitionPlaces()) {
188 if (trans.getOutputPlaces().count(inhEntry.first) == 0) {
189 outStream <<
"\t" << places.at(inhEntry.first).getName() <<
" -> " << trans.getName() <<
"[arrowhead=\"dot\", label=\""
190 << (inhEntry.second > 1 ? std::to_string(inhEntry.second) :
"") <<
"\"];\n";
194 for (
auto const& outEntry : trans.getOutputPlaces()) {
195 if (trans.getInhibitionPlaces().count(outEntry.first) == 1) {
196 outStream <<
"\t" << trans.getName() <<
" -> " << places.at(outEntry.first).getName() <<
"[arrowtail=\"dot\", label=\""
197 << (outEntry.second > 1 ? std::to_string(outEntry.second) :
"") <<
"\", dir=both];\n";
198 }
else if (trans.getInputPlaces().count(outEntry.first) == 1) {
199 outStream <<
"\t" << trans.getName() <<
" -> " << places.at(outEntry.first).getName() <<
"[label=\""
200 << (outEntry.second > 1 ? std::to_string(outEntry.second) :
"") <<
"\", dir=both];\n";
202 outStream <<
"\t" << trans.getName() <<
" -> " << places.at(outEntry.first).getName() <<
"[label=\""
203 << (outEntry.second > 1 ? std::to_string(outEntry.second) :
"") <<
"\"];\n";
209 for (
auto const& inEntry : trans.getInputPlaces()) {
210 if (trans.getOutputPlaces().count(inEntry.first) == 0) {
211 outStream <<
"\t" << places.at(inEntry.first).getName() <<
" -> " << trans.getName() <<
"[label=\""
212 << (inEntry.second > 1 ? std::to_string(inEntry.second) :
"") <<
"\"];\n";
216 for (
auto const& inhEntry : trans.getInhibitionPlaces()) {
217 if (trans.getOutputPlaces().count(inhEntry.first) == 0) {
218 outStream <<
"\t" << places.at(inhEntry.first).getName() <<
" -> " << trans.getName() <<
"[arrowhead=\"dot\", label=\""
219 << (inhEntry.second > 1 ? std::to_string(inhEntry.second) :
"") <<
"\"];\n";
223 for (
auto const& outEntry : trans.getOutputPlaces()) {
224 if (trans.getInhibitionPlaces().count(outEntry.first) == 1) {
225 outStream <<
"\t" << trans.getName() <<
" -> " << places.at(outEntry.first).getName() <<
"[arrowtail=\"dot\", label=\""
226 << (outEntry.second > 1 ? std::to_string(outEntry.second) :
"") <<
"\", dir=both];\n";
227 }
else if (trans.getInputPlaces().count(outEntry.first) == 1) {
228 outStream <<
"\t" << trans.getName() <<
" -> " << places.at(outEntry.first).getName() <<
"[label=\""
229 << (outEntry.second > 1 ? std::to_string(outEntry.second) :
"") <<
"\", dir=both];\n";
231 outStream <<
"\t" << trans.getName() <<
" -> " << places.at(outEntry.first).getName() <<
"[label=\""
232 << (outEntry.second > 1 ? std::to_string(outEntry.second) :
"") <<
"\"];\n";
250 result |= testPlaces();
251 result |= testTransitions();
256bool GSPN::testPlaces()
const {
257 std::vector<std::string> namesOfPlaces;
258 std::vector<uint64_t> idsOfPlaces;
261 for (
auto const& place : this->
getPlaces()) {
262 if (std::find(namesOfPlaces.begin(), namesOfPlaces.end(), place.getName()) != namesOfPlaces.end()) {
267 if (std::find(idsOfPlaces.begin(), idsOfPlaces.end(), place.getID()) != idsOfPlaces.end()) {
268 STORM_PRINT_AND_LOG(
"duplicates states with the id \"" + boost::lexical_cast<std::string>(place.getID()) +
"\"\n");
272 if (place.getNumberOfInitialTokens() > place.getNumberOfInitialTokens()) {
273 STORM_PRINT_AND_LOG(
"number of initial tokens is greater than the capacity for place \"" + place.getName() +
"\"\n");
281bool GSPN::testTransitions()
const {
397 placeLayout[placeId] = layout;
400 transitionLayout[transitionId] = layout;
404 this->placeLayout = placeLayout;
407 this->transitionLayout = transitionLayout;
411 return this->placeLayout;
415 return this->transitionLayout;
422 auto projectName =
"storm-export";
423 stream <<
"<project name=\"" << projectName <<
"\" version=\"121\">\n";
424 stream << space <<
"<gspn name=\"" <<
getName() <<
"\" >\n";
427 stream << space2 <<
"<nodes>\n";
428 for (
auto& place : places) {
429 stream << space3 <<
"<place marking=\"" << place.getNumberOfInitialTokens() <<
"\" ";
430 stream <<
"name =\"" << place.getName() <<
"\" ";
431 if (placeLayout.count(place.getID()) > 0) {
432 stream <<
"x=\"" << placeLayout.at(place.getID()).x <<
"\" ";
433 stream <<
"y=\"" << placeLayout.at(place.getID()).y <<
"\" ";
435 stream <<
"x=\"" << x <<
"\" ";
436 stream <<
"y=\"1\" ";
442 for (
auto& trans : timedTransitions) {
443 stream << space3 <<
"<transition name=\"" << trans.getName() <<
"\" ";
444 stream <<
"type=\"EXP\" ";
448 stream <<
"nservers=\"1\" ";
450 stream <<
"delay=\"" << std::showpoint << trans.getRate() <<
"\" ";
451 if (transitionLayout.count(trans.getID()) > 0) {
452 stream <<
"x=\"" << transitionLayout.at(trans.getID()).x <<
"\" ";
453 stream <<
"y=\"" << transitionLayout.at(trans.getID()).y <<
"\" ";
455 stream <<
"x=\"" << x <<
"\" ";
456 stream <<
"y=\"4\" ";
461 for (
auto& trans : immediateTransitions) {
462 stream << space3 <<
"<transition name=\"" << trans.getName() <<
"\" ";
463 stream <<
"type=\"IMM\" ";
464 stream <<
"priority=\"" << trans.getPriority() <<
"\" ";
465 stream <<
"weight=\"" << trans.getWeight() <<
"\" ";
466 if (transitionLayout.count(trans.getID()) > 0) {
467 stream <<
"x=\"" << transitionLayout.at(trans.getID()).x <<
"\" ";
468 stream <<
"y=\"" << transitionLayout.at(trans.getID()).y <<
"\" ";
470 stream <<
"x=\"" << x <<
"\" ";
471 stream <<
"y=\"4\" ";
476 stream << space2 <<
"</nodes>\n";
478 stream << space2 <<
"<edges>\n";
479 for (
auto& trans : timedTransitions) {
480 for (
auto const& inEntry : trans.getInputPlaces()) {
481 stream << space3 <<
"<arc ";
482 stream <<
"head=\"" << trans.getName() <<
"\" ";
483 stream <<
"tail=\"" << places.at(inEntry.first).getName() <<
"\" ";
484 stream <<
"kind=\"INPUT\" ";
485 stream <<
"mult=\"" << inEntry.second <<
"\" ";
488 for (
auto const& inhEntry : trans.getInhibitionPlaces()) {
489 stream << space3 <<
"<arc ";
490 stream <<
"head=\"" << trans.getName() <<
"\" ";
491 stream <<
"tail=\"" << places.at(inhEntry.first).getName() <<
"\" ";
492 stream <<
"kind=\"INHIBITOR\" ";
493 stream <<
"mult=\"" << inhEntry.second <<
"\" ";
496 for (
auto const& outEntry : trans.getOutputPlaces()) {
497 stream << space3 <<
"<arc ";
498 stream <<
"head=\"" << places.at(outEntry.first).getName() <<
"\" ";
499 stream <<
"tail=\"" << trans.getName() <<
"\" ";
500 stream <<
"kind=\"OUTPUT\" ";
501 stream <<
"mult=\"" << outEntry.second <<
"\" ";
505 for (
auto& trans : immediateTransitions) {
506 for (
auto const& inEntry : trans.getInputPlaces()) {
507 stream << space3 <<
"<arc ";
508 stream <<
"head=\"" << trans.getName() <<
"\" ";
509 stream <<
"tail=\"" << places.at(inEntry.first).getName() <<
"\" ";
510 stream <<
"kind=\"INPUT\" ";
511 stream <<
"mult=\"" << inEntry.second <<
"\" ";
514 for (
auto const& inhEntry : trans.getInhibitionPlaces()) {
515 stream << space3 <<
"<arc ";
516 stream <<
"head=\"" << trans.getName() <<
"\" ";
517 stream <<
"tail=\"" << places.at(inhEntry.first).getName() <<
"\" ";
518 stream <<
"kind=\"INHIBITOR\" ";
519 stream <<
"mult=\"" << inhEntry.second <<
"\" ";
522 for (
auto const& outEntry : trans.getOutputPlaces()) {
523 stream << space3 <<
"<arc ";
524 stream <<
"head=\"" << places.at(outEntry.first).getName() <<
"\" ";
525 stream <<
"tail=\"" << trans.getName() <<
"\" ";
526 stream <<
"kind=\"OUTPUT\" ";
527 stream <<
"mult=\"" << outEntry.second <<
"\" ";
531 stream << space2 <<
"</edges>\n";
532 stream << space <<
"</gspn>\n";
533 stream <<
"</project>\n";
537 std::string space =
" ";
538 std::string space2 =
" ";
539 std::string space3 =
" ";
540 std::string space4 =
" ";
542 stream <<
"<pnml>\n";
543 stream << space <<
"<net id=\"" <<
getName() <<
"\">\n";
546 for (
const auto& place : places) {
547 stream << space2 <<
"<place id=\"" << place.getName() <<
"\">\n";
548 stream << space3 <<
"<initialMarking>\n";
549 stream << space4 <<
"<value>Default," << place.getNumberOfInitialTokens() <<
"</value>\n";
550 stream << space3 <<
"</initialMarking>\n";
551 if (place.hasRestrictedCapacity()) {
552 stream << space3 <<
"<capacity>\n";
553 stream << space4 <<
"<value>Default," << place.getCapacity() <<
"</value>\n";
554 stream << space3 <<
"</capacity>\n";
556 stream << space2 <<
"</place>\n";
560 for (
const auto& trans : immediateTransitions) {
561 stream << space2 <<
"<transition id=\"" << trans.getName() <<
"\">\n";
562 stream << space3 <<
"<rate>\n";
563 stream << space4 <<
"<value>" << trans.getWeight() <<
"</value>\n";
564 stream << space3 <<
"</rate>\n";
565 stream << space3 <<
"<timed>\n";
566 stream << space4 <<
"<value>false</value>\n";
567 stream << space3 <<
"</timed>\n";
568 stream << space2 <<
"</transition>\n";
572 for (
const auto& trans : timedTransitions) {
573 STORM_LOG_WARN_COND(trans.hasInfiniteServerSemantics(),
"Unable to export non-trivial transition semantics");
574 stream << space2 <<
"<transition id=\"" << trans.getName() <<
"\">\n";
575 stream << space3 <<
"<rate>\n";
576 stream << space4 <<
"<value>" << trans.getRate() <<
"</value>\n";
577 stream << space3 <<
"</rate>\n";
578 stream << space3 <<
"<timed>\n";
579 stream << space4 <<
"<value>true</value>\n";
580 stream << space3 <<
"</timed>\n";
581 stream << space2 <<
"</transition>\n";
586 for (
const auto& trans : immediateTransitions) {
588 for (
auto const& inEntry : trans.getInputPlaces()) {
589 stream << space2 <<
"<arc ";
590 stream <<
"id=\"arc" << i++ <<
"\" ";
591 stream <<
"source=\"" << places.at(inEntry.first).getName() <<
"\" ";
592 stream <<
"target=\"" << trans.getName() <<
"\" ";
595 stream << space3 <<
"<inscription>\n";
596 stream << space4 <<
"<value>Default," << inEntry.second <<
"</value>\n";
597 stream << space3 <<
"</inscription>\n";
599 stream << space3 <<
"<type value=\"normal\" />\n";
601 stream << space2 <<
"</arc>\n";
605 for (
auto const& inhEntry : trans.getInhibitionPlaces()) {
606 stream << space2 <<
"<arc ";
607 stream <<
"id=\"arc" << i++ <<
"\" ";
608 stream <<
"source=\"" << places.at(inhEntry.first).getName() <<
"\" ";
609 stream <<
"target=\"" << trans.getName() <<
"\" ";
612 stream << space3 <<
"<inscription>\n";
613 stream << space4 <<
"<value>Default," << inhEntry.second <<
"</value>\n";
614 stream << space3 <<
"</inscription>\n";
616 stream << space3 <<
"<type value=\"inhibition\" />\n";
618 stream << space2 <<
"</arc>\n";
622 for (
auto const& outEntry : trans.getOutputPlaces()) {
623 stream << space2 <<
"<arc ";
624 stream <<
"id=\"arc" << i++ <<
"\" ";
625 stream <<
"source=\"" << trans.getName() <<
"\" ";
626 stream <<
"target=\"" << places.at(outEntry.first).getName() <<
"\" ";
629 stream << space3 <<
"<inscription>\n";
630 stream << space4 <<
"<value>Default," << outEntry.second <<
"</value>\n";
631 stream << space3 <<
"</inscription>\n";
633 stream << space3 <<
"<type value=\"normal\" />\n";
635 stream << space2 <<
"</arc>\n";
640 for (
const auto& trans : timedTransitions) {
642 for (
auto const& inEntry : trans.getInputPlaces()) {
643 stream << space2 <<
"<arc ";
644 stream <<
"id=\"arc" << i++ <<
"\" ";
645 stream <<
"source=\"" << places.at(inEntry.first).getName() <<
"\" ";
646 stream <<
"target=\"" << trans.getName() <<
"\" ";
649 stream << space3 <<
"<inscription>\n";
650 stream << space4 <<
"<value>Default," << inEntry.second <<
"</value>\n";
651 stream << space3 <<
"</inscription>\n";
653 stream << space3 <<
"<type value=\"normal\" />\n";
655 stream << space2 <<
"</arc>\n";
659 for (
auto const& inhEntry : trans.getInhibitionPlaces()) {
660 stream << space2 <<
"<arc ";
661 stream <<
"id=\"arc" << i++ <<
"\" ";
662 stream <<
"source=\"" << places.at(inhEntry.first).getName() <<
"\" ";
663 stream <<
"target=\"" << trans.getName() <<
"\" ";
666 stream << space3 <<
"<inscription>\n";
667 stream << space4 <<
"<value>Default," << inhEntry.second <<
"</value>\n";
668 stream << space3 <<
"</inscription>\n";
670 stream << space3 <<
"<type value=\"inhibition\" />\n";
672 stream << space2 <<
"</arc>\n";
676 for (
auto const& outEntry : trans.getOutputPlaces()) {
677 stream << space2 <<
"<arc ";
678 stream <<
"id=\"arc" << i++ <<
"\" ";
679 stream <<
"source=\"" << trans.getName() <<
"\" ";
680 stream <<
"target=\"" << places.at(outEntry.first).getName() <<
"\" ";
683 stream << space3 <<
"<inscription>\n";
684 stream << space4 <<
"<value>Default," << outEntry.second <<
"</value>\n";
685 stream << space3 <<
"</inscription>\n";
687 stream << space3 <<
"<type value=\"normal\" />\n";
689 stream << space2 <<
"</arc>\n";
693 stream << space <<
"</net>\n";
694 stream <<
"</pnml>\n";
bool isValid() const
Performe some checks.
static uint64_t immediateTransitionIdToTransitionId(uint64_t)
uint64_t getNumberOfPlaces() const
Returns the number of places in this gspn.
static uint64_t timedTransitionIdToTransitionId(uint64_t)
storm::gspn::ImmediateTransition< GSPN::WeightType > const * getImmediateTransition(std::string const &name) const
Returns the immediate transition with the corresponding name.
uint64_t getNumberOfTimedTransitions() const
uint64_t getNumberOfImmediateTransitions() const
void toPnml(std::ostream &stream) const
void setName(std::string const &name)
Set the name of the gspn to the given name.
void setTransitionLayoutInfo(uint64_t transitionId, LayoutInfo const &layout) const
std::map< uint64_t, LayoutInfo > const & getTransitionLayoutInfos() const
GSPN(std::string const &name, std::vector< Place > const &places, std::vector< ImmediateTransition< WeightType > > const &itransitions, std::vector< TimedTransition< RateType > > const &ttransitions, std::vector< TransitionPartition > const &partitions, std::shared_ptr< storm::expressions::ExpressionManager > const &exprManager, std::map< storm::expressions::Variable, storm::expressions::Expression > const &constantsSubstitution=std::map< storm::expressions::Variable, storm::expressions::Expression >())
std::vector< ImmediateTransition< GSPN::WeightType > > const & getImmediateTransitions() const
Returns the vector of immediate transitions in this gspn.
void setCapacities(std::unordered_map< std::string, uint64_t > const &mapping)
Set Capacities of places according to name->capacity map.
static uint64_t transitionIdToTimedTransitionId(uint64_t)
std::shared_ptr< storm::gspn::Marking > getInitialMarking(std::map< uint64_t, uint64_t > &numberOfBits, uint64_t const &numberOfTotalBits) const
void toJson(std::ostream &stream) const
Export GSPN in Json format.
std::map< storm::expressions::Variable, storm::expressions::Expression > const & getConstantsSubstitution() const
Gets an assignment of occurring constants of the GSPN to their value.
void writeStatsToStream(std::ostream &stream) const
std::vector< TransitionPartition > const & getPartitions() const
std::vector< storm::gspn::Place > const & getPlaces() const
Returns the places of this gspn.
std::map< uint64_t, LayoutInfo > const & getPlaceLayoutInfos() const
storm::gspn::Transition const * getTransition(std::string const &name) const
Returns the transition with the corresponding name.
void setPlaceLayoutInfo(uint64_t placeId, LayoutInfo const &layout) const
void toPnpro(std::ostream &stream) const
storm::gspn::TimedTransition< GSPN::RateType > const * getTimedTransition(std::string const &name) const
Returns the timed transition with the corresponding name.
std::shared_ptr< storm::expressions::ExpressionManager > const & getExpressionManager() const
Obtain the expression manager used for expressions over GSPNs.
storm::gspn::Place const * getPlace(uint64_t id) const
Returns the place with the corresponding id.
static uint64_t transitionIdToImmediateTransitionId(uint64_t)
std::vector< TimedTransition< GSPN::RateType > > const & getTimedTransitions() const
Returns the vector of timed transitions in this gspn.
std::string const & getName() const
Returns the name of the gspn.
void writeDotToStream(std::ostream &outStream) const
Write the gspn in a dot(graphviz) configuration.
static void toStream(storm::gspn::GSPN const &gspn, std::ostream &os)
This class provides methods to store and retrieve data for a place in a gspn.
void setCapacity(boost::optional< uint64_t > const &capacity)
Sets the capacity of tokens of this place.
This class represents a transition in a gspn.
#define STORM_LOG_WARN_COND(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
#define STORM_PRINT_AND_LOG(message)