Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
EliminateAutomaticallyAction.cpp
Go to the documentation of this file.
2#include "EliminateAction.h"
3
5
6namespace storm {
7namespace jani {
8namespace elimination_actions {
10 uint32_t transitionCountThreshold, bool restrictToUnnamedActions)
11 : automatonName(automatonName),
12 eliminationOrder(order),
13 restrictToUnnamedActions(restrictToUnnamedActions),
14 transitionCountThreshold(transitionCountThreshold) {}
15
17 return "EliminateAutomaticallyAction";
18}
19
21 Automaton* automaton = &session.getModel().getAutomaton(automatonName);
22 switch (eliminationOrder) {
24 STORM_LOG_THROW(!restrictToUnnamedActions, storm::exceptions::NotImplementedException,
25 "Cannot perform automatic elimination if restrictToUnnamedActions is true and elimination order is arbitrary.");
26
27 for (const auto& loc : automaton->getLocations()) {
28 if (session.isEliminable(automatonName, loc.getName())) {
29 STORM_LOG_TRACE("Eliminating location " + loc.getName());
30 EliminateAction action = EliminateAction(automatonName, loc.getName());
31 action.doAction(session);
32 }
33 }
34 break;
35 }
37 // A location is uneliminable if
38 // - it is initial
39 // - it (potentially) satisfies the property
40 // - it has already been eliminated
41 // - it has a loop
42 // After each elimination, this list is updated to account for new loops
43 std::map<std::string, bool> uneliminable;
44 STORM_LOG_TRACE("Elimination status of locations:");
45 for (const auto& loc : automaton->getLocations()) {
46 bool possiblyInitial = session.isPossiblyInitial(automatonName, loc.getName());
47 bool partOfProp = session.isPartOfProp(automatonName, loc.getName());
48 bool hasLoops = session.hasLoops(automatonName, loc.getName());
49 bool isDeadlock = automaton->getEdgesFromLocation(loc.getName()).empty();
50 bool hasNamedAction = restrictToUnnamedActions && session.hasNamedActions(automatonName, loc.getName());
51
52 bool isUneliminable = possiblyInitial || partOfProp || hasLoops || isDeadlock || hasNamedAction;
53 uneliminable.insert(std::pair<std::string, bool>(loc.getName(), isUneliminable));
54 STORM_LOG_TRACE("\t" + loc.getName() + ": " << ([&] {
55 std::string eliminationStatus = "";
56 if (isUneliminable) {
57 eliminationStatus += "Uneliminable (";
58 if (possiblyInitial)
59 eliminationStatus += "initial, ";
60 if (partOfProp)
61 eliminationStatus += "part of prop, ";
62 if (hasLoops)
63 eliminationStatus += "has loops, ";
64 if (isDeadlock)
65 eliminationStatus += "has no outgoing edges, ";
66 if (hasNamedAction)
67 eliminationStatus += "has named action, ";
68 eliminationStatus = eliminationStatus.substr(0, eliminationStatus.size() - 2) + ")";
69 } else {
70 eliminationStatus += "Eliminable";
71 }
72 return eliminationStatus;
73 })());
74 }
75 STORM_LOG_TRACE("Performing elimination");
76
77 bool done = false;
78 while (!done) {
79 uint64_t minNewEdges = 18446744073709551615U; // max value of uint64
80 int bestLocIndex = -1;
81 for (const auto& loc : automaton->getLocations()) {
82 if (uneliminable[loc.getName()]) {
83 continue;
84 }
85
86 auto locIndex = automaton->getLocationIndex(loc.getName());
87 uint64_t outgoing = automaton->getEdgesFromLocation(locIndex).size();
88 uint64_t incoming = 0;
89 for (const auto& edge : automaton->getEdges()) {
90 uint64_t addedTransitions = 1;
91 for (const auto& dest : edge.getDestinations()) {
92 if (dest.getLocationIndex() == locIndex) {
93 addedTransitions *= outgoing;
94 // Stop once we hit the threshold -- otherwise there is a risk of causing
95 // an overflow due to the exponential growth of addedTransitions:
96 if (addedTransitions > transitionCountThreshold) {
97 break;
98 }
99 }
100 }
101 incoming += addedTransitions - 1;
102 }
103 uint64_t newEdges = incoming * outgoing;
104
105 if (newEdges <= minNewEdges) {
106 minNewEdges = newEdges;
107 bestLocIndex = locIndex;
108 }
109 }
110
111 if (bestLocIndex == -1) {
112 done = true;
113 STORM_LOG_TRACE("Cannot eliminate more locations");
114 } else if (minNewEdges > transitionCountThreshold) {
115 done = true;
116 STORM_LOG_TRACE("Cannot eliminate more locations without creating too many new transitions (best: " + std::to_string(minNewEdges) +
117 " new transitions)");
118 } else {
119 std::string locName = automaton->getLocation(bestLocIndex).getName();
120 STORM_LOG_TRACE("\tEliminating location " + locName + " (" + std::to_string(minNewEdges) + " new edges)");
121 EliminateAction action = EliminateAction(automatonName, locName);
122 action.doAction(session);
123 automaton = &session.getModel().getAutomaton(automatonName);
124 uneliminable[locName] = true;
125
126 // Update "uneliminable" to account for potential new loops
127 for (const auto& loc : automaton->getLocations()) {
128 if (!uneliminable[loc.getName()]) {
129 if (session.hasLoops(automatonName, loc.getName())) {
130 uneliminable[loc.getName()] = true;
131 STORM_LOG_TRACE("\t" + loc.getName() + " now has a loop");
132 }
133 if (restrictToUnnamedActions && session.hasNamedActions(automatonName, loc.getName())) {
134 uneliminable[loc.getName()] = true;
135 STORM_LOG_TRACE("\t" + loc.getName() + " now has a named action");
136 }
137 }
138 }
139 }
140 }
141
142 break;
143 }
144 default: {
145 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This elimination order is not yet implemented.");
146 break;
147 }
148 }
149}
150} // namespace elimination_actions
151} // namespace jani
152} // namespace storm
Location const & getLocation(uint64_t index) const
Retrieves the location with the given index.
std::vector< Location > const & getLocations() const
Retrieves the locations of the automaton.
Definition Automaton.cpp:98
Edges getEdgesFromLocation(std::string const &name)
Retrieves the edges of the location with the given name.
std::vector< Edge > & getEdges()
Retrieves the edges of the automaton.
uint64_t getLocationIndex(std::string const &name) const
bool hasLoops(const std::string &automatonName, std::string const &locationName)
bool hasNamedActions(const std::string &automatonName, std::string const &locationName)
bool isPartOfProp(const std::string &automatonName, std::string const &locationName)
bool isPossiblyInitial(const std::string &automatonName, std::string const &locationName)
bool isEliminable(const std::string &automatonName, std::string const &locationName)
std::string const & getName() const
Retrieves the name of the location.
Definition Location.cpp:19
Automaton & getAutomaton(std::string const &name)
Retrieves the automaton with the given name.
Definition Model.cpp:884
bool empty() const
Determines whether this set of edges is empty.
std::size_t size() const
Retrieves the number of edges.
void doAction(JaniLocalEliminator::Session &session) override
void doAction(JaniLocalEliminator::Session &session) override
EliminateAutomaticallyAction(const std::string &automatonName, EliminationOrder eliminationOrder, uint32_t transitionCountThreshold=1000, bool restrictToUnnamedActions=false)
#define STORM_LOG_TRACE(message)
Definition logging.h:15
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:28