Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
stateelimination.cpp
Go to the documentation of this file.
2
3#include <random>
4
8
11
13
17#include "storm/utility/graph.h"
19
20namespace storm {
21namespace utility {
22namespace stateelimination {
23
30
35
40
46
50
51template<typename ValueType>
52uint_fast64_t estimateComplexity(ValueType const&) {
53 return 1;
54}
55
56#ifdef STORM_HAVE_CARL
57template<>
58uint_fast64_t estimateComplexity(storm::RationalFunction const& value) {
59 if (storm::utility::isConstant(value)) {
60 return 1;
61 }
62 if (value.denominator().isConstant()) {
63 return value.nominator().complexity();
64 } else {
65 return value.denominator().complexity() * value.nominator().complexity();
66 }
67}
68#endif
69
70template<typename ValueType>
72 storm::storage::FlexibleSparseMatrix<ValueType> const& backwardTransitions,
73 std::vector<ValueType> const& oneStepProbabilities) {
74 uint_fast64_t penalty = 0;
75 bool hasParametricSelfLoop = false;
76
77 for (auto const& predecessor : backwardTransitions.getRow(state)) {
78 for (auto const& successor : transitionMatrix.getRow(state)) {
79 penalty += estimateComplexity(predecessor.getValue()) * estimateComplexity(successor.getValue());
80 }
81 if (predecessor.getColumn() == state) {
82 hasParametricSelfLoop = !storm::utility::isConstant(predecessor.getValue());
83 }
84 penalty += estimateComplexity(oneStepProbabilities[predecessor.getColumn()]) * estimateComplexity(predecessor.getValue()) *
85 estimateComplexity(oneStepProbabilities[state]);
86 }
87
88 // If it is a self-loop that is parametric, we increase the penalty a lot.
89 if (hasParametricSelfLoop) {
90 penalty *= 10;
91 }
92
93 return penalty;
94}
95
96template<typename ValueType>
99 storm::storage::FlexibleSparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const&) {
100 return backwardTransitions.getRow(state).size() * transitionMatrix.getRow(state).size();
101}
102
103template<typename ValueType>
104std::shared_ptr<StatePriorityQueue> createStatePriorityQueue(boost::optional<std::vector<uint_fast64_t>> const& distanceBasedStatePriorities,
106 storm::storage::FlexibleSparseMatrix<ValueType> const& backwardTransitions,
107 std::vector<ValueType> const& oneStepProbabilities, storm::storage::BitVector const& states) {
108 STORM_LOG_TRACE("Creating state priority queue for states " << states);
109
110 // Get the settings to customize the priority queue.
113
114 std::vector<storm::storage::sparse::state_type> sortedStates(states.begin(), states.end());
115
117 std::random_device randomDevice;
118 std::mt19937 generator(randomDevice());
119 std::shuffle(sortedStates.begin(), sortedStates.end(), generator);
120 return std::make_unique<StaticStatePriorityQueue>(sortedStates);
121 } else {
123 STORM_LOG_THROW(static_cast<bool>(distanceBasedStatePriorities), storm::exceptions::InvalidStateException,
124 "Unable to build state priority queue without distance-based priorities.");
125 std::sort(sortedStates.begin(), sortedStates.end(),
126 [&distanceBasedStatePriorities](storm::storage::sparse::state_type const& state1, storm::storage::sparse::state_type const& state2) {
127 return distanceBasedStatePriorities.get()[state1] < distanceBasedStatePriorities.get()[state2];
128 });
129 return std::make_unique<StaticStatePriorityQueue>(sortedStates);
130 } else if (eliminationOrderIsPenaltyBased(order)) {
131 std::vector<std::pair<storm::storage::sparse::state_type, uint_fast64_t>> statePenalties(sortedStates.size());
133 order == storm::settings::modules::EliminationSettings::EliminationOrder::RegularExpression ? computeStatePenaltyRegularExpression<ValueType>
134 : computeStatePenalty<ValueType>;
135 for (uint_fast64_t index = 0; index < sortedStates.size(); ++index) {
136 statePenalties[index] =
137 std::make_pair(sortedStates[index], penaltyFunction(sortedStates[index], transitionMatrix, backwardTransitions, oneStepProbabilities));
138 }
139
140 std::sort(
141 statePenalties.begin(), statePenalties.end(),
142 [](std::pair<storm::storage::sparse::state_type, uint_fast64_t> const& statePenalty1,
143 std::pair<storm::storage::sparse::state_type, uint_fast64_t> const& statePenalty2) { return statePenalty1.second < statePenalty2.second; });
144
145 if (eliminationOrderIsStatic(order)) {
146 // For the static penalty version, we need to strip the penalties to create the queue.
147 for (uint_fast64_t index = 0; index < sortedStates.size(); ++index) {
148 sortedStates[index] = statePenalties[index].first;
149 }
150 return std::make_unique<StaticStatePriorityQueue>(sortedStates);
151 } else {
152 // For the dynamic penalty version, we need to give the full state-penalty pairs.
153 return std::make_unique<DynamicStatePriorityQueue<ValueType>>(statePenalties, transitionMatrix, backwardTransitions, oneStepProbabilities,
154 penaltyFunction);
155 }
156 }
157 }
158 STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Illegal elimination order selected.");
159}
160
161std::shared_ptr<StatePriorityQueue> createStatePriorityQueue(storm::storage::BitVector const& states) {
162 std::vector<storm::storage::sparse::state_type> sortedStates(states.begin(), states.end());
163 return std::make_shared<StaticStatePriorityQueue>(sortedStates);
164}
165
166std::shared_ptr<StatePriorityQueue> createStatePriorityQueue(std::vector<storm::storage::sparse::state_type> const& states) {
167 return std::make_shared<StaticStatePriorityQueue>(states);
168}
169
170template<typename ValueType>
171std::vector<uint_fast64_t> getDistanceBasedPriorities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
172 storm::storage::SparseMatrix<ValueType> const& transitionMatrixTransposed,
173 storm::storage::BitVector const& initialStates, std::vector<ValueType> const& oneStepProbabilities,
174 bool forward, bool reverse) {
175 std::vector<uint_fast64_t> statePriorities(transitionMatrix.getRowCount());
176 std::vector<storm::storage::sparse::state_type> states(transitionMatrix.getRowCount());
177 for (std::size_t index = 0; index < states.size(); ++index) {
178 states[index] = index;
179 }
180
181 std::vector<uint_fast64_t> distances =
182 getStateDistances(transitionMatrix, transitionMatrixTransposed, initialStates, oneStepProbabilities,
187
188 // In case of the forward or backward ordering, we can sort the states according to the distances.
189 if (forward ^ reverse) {
190 std::sort(states.begin(), states.end(),
191 [&distances](storm::storage::sparse::state_type const& state1, storm::storage::sparse::state_type const& state2) {
192 return distances[state1] < distances[state2];
193 });
194 } else {
195 // Otherwise, we sort them according to descending distances.
196 std::sort(states.begin(), states.end(),
197 [&distances](storm::storage::sparse::state_type const& state1, storm::storage::sparse::state_type const& state2) {
198 return distances[state1] > distances[state2];
199 });
200 }
201
202 // Now convert the ordering of the states to priorities.
203 for (uint_fast64_t index = 0; index < states.size(); ++index) {
204 statePriorities[states[index]] = index;
205 }
206
207 return statePriorities;
208}
209
210template<typename ValueType>
211std::vector<uint_fast64_t> getStateDistances(storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
212 storm::storage::SparseMatrix<ValueType> const& transitionMatrixTransposed,
213 storm::storage::BitVector const& initialStates, std::vector<ValueType> const& oneStepProbabilities, bool forward) {
214 if (forward) {
215 return storm::utility::graph::getDistances(transitionMatrix, initialStates);
216 } else {
217 // Since the target states were eliminated from the matrix already, we construct a replacement by
218 // treating all states that have some non-zero probability to go to a target state in one step as target
219 // states.
220 storm::storage::BitVector pseudoTargetStates(transitionMatrix.getRowCount());
221 for (std::size_t index = 0; index < oneStepProbabilities.size(); ++index) {
222 if (oneStepProbabilities[index] != storm::utility::zero<ValueType>()) {
223 pseudoTargetStates.set(index);
224 }
225 }
226
227 return storm::utility::graph::getDistances(transitionMatrixTransposed, pseudoTargetStates);
228 }
229}
230
231template uint_fast64_t estimateComplexity(double const& value);
232template std::shared_ptr<StatePriorityQueue> createStatePriorityQueue(boost::optional<std::vector<uint_fast64_t>> const& distanceBasedStatePriorities,
233 storm::storage::FlexibleSparseMatrix<double> const& transitionMatrix,
234 storm::storage::FlexibleSparseMatrix<double> const& backwardTransitions,
235 std::vector<double> const& oneStepProbabilities, storm::storage::BitVector const& states);
236template uint_fast64_t computeStatePenalty(storm::storage::sparse::state_type const& state,
237 storm::storage::FlexibleSparseMatrix<double> const& transitionMatrix,
238 storm::storage::FlexibleSparseMatrix<double> const& backwardTransitions,
239 std::vector<double> const& oneStepProbabilities);
241 storm::storage::FlexibleSparseMatrix<double> const& transitionMatrix,
242 storm::storage::FlexibleSparseMatrix<double> const& backwardTransitions,
243 std::vector<double> const& oneStepProbabilities);
244template std::vector<uint_fast64_t> getDistanceBasedPriorities(storm::storage::SparseMatrix<double> const& transitionMatrix,
245 storm::storage::SparseMatrix<double> const& transitionMatrixTransposed,
246 storm::storage::BitVector const& initialStates, std::vector<double> const& oneStepProbabilities,
247 bool forward, bool reverse);
248template std::vector<uint_fast64_t> getStateDistances(storm::storage::SparseMatrix<double> const& transitionMatrix,
249 storm::storage::SparseMatrix<double> const& transitionMatrixTransposed,
250 storm::storage::BitVector const& initialStates, std::vector<double> const& oneStepProbabilities,
251 bool forward);
252
253#ifdef STORM_HAVE_CARL
254template uint_fast64_t estimateComplexity(storm::RationalNumber const& value);
255template std::shared_ptr<StatePriorityQueue> createStatePriorityQueue(boost::optional<std::vector<uint_fast64_t>> const& distanceBasedStatePriorities,
258 std::vector<storm::RationalNumber> const& oneStepProbabilities,
259 storm::storage::BitVector const& states);
260template uint_fast64_t computeStatePenalty(storm::storage::sparse::state_type const& state,
263 std::vector<storm::RationalNumber> const& oneStepProbabilities);
267 std::vector<storm::RationalNumber> const& oneStepProbabilities);
268template std::vector<uint_fast64_t> getDistanceBasedPriorities(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
269 storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrixTransposed,
270 storm::storage::BitVector const& initialStates,
271 std::vector<storm::RationalNumber> const& oneStepProbabilities, bool forward, bool reverse);
272template std::vector<uint_fast64_t> getStateDistances(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
273 storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrixTransposed,
274 storm::storage::BitVector const& initialStates,
275 std::vector<storm::RationalNumber> const& oneStepProbabilities, bool forward);
276
277template std::shared_ptr<StatePriorityQueue> createStatePriorityQueue(boost::optional<std::vector<uint_fast64_t>> const& distanceBasedStatePriorities,
280 std::vector<storm::RationalFunction> const& oneStepProbabilities,
281 storm::storage::BitVector const& states);
282template uint_fast64_t computeStatePenalty(storm::storage::sparse::state_type const& state,
285 std::vector<storm::RationalFunction> const& oneStepProbabilities);
289 std::vector<storm::RationalFunction> const& oneStepProbabilities);
290template std::vector<uint_fast64_t> getDistanceBasedPriorities(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix,
291 storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrixTransposed,
292 storm::storage::BitVector const& initialStates,
293 std::vector<storm::RationalFunction> const& oneStepProbabilities, bool forward, bool reverse);
294template std::vector<uint_fast64_t> getStateDistances(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix,
295 storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrixTransposed,
296 storm::storage::BitVector const& initialStates,
297 std::vector<storm::RationalFunction> const& oneStepProbabilities, bool forward);
298#endif
299} // namespace stateelimination
300} // namespace utility
301} // namespace storm
EliminationOrder
An enum that contains all available state elimination orders.
std::function< uint_fast64_t(storm::storage::sparse::state_type const &state, storm::storage::FlexibleSparseMatrix< ValueType > const &transitionMatrix, storm::storage::FlexibleSparseMatrix< ValueType > const &backwardTransitions, std::vector< ValueType > const &oneStepProbabilities)> PenaltyFunctionType
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:18
const_iterator end() const
Returns an iterator pointing at the element past the back of the bit vector.
const_iterator begin() const
Returns an iterator to the indices of the set bits in the bit vector.
void set(uint_fast64_t index, bool value=true)
Sets the given truth value at the given index.
The flexible sparse matrix is used during state elimination.
row_type & getRow(index_type)
Returns an object representing the given row.
A class that holds a possibly non-square matrix in the compressed row storage format.
index_type getRowCount() const
Returns the number of rows of the matrix.
#define STORM_LOG_TRACE(message)
Definition logging.h:17
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
SettingsType const & getModule()
Get module.
std::vector< uint_fast64_t > getDistances(storm::storage::SparseMatrix< T > const &transitionMatrix, storm::storage::BitVector const &initialStates, boost::optional< storm::storage::BitVector > const &subsystem)
Performs a breadth-first search through the underlying graph structure to compute the distance from a...
Definition graph.cpp:288
std::shared_ptr< StatePriorityQueue > createStatePriorityQueue(boost::optional< std::vector< uint_fast64_t > > const &distanceBasedStatePriorities, storm::storage::FlexibleSparseMatrix< ValueType > const &transitionMatrix, storm::storage::FlexibleSparseMatrix< ValueType > const &backwardTransitions, std::vector< ValueType > const &oneStepProbabilities, storm::storage::BitVector const &states)
uint_fast64_t computeStatePenalty(storm::storage::sparse::state_type const &state, storm::storage::FlexibleSparseMatrix< ValueType > const &transitionMatrix, storm::storage::FlexibleSparseMatrix< ValueType > const &backwardTransitions, std::vector< ValueType > const &oneStepProbabilities)
std::vector< uint_fast64_t > getStateDistances(storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &transitionMatrixTransposed, storm::storage::BitVector const &initialStates, std::vector< ValueType > const &oneStepProbabilities, bool forward)
bool eliminationOrderIsStatic(storm::settings::modules::EliminationSettings::EliminationOrder const &order)
bool eliminationOrderNeedsForwardDistances(storm::settings::modules::EliminationSettings::EliminationOrder const &order)
uint_fast64_t computeStatePenaltyRegularExpression(storm::storage::sparse::state_type const &state, storm::storage::FlexibleSparseMatrix< ValueType > const &transitionMatrix, storm::storage::FlexibleSparseMatrix< ValueType > const &backwardTransitions, std::vector< ValueType > const &)
uint_fast64_t estimateComplexity(ValueType const &)
bool eliminationOrderNeedsDistances(storm::settings::modules::EliminationSettings::EliminationOrder const &order)
std::vector< uint_fast64_t > getDistanceBasedPriorities(storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &transitionMatrixTransposed, storm::storage::BitVector const &initialStates, std::vector< ValueType > const &oneStepProbabilities, bool forward, bool reverse)
bool eliminationOrderNeedsReversedDistances(storm::settings::modules::EliminationSettings::EliminationOrder const &order)
bool eliminationOrderIsPenaltyBased(storm::settings::modules::EliminationSettings::EliminationOrder const &order)
bool isConstant(ValueType const &)
Definition constants.cpp:66
LabParser.cpp.
Definition cli.cpp:18