Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
StateEliminationUtility.cpp
Go to the documentation of this file.
2
3#include <random>
4
14#include "storm/utility/graph.h"
16
17namespace storm {
18namespace solver {
19namespace stateelimination {
20
25
29
33
37
41
42template<typename ValueType>
43uint_fast64_t estimateComplexity(ValueType const&) {
44 return 1;
45}
46
47template<>
48uint_fast64_t estimateComplexity(storm::RationalFunction const& value) {
49 if (storm::utility::isConstant(value)) {
50 return 1;
51 }
52 if (value.denominator().isConstant()) {
53 return value.nominator().complexity();
54 } else {
55 return value.denominator().complexity() * value.nominator().complexity();
56 }
57}
58
59template<typename ValueType>
61 storm::storage::FlexibleSparseMatrix<ValueType> const& backwardTransitions,
62 std::vector<ValueType> const& oneStepProbabilities) {
63 uint_fast64_t penalty = 0;
64 bool hasParametricSelfLoop = false;
65
66 for (auto const& predecessor : backwardTransitions.getRow(state)) {
67 for (auto const& successor : transitionMatrix.getRow(state)) {
68 penalty += estimateComplexity(predecessor.getValue()) * estimateComplexity(successor.getValue());
69 }
70 if (predecessor.getColumn() == state) {
71 hasParametricSelfLoop = !storm::utility::isConstant(predecessor.getValue());
72 }
73 penalty += estimateComplexity(oneStepProbabilities[predecessor.getColumn()]) * estimateComplexity(predecessor.getValue()) *
74 estimateComplexity(oneStepProbabilities[state]);
75 }
76
77 // If it is a self-loop that is parametric, we increase the penalty a lot.
78 if (hasParametricSelfLoop) {
79 penalty *= 10;
80 }
81
82 return penalty;
83}
84
85template<typename ValueType>
88 storm::storage::FlexibleSparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const&) {
89 return backwardTransitions.getRow(state).size() * transitionMatrix.getRow(state).size();
90}
91
92template<typename ValueType>
93std::shared_ptr<StatePriorityQueue> createStatePriorityQueue(EliminationOrder const& order,
94 boost::optional<std::vector<uint_fast64_t>> const& distanceBasedStatePriorities,
96 storm::storage::FlexibleSparseMatrix<ValueType> const& backwardTransitions,
97 std::vector<ValueType> const& oneStepProbabilities, storm::storage::BitVector const& states) {
98 STORM_LOG_TRACE("Creating state priority queue for states " << states);
99
100 std::vector<storm::storage::sparse::state_type> sortedStates(states.begin(), states.end());
101
102 if (order == EliminationOrder::Random) {
103 std::random_device randomDevice;
104 std::mt19937 generator(randomDevice());
105 std::shuffle(sortedStates.begin(), sortedStates.end(), generator);
106 return std::make_unique<StaticStatePriorityQueue>(sortedStates);
107 } else {
109 STORM_LOG_THROW(static_cast<bool>(distanceBasedStatePriorities), storm::exceptions::InvalidStateException,
110 "Unable to build state priority queue without distance-based priorities.");
111 std::sort(sortedStates.begin(), sortedStates.end(),
112 [&distanceBasedStatePriorities](storm::storage::sparse::state_type const& state1, storm::storage::sparse::state_type const& state2) {
113 return distanceBasedStatePriorities.get()[state1] < distanceBasedStatePriorities.get()[state2];
114 });
115 return std::make_unique<StaticStatePriorityQueue>(sortedStates);
116 } else if (eliminationOrderIsPenaltyBased(order)) {
117 std::vector<std::pair<storm::storage::sparse::state_type, uint_fast64_t>> statePenalties(sortedStates.size());
120 for (uint_fast64_t index = 0; index < sortedStates.size(); ++index) {
121 statePenalties[index] =
122 std::make_pair(sortedStates[index], penaltyFunction(sortedStates[index], transitionMatrix, backwardTransitions, oneStepProbabilities));
123 }
124
125 std::sort(
126 statePenalties.begin(), statePenalties.end(),
127 [](std::pair<storm::storage::sparse::state_type, uint_fast64_t> const& statePenalty1,
128 std::pair<storm::storage::sparse::state_type, uint_fast64_t> const& statePenalty2) { return statePenalty1.second < statePenalty2.second; });
129
130 if (eliminationOrderIsStatic(order)) {
131 // For the static penalty version, we need to strip the penalties to create the queue.
132 for (uint_fast64_t index = 0; index < sortedStates.size(); ++index) {
133 sortedStates[index] = statePenalties[index].first;
134 }
135 return std::make_unique<StaticStatePriorityQueue>(sortedStates);
136 } else {
137 // For the dynamic penalty version, we need to give the full state-penalty pairs.
138 return std::make_unique<DynamicStatePriorityQueue<ValueType>>(statePenalties, transitionMatrix, backwardTransitions, oneStepProbabilities,
139 penaltyFunction);
140 }
141 }
142 }
143 STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Illegal elimination order selected.");
144}
145
146std::shared_ptr<StatePriorityQueue> createStatePriorityQueue(storm::storage::BitVector const& states) {
147 std::vector<storm::storage::sparse::state_type> sortedStates(states.begin(), states.end());
148 return std::make_shared<StaticStatePriorityQueue>(sortedStates);
149}
150
151std::shared_ptr<StatePriorityQueue> createStatePriorityQueue(std::vector<storm::storage::sparse::state_type> const& states) {
152 return std::make_shared<StaticStatePriorityQueue>(states);
153}
154
155template<typename ValueType>
156std::vector<uint_fast64_t> getDistanceBasedPriorities(EliminationOrder const& order, storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
157 storm::storage::SparseMatrix<ValueType> const& transitionMatrixTransposed,
158 storm::storage::BitVector const& initialStates, std::vector<ValueType> const& oneStepProbabilities,
159 bool forward, bool reverse) {
160 std::vector<uint_fast64_t> statePriorities(transitionMatrix.getRowCount());
161 std::vector<storm::storage::sparse::state_type> states(transitionMatrix.getRowCount());
162 for (std::size_t index = 0; index < states.size(); ++index) {
163 states[index] = index;
164 }
165
166 std::vector<uint_fast64_t> distances = getStateDistances(transitionMatrix, transitionMatrixTransposed, initialStates, oneStepProbabilities,
168
169 // In case of the forward or backward ordering, we can sort the states according to the distances.
170 if (forward ^ reverse) {
171 std::sort(states.begin(), states.end(),
172 [&distances](storm::storage::sparse::state_type const& state1, storm::storage::sparse::state_type const& state2) {
173 return distances[state1] < distances[state2];
174 });
175 } else {
176 // Otherwise, we sort them according to descending distances.
177 std::sort(states.begin(), states.end(),
178 [&distances](storm::storage::sparse::state_type const& state1, storm::storage::sparse::state_type const& state2) {
179 return distances[state1] > distances[state2];
180 });
181 }
182
183 // Now convert the ordering of the states to priorities.
184 for (uint_fast64_t index = 0; index < states.size(); ++index) {
185 statePriorities[states[index]] = index;
186 }
187
188 return statePriorities;
189}
190
191template<typename ValueType>
192std::vector<uint_fast64_t> getStateDistances(storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
193 storm::storage::SparseMatrix<ValueType> const& transitionMatrixTransposed,
194 storm::storage::BitVector const& initialStates, std::vector<ValueType> const& oneStepProbabilities, bool forward) {
195 if (forward) {
196 return storm::utility::graph::getDistances(transitionMatrix, initialStates);
197 } else {
198 // Since the target states were eliminated from the matrix already, we construct a replacement by
199 // treating all states that have some non-zero probability to go to a target state in one step as target
200 // states.
201 storm::storage::BitVector pseudoTargetStates(transitionMatrix.getRowCount());
202 for (std::size_t index = 0; index < oneStepProbabilities.size(); ++index) {
203 if (oneStepProbabilities[index] != storm::utility::zero<ValueType>()) {
204 pseudoTargetStates.set(index);
205 }
206 }
207
208 return storm::utility::graph::getDistances(transitionMatrixTransposed, pseudoTargetStates);
209 }
210}
211
212template uint_fast64_t estimateComplexity(double const& value);
213template std::shared_ptr<StatePriorityQueue> createStatePriorityQueue(EliminationOrder const& order,
214 boost::optional<std::vector<uint_fast64_t>> const& distanceBasedStatePriorities,
215 storm::storage::FlexibleSparseMatrix<double> const& transitionMatrix,
216 storm::storage::FlexibleSparseMatrix<double> const& backwardTransitions,
217 std::vector<double> const& oneStepProbabilities, storm::storage::BitVector const& states);
218template uint_fast64_t computeStatePenalty(storm::storage::sparse::state_type const& state,
219 storm::storage::FlexibleSparseMatrix<double> const& transitionMatrix,
220 storm::storage::FlexibleSparseMatrix<double> const& backwardTransitions,
221 std::vector<double> const& oneStepProbabilities);
223 storm::storage::FlexibleSparseMatrix<double> const& transitionMatrix,
224 storm::storage::FlexibleSparseMatrix<double> const& backwardTransitions,
225 std::vector<double> const& oneStepProbabilities);
226template std::vector<uint_fast64_t> getDistanceBasedPriorities(EliminationOrder const& order, storm::storage::SparseMatrix<double> const& transitionMatrix,
227 storm::storage::SparseMatrix<double> const& transitionMatrixTransposed,
228 storm::storage::BitVector const& initialStates, std::vector<double> const& oneStepProbabilities,
229 bool forward, bool reverse);
230template std::vector<uint_fast64_t> getStateDistances(storm::storage::SparseMatrix<double> const& transitionMatrix,
231 storm::storage::SparseMatrix<double> const& transitionMatrixTransposed,
232 storm::storage::BitVector const& initialStates, std::vector<double> const& oneStepProbabilities,
233 bool forward);
234
235template uint_fast64_t estimateComplexity(storm::RationalNumber const& value);
236template std::shared_ptr<StatePriorityQueue> createStatePriorityQueue(EliminationOrder const& order,
237 boost::optional<std::vector<uint_fast64_t>> const& distanceBasedStatePriorities,
240 std::vector<storm::RationalNumber> const& oneStepProbabilities,
241 storm::storage::BitVector const& states);
242template uint_fast64_t computeStatePenalty(storm::storage::sparse::state_type const& state,
245 std::vector<storm::RationalNumber> const& oneStepProbabilities);
249 std::vector<storm::RationalNumber> const& oneStepProbabilities);
250template std::vector<uint_fast64_t> getDistanceBasedPriorities(EliminationOrder const& order,
252 storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrixTransposed,
253 storm::storage::BitVector const& initialStates,
254 std::vector<storm::RationalNumber> const& oneStepProbabilities, bool forward, bool reverse);
255template std::vector<uint_fast64_t> getStateDistances(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
256 storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrixTransposed,
257 storm::storage::BitVector const& initialStates,
258 std::vector<storm::RationalNumber> const& oneStepProbabilities, bool forward);
259
260template std::shared_ptr<StatePriorityQueue> createStatePriorityQueue(EliminationOrder const& order,
261 boost::optional<std::vector<uint_fast64_t>> const& distanceBasedStatePriorities,
264 std::vector<storm::RationalFunction> const& oneStepProbabilities,
265 storm::storage::BitVector const& states);
266template uint_fast64_t computeStatePenalty(storm::storage::sparse::state_type const& state,
269 std::vector<storm::RationalFunction> const& oneStepProbabilities);
273 std::vector<storm::RationalFunction> const& oneStepProbabilities);
274template std::vector<uint_fast64_t> getDistanceBasedPriorities(EliminationOrder const& order,
276 storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrixTransposed,
277 storm::storage::BitVector const& initialStates,
278 std::vector<storm::RationalFunction> const& oneStepProbabilities, bool forward, bool reverse);
279template std::vector<uint_fast64_t> getStateDistances(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix,
280 storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrixTransposed,
281 storm::storage::BitVector const& initialStates,
282 std::vector<storm::RationalFunction> const& oneStepProbabilities, bool forward);
283} // namespace stateelimination
284} // namespace solver
285} // namespace storm
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:16
const_iterator end() const
Returns an iterator pointing at the element past the back of the bit vector.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
const_iterator begin() const
Returns an iterator to the indices of the set bits in the bit vector.
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:15
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:28
bool eliminationOrderIsStatic(EliminationOrder const &order)
uint_fast64_t estimateComplexity(ValueType const &)
bool eliminationOrderNeedsReversedDistances(EliminationOrder const &order)
bool eliminationOrderNeedsForwardDistances(EliminationOrder const &order)
bool eliminationOrderIsPenaltyBased(EliminationOrder const &order)
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)
std::shared_ptr< StatePriorityQueue > createStatePriorityQueue(EliminationOrder const &order, 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)
bool eliminationOrderNeedsDistances(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 &)
EliminationOrder
An enum that contains all available state elimination orders.
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 > getDistanceBasedPriorities(EliminationOrder const &order, 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)
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:281
bool isConstant(ValueType const &)
ValueType zero()
Definition constants.cpp:24
carl::RationalFunction< Polynomial, true > RationalFunction