3#include <unordered_map>
12 return ttId | (1ull << ((
sizeof(ttId) * CHAR_BIT) - 1));
20 return (tId << 1) >> 1;
29 std::shared_ptr<storm::expressions::ExpressionManager>
const& exprManager,
30 std::map<storm::expressions::Variable, storm::expressions::Expression>
const& constantsSubstitution)
33 immediateTransitions(itransitions),
34 timedTransitions(ttransitions),
35 partitions(partitions),
36 exprManager(exprManager),
37 constantsSubstitution(constantsSubstitution) {}
44 return immediateTransitions.size();
48 return timedTransitions.size();
52 return this->timedTransitions;
56 return this->immediateTransitions;
63std::shared_ptr<storm::gspn::Marking>
GSPN::getInitialMarking(std::map<uint64_t, uint64_t>& numberOfBits, uint64_t
const& numberOfTotalBits)
const {
64 auto m = std::make_shared<storm::gspn::Marking>(
getNumberOfPlaces(), numberOfBits, numberOfTotalBits);
66 m->setNumberOfTokensAt(place.getID(), place.getNumberOfInitialTokens());
76 if (
id < places.size()) {
78 return &places.at(
id);
84 if (
id < places.size()) {
86 return &places.at(
id);
92 for (
auto& place : places) {
93 if (place.getName() == name) {
101 for (
auto& place : places) {
102 if (place.getName() == name) {
110 for (
auto& trans : timedTransitions) {
111 if (name == trans.getName()) {
119 for (
auto& trans : immediateTransitions) {
120 if (name == trans.getName()) {
129 if (trans !=
nullptr) {
141 return constantsSubstitution;
145 for (
auto const& entry : mapping) {
147 STORM_LOG_THROW(place !=
nullptr, storm::exceptions::InvalidArgumentException,
"No place with name " << entry.first <<
".");
153 outStream <<
"digraph " << this->
getName() <<
" {\n";
156 outStream <<
"\t" <<
"node [shape=ellipse]\n";
158 outStream <<
"\t" << place.getName() <<
" [label=\"" << place.getName() <<
"(" << place.getNumberOfInitialTokens();
159 outStream <<
")\"];\n";
163 outStream <<
"\t" <<
"node [shape=box]\n";
166 outStream <<
"\t" << trans.getName() <<
" [fontcolor=white, style=filled, fillcolor=black, label=<" << trans.getName()
167 <<
"<br/><FONT POINT-SIZE=\"10\"> π = " + std::to_string(trans.getPriority()) <<
"</FONT>>];\n";
171 outStream <<
"\t" << trans.getName() <<
" [label=\"" << trans.getName();
172 outStream <<
"(" << trans.getRate() <<
")\"];\n";
173 STORM_LOG_WARN_COND(trans.hasSingleServerSemantics(),
"Unable to export non-trivial transition semantics");
178 for (
auto const& inEntry : trans.getInputPlaces()) {
179 if (trans.getOutputPlaces().count(inEntry.first) == 0) {
180 outStream <<
"\t" << places.at(inEntry.first).getName() <<
" -> " << trans.getName() <<
"[label=\""
181 << (inEntry.second > 1 ? std::to_string(inEntry.second) :
"") <<
"\"];\n";
185 for (
auto const& inhEntry : trans.getInhibitionPlaces()) {
186 if (trans.getOutputPlaces().count(inhEntry.first) == 0) {
187 outStream <<
"\t" << places.at(inhEntry.first).getName() <<
" -> " << trans.getName() <<
"[arrowhead=\"dot\", label=\""
188 << (inhEntry.second > 1 ? std::to_string(inhEntry.second) :
"") <<
"\"];\n";
192 for (
auto const& outEntry : trans.getOutputPlaces()) {
193 if (trans.getInhibitionPlaces().count(outEntry.first) == 1) {
194 outStream <<
"\t" << trans.getName() <<
" -> " << places.at(outEntry.first).getName() <<
"[arrowtail=\"dot\", label=\""
195 << (outEntry.second > 1 ? std::to_string(outEntry.second) :
"") <<
"\", dir=both];\n";
196 }
else if (trans.getInputPlaces().count(outEntry.first) == 1) {
197 outStream <<
"\t" << trans.getName() <<
" -> " << places.at(outEntry.first).getName() <<
"[label=\""
198 << (outEntry.second > 1 ? std::to_string(outEntry.second) :
"") <<
"\", dir=both];\n";
200 outStream <<
"\t" << trans.getName() <<
" -> " << places.at(outEntry.first).getName() <<
"[label=\""
201 << (outEntry.second > 1 ? std::to_string(outEntry.second) :
"") <<
"\"];\n";
207 for (
auto const& inEntry : trans.getInputPlaces()) {
208 if (trans.getOutputPlaces().count(inEntry.first) == 0) {
209 outStream <<
"\t" << places.at(inEntry.first).getName() <<
" -> " << trans.getName() <<
"[label=\""
210 << (inEntry.second > 1 ? std::to_string(inEntry.second) :
"") <<
"\"];\n";
214 for (
auto const& inhEntry : trans.getInhibitionPlaces()) {
215 if (trans.getOutputPlaces().count(inhEntry.first) == 0) {
216 outStream <<
"\t" << places.at(inhEntry.first).getName() <<
" -> " << trans.getName() <<
"[arrowhead=\"dot\", label=\""
217 << (inhEntry.second > 1 ? std::to_string(inhEntry.second) :
"") <<
"\"];\n";
221 for (
auto const& outEntry : trans.getOutputPlaces()) {
222 if (trans.getInhibitionPlaces().count(outEntry.first) == 1) {
223 outStream <<
"\t" << trans.getName() <<
" -> " << places.at(outEntry.first).getName() <<
"[arrowtail=\"dot\", label=\""
224 << (outEntry.second > 1 ? std::to_string(outEntry.second) :
"") <<
"\", dir=both];\n";
225 }
else if (trans.getInputPlaces().count(outEntry.first) == 1) {
226 outStream <<
"\t" << trans.getName() <<
" -> " << places.at(outEntry.first).getName() <<
"[label=\""
227 << (outEntry.second > 1 ? std::to_string(outEntry.second) :
"") <<
"\", dir=both];\n";
229 outStream <<
"\t" << trans.getName() <<
" -> " << places.at(outEntry.first).getName() <<
"[label=\""
230 << (outEntry.second > 1 ? std::to_string(outEntry.second) :
"") <<
"\"];\n";
248 result |= testPlaces();
249 result |= testTransitions();
254bool GSPN::testPlaces()
const {
255 std::vector<std::string> namesOfPlaces;
256 std::vector<uint64_t> idsOfPlaces;
259 for (
auto const& place : this->
getPlaces()) {
260 if (std::find(namesOfPlaces.begin(), namesOfPlaces.end(), place.getName()) != namesOfPlaces.end()) {
261 STORM_LOG_WARN(
"duplicates states with the name \"" + place.getName() +
"\"\n");
265 if (std::find(idsOfPlaces.begin(), idsOfPlaces.end(), place.getID()) != idsOfPlaces.end()) {
266 STORM_LOG_WARN(
"duplicates states with the id \"" + std::to_string(place.getID()) +
"\"\n");
270 if (place.getNumberOfInitialTokens() > place.getCapacity()) {
271 STORM_LOG_WARN(
"number of initial tokens is greater than the capacity for place \"" + place.getName() +
"\"\n");
279bool GSPN::testTransitions()
const {
395 placeLayout[placeId] = layout;
398 transitionLayout[transitionId] = layout;
402 this->placeLayout = placeLayout;
405 this->transitionLayout = transitionLayout;
409 return this->placeLayout;
413 return this->transitionLayout;
420 auto projectName =
"storm-export";
421 stream <<
"<project name=\"" << projectName <<
"\" version=\"121\">\n";
422 stream << space <<
"<gspn name=\"" <<
getName() <<
"\" >\n";
425 stream << space2 <<
"<nodes>\n";
426 for (
auto& place : places) {
427 stream << space3 <<
"<place marking=\"" << place.getNumberOfInitialTokens() <<
"\" ";
428 stream <<
"name =\"" << place.getName() <<
"\" ";
429 if (placeLayout.count(place.getID()) > 0) {
430 stream <<
"x=\"" << placeLayout.at(place.getID()).x <<
"\" ";
431 stream <<
"y=\"" << placeLayout.at(place.getID()).y <<
"\" ";
433 stream <<
"x=\"" << x <<
"\" ";
434 stream <<
"y=\"1\" ";
440 for (
auto& trans : timedTransitions) {
441 stream << space3 <<
"<transition name=\"" << trans.getName() <<
"\" ";
442 stream <<
"type=\"EXP\" ";
446 stream <<
"nservers=\"1\" ";
448 stream <<
"delay=\"" << std::showpoint << trans.getRate() <<
"\" ";
449 if (transitionLayout.count(trans.getID()) > 0) {
450 stream <<
"x=\"" << transitionLayout.at(trans.getID()).x <<
"\" ";
451 stream <<
"y=\"" << transitionLayout.at(trans.getID()).y <<
"\" ";
453 stream <<
"x=\"" << x <<
"\" ";
454 stream <<
"y=\"4\" ";
459 for (
auto& trans : immediateTransitions) {
460 stream << space3 <<
"<transition name=\"" << trans.getName() <<
"\" ";
461 stream <<
"type=\"IMM\" ";
462 stream <<
"priority=\"" << trans.getPriority() <<
"\" ";
463 stream <<
"weight=\"" << trans.getWeight() <<
"\" ";
464 if (transitionLayout.count(trans.getID()) > 0) {
465 stream <<
"x=\"" << transitionLayout.at(trans.getID()).x <<
"\" ";
466 stream <<
"y=\"" << transitionLayout.at(trans.getID()).y <<
"\" ";
468 stream <<
"x=\"" << x <<
"\" ";
469 stream <<
"y=\"4\" ";
474 stream << space2 <<
"</nodes>\n";
476 stream << space2 <<
"<edges>\n";
477 for (
auto& trans : timedTransitions) {
478 for (
auto const& inEntry : trans.getInputPlaces()) {
479 stream << space3 <<
"<arc ";
480 stream <<
"head=\"" << trans.getName() <<
"\" ";
481 stream <<
"tail=\"" << places.at(inEntry.first).getName() <<
"\" ";
482 stream <<
"kind=\"INPUT\" ";
483 stream <<
"mult=\"" << inEntry.second <<
"\" ";
486 for (
auto const& inhEntry : trans.getInhibitionPlaces()) {
487 stream << space3 <<
"<arc ";
488 stream <<
"head=\"" << trans.getName() <<
"\" ";
489 stream <<
"tail=\"" << places.at(inhEntry.first).getName() <<
"\" ";
490 stream <<
"kind=\"INHIBITOR\" ";
491 stream <<
"mult=\"" << inhEntry.second <<
"\" ";
494 for (
auto const& outEntry : trans.getOutputPlaces()) {
495 stream << space3 <<
"<arc ";
496 stream <<
"head=\"" << places.at(outEntry.first).getName() <<
"\" ";
497 stream <<
"tail=\"" << trans.getName() <<
"\" ";
498 stream <<
"kind=\"OUTPUT\" ";
499 stream <<
"mult=\"" << outEntry.second <<
"\" ";
503 for (
auto& trans : immediateTransitions) {
504 for (
auto const& inEntry : trans.getInputPlaces()) {
505 stream << space3 <<
"<arc ";
506 stream <<
"head=\"" << trans.getName() <<
"\" ";
507 stream <<
"tail=\"" << places.at(inEntry.first).getName() <<
"\" ";
508 stream <<
"kind=\"INPUT\" ";
509 stream <<
"mult=\"" << inEntry.second <<
"\" ";
512 for (
auto const& inhEntry : trans.getInhibitionPlaces()) {
513 stream << space3 <<
"<arc ";
514 stream <<
"head=\"" << trans.getName() <<
"\" ";
515 stream <<
"tail=\"" << places.at(inhEntry.first).getName() <<
"\" ";
516 stream <<
"kind=\"INHIBITOR\" ";
517 stream <<
"mult=\"" << inhEntry.second <<
"\" ";
520 for (
auto const& outEntry : trans.getOutputPlaces()) {
521 stream << space3 <<
"<arc ";
522 stream <<
"head=\"" << places.at(outEntry.first).getName() <<
"\" ";
523 stream <<
"tail=\"" << trans.getName() <<
"\" ";
524 stream <<
"kind=\"OUTPUT\" ";
525 stream <<
"mult=\"" << outEntry.second <<
"\" ";
529 stream << space2 <<
"</edges>\n";
530 stream << space <<
"</gspn>\n";
531 stream <<
"</project>\n";
535 std::string space =
" ";
536 std::string space2 =
" ";
537 std::string space3 =
" ";
538 std::string space4 =
" ";
540 stream <<
"<pnml>\n";
541 stream << space <<
"<net id=\"" <<
getName() <<
"\">\n";
544 for (
const auto& place : places) {
545 stream << space2 <<
"<place id=\"" << place.getName() <<
"\">\n";
546 stream << space3 <<
"<initialMarking>\n";
547 stream << space4 <<
"<value>Default," << place.getNumberOfInitialTokens() <<
"</value>\n";
548 stream << space3 <<
"</initialMarking>\n";
549 if (place.hasRestrictedCapacity()) {
550 stream << space3 <<
"<capacity>\n";
551 stream << space4 <<
"<value>Default," << place.getCapacity() <<
"</value>\n";
552 stream << space3 <<
"</capacity>\n";
554 stream << space2 <<
"</place>\n";
558 for (
const auto& trans : immediateTransitions) {
559 stream << space2 <<
"<transition id=\"" << trans.getName() <<
"\">\n";
560 stream << space3 <<
"<rate>\n";
561 stream << space4 <<
"<value>" << trans.getWeight() <<
"</value>\n";
562 stream << space3 <<
"</rate>\n";
563 stream << space3 <<
"<timed>\n";
564 stream << space4 <<
"<value>false</value>\n";
565 stream << space3 <<
"</timed>\n";
566 stream << space2 <<
"</transition>\n";
570 for (
const auto& trans : timedTransitions) {
571 STORM_LOG_WARN_COND(trans.hasInfiniteServerSemantics(),
"Unable to export non-trivial transition semantics");
572 stream << space2 <<
"<transition id=\"" << trans.getName() <<
"\">\n";
573 stream << space3 <<
"<rate>\n";
574 stream << space4 <<
"<value>" << trans.getRate() <<
"</value>\n";
575 stream << space3 <<
"</rate>\n";
576 stream << space3 <<
"<timed>\n";
577 stream << space4 <<
"<value>true</value>\n";
578 stream << space3 <<
"</timed>\n";
579 stream << space2 <<
"</transition>\n";
584 for (
const auto& trans : immediateTransitions) {
586 for (
auto const& inEntry : trans.getInputPlaces()) {
587 stream << space2 <<
"<arc ";
588 stream <<
"id=\"arc" << i++ <<
"\" ";
589 stream <<
"source=\"" << places.at(inEntry.first).getName() <<
"\" ";
590 stream <<
"target=\"" << trans.getName() <<
"\" ";
593 stream << space3 <<
"<inscription>\n";
594 stream << space4 <<
"<value>Default," << inEntry.second <<
"</value>\n";
595 stream << space3 <<
"</inscription>\n";
597 stream << space3 <<
"<type value=\"normal\" />\n";
599 stream << space2 <<
"</arc>\n";
603 for (
auto const& inhEntry : trans.getInhibitionPlaces()) {
604 stream << space2 <<
"<arc ";
605 stream <<
"id=\"arc" << i++ <<
"\" ";
606 stream <<
"source=\"" << places.at(inhEntry.first).getName() <<
"\" ";
607 stream <<
"target=\"" << trans.getName() <<
"\" ";
610 stream << space3 <<
"<inscription>\n";
611 stream << space4 <<
"<value>Default," << inhEntry.second <<
"</value>\n";
612 stream << space3 <<
"</inscription>\n";
614 stream << space3 <<
"<type value=\"inhibition\" />\n";
616 stream << space2 <<
"</arc>\n";
620 for (
auto const& outEntry : trans.getOutputPlaces()) {
621 stream << space2 <<
"<arc ";
622 stream <<
"id=\"arc" << i++ <<
"\" ";
623 stream <<
"source=\"" << trans.getName() <<
"\" ";
624 stream <<
"target=\"" << places.at(outEntry.first).getName() <<
"\" ";
627 stream << space3 <<
"<inscription>\n";
628 stream << space4 <<
"<value>Default," << outEntry.second <<
"</value>\n";
629 stream << space3 <<
"</inscription>\n";
631 stream << space3 <<
"<type value=\"normal\" />\n";
633 stream << space2 <<
"</arc>\n";
638 for (
const auto& trans : timedTransitions) {
640 for (
auto const& inEntry : trans.getInputPlaces()) {
641 stream << space2 <<
"<arc ";
642 stream <<
"id=\"arc" << i++ <<
"\" ";
643 stream <<
"source=\"" << places.at(inEntry.first).getName() <<
"\" ";
644 stream <<
"target=\"" << trans.getName() <<
"\" ";
647 stream << space3 <<
"<inscription>\n";
648 stream << space4 <<
"<value>Default," << inEntry.second <<
"</value>\n";
649 stream << space3 <<
"</inscription>\n";
651 stream << space3 <<
"<type value=\"normal\" />\n";
653 stream << space2 <<
"</arc>\n";
657 for (
auto const& inhEntry : trans.getInhibitionPlaces()) {
658 stream << space2 <<
"<arc ";
659 stream <<
"id=\"arc" << i++ <<
"\" ";
660 stream <<
"source=\"" << places.at(inhEntry.first).getName() <<
"\" ";
661 stream <<
"target=\"" << trans.getName() <<
"\" ";
664 stream << space3 <<
"<inscription>\n";
665 stream << space4 <<
"<value>Default," << inhEntry.second <<
"</value>\n";
666 stream << space3 <<
"</inscription>\n";
668 stream << space3 <<
"<type value=\"inhibition\" />\n";
670 stream << space2 <<
"</arc>\n";
674 for (
auto const& outEntry : trans.getOutputPlaces()) {
675 stream << space2 <<
"<arc ";
676 stream <<
"id=\"arc" << i++ <<
"\" ";
677 stream <<
"source=\"" << trans.getName() <<
"\" ";
678 stream <<
"target=\"" << places.at(outEntry.first).getName() <<
"\" ";
681 stream << space3 <<
"<inscription>\n";
682 stream << space4 <<
"<value>Default," << outEntry.second <<
"</value>\n";
683 stream << space3 <<
"</inscription>\n";
685 stream << space3 <<
"<type value=\"normal\" />\n";
687 stream << space2 <<
"</arc>\n";
691 stream << space <<
"</net>\n";
692 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(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_WARN_COND(cond, message)
#define STORM_LOG_THROW(cond, exception, message)