Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
MarkovAutomaton.cpp
Go to the documentation of this file.
2
11#include "storm/utility/graph.h"
14
15namespace storm {
16namespace models {
17namespace sparse {
18
19template<typename ValueType, typename RewardModelType>
21 storm::models::sparse::StateLabeling const& stateLabeling,
22 storm::storage::BitVector const& markovianStates,
23 std::unordered_map<std::string, RewardModelType> const& rewardModels)
25 storm::storage::sparse::ModelComponents<ValueType, RewardModelType>(transitionMatrix, stateLabeling, rewardModels, true, markovianStates)) {
26 // Intentionally left empty
27}
28
29template<typename ValueType, typename RewardModelType>
31 storm::models::sparse::StateLabeling&& stateLabeling, storm::storage::BitVector&& markovianStates,
32 std::unordered_map<std::string, RewardModelType>&& rewardModels)
34 std::move(transitionMatrix), std::move(stateLabeling), std::move(rewardModels), true, std::move(markovianStates))) {
35 // Intentionally left empty
36}
37
38template<typename ValueType, typename RewardModelType>
40 : NondeterministicModel<ValueType, RewardModelType>(ModelType::MarkovAutomaton, components), markovianStates(components.markovianStates.get()) {
41 if (components.exitRates) {
42 exitRates = components.exitRates.get();
43 }
44
45 if (components.rateTransitions) {
46 this->turnRatesToProbabilities();
47 }
48 closed = this->checkIsClosed();
49}
50
51template<typename ValueType, typename RewardModelType>
54 // NOLINTBEGIN(bugprone-use-after-move) The base constructor only consumes the base-relevant fields of components.
55 markovianStates(std::move(components.markovianStates.get())) {
56 if (components.exitRates) {
57 exitRates = std::move(components.exitRates.get());
58 }
59
60 if (components.rateTransitions) {
61 this->turnRatesToProbabilities();
62 }
63 // NOLINTEND(bugprone-use-after-move)
64 closed = this->checkIsClosed();
65}
66
67template<typename ValueType, typename RewardModelType>
69 return closed;
70}
71
72template<typename ValueType, typename RewardModelType>
74 if (!this->hasZenoCycle.is_initialized()) {
75 this->hasZenoCycle = this->checkContainsZenoCycle();
76 }
77 return this->hasZenoCycle.get();
78}
79
80template<typename ValueType, typename RewardModelType>
84
85template<typename ValueType, typename RewardModelType>
87 return this->markovianStates.get(state);
88}
89
90template<typename ValueType, typename RewardModelType>
92 return !this->markovianStates.get(state);
93}
94
95template<typename ValueType, typename RewardModelType>
96std::vector<ValueType> const& MarkovAutomaton<ValueType, RewardModelType>::getExitRates() const {
97 return this->exitRates;
98}
99
100template<typename ValueType, typename RewardModelType>
102 return this->exitRates;
103}
104
105template<typename ValueType, typename RewardModelType>
109
110template<typename ValueType, typename RewardModelType>
114
115template<typename ValueType, typename RewardModelType>
119
120template<typename ValueType, typename RewardModelType>
122 if (!closed) {
123 // Get the choices that we will keep
124 storm::storage::BitVector keptChoices(this->getNumberOfChoices(), true);
125 for (auto state : this->getMarkovianStates()) {
126 if (this->getTransitionMatrix().getRowGroupSize(state) > 1) {
127 // The state is hybrid, hence, we remove the first choice.
128 keptChoices.set(this->getTransitionMatrix().getRowGroupIndices()[state], false);
129 // Afterwards, the state will no longer be Markovian.
130 this->markovianStates.set(state, false);
131 exitRates[state] = storm::utility::zero<ValueType>();
132 }
133 }
134
135 if (!keptChoices.full()) {
136 *this = std::move(*storm::transformer::buildSubsystem(*this, storm::storage::BitVector(this->getNumberOfStates(), true), keptChoices, false)
138 }
139
140 // Mark the automaton as closed.
141 closed = true;
142 }
143}
144
145template<typename ValueType, typename RewardModelType>
146void MarkovAutomaton<ValueType, RewardModelType>::turnRatesToProbabilities() {
147 bool assertRates = (this->exitRates.size() == this->getNumberOfStates());
148 if (!assertRates) {
149 STORM_LOG_THROW(this->exitRates.empty(), storm::exceptions::InvalidArgumentException, "The specified exit rate vector has an unexpected size.");
150 this->exitRates.reserve(this->getNumberOfStates());
151 }
152
153 for (uint_fast64_t state = 0; state < this->getNumberOfStates(); ++state) {
154 uint_fast64_t row = this->getTransitionMatrix().getRowGroupIndices()[state];
155 if (this->markovianStates.get(state)) {
156 if (assertRates) {
157 STORM_LOG_THROW(this->exitRates[state] == this->getTransitionMatrix().getRowSum(row), storm::exceptions::InvalidArgumentException,
158 "The specified exit rate is inconsistent with the rate matrix. Difference is "
159 << (this->exitRates[state] - this->getTransitionMatrix().getRowSum(row)) << ".");
160 } else {
161 this->exitRates.push_back(this->getTransitionMatrix().getRowSum(row));
162 }
163 for (auto& transition : this->getTransitionMatrix().getRow(row)) {
164 transition.setValue(transition.getValue() / this->exitRates[state]);
165 }
166 ++row;
167 } else {
168 if (assertRates) {
169 STORM_LOG_THROW(storm::utility::isZero(this->exitRates[state]), storm::exceptions::InvalidArgumentException,
170 "The specified exit rate for (non-Markovian) choice should be 0.");
171 } else {
172 this->exitRates.push_back(storm::utility::zero<ValueType>());
173 }
174 }
175 }
176}
177
178template<typename ValueType, typename RewardModelType>
180 return isClosed() && markovianStates.full();
181}
182
183template<typename ValueType, typename RewardModelType>
185 // Check every state
186 for (uint_fast64_t state = 0; state < this->getNumberOfStates(); ++state) {
187 STORM_LOG_ASSERT(!isHybridState(state), "State is hybrid.");
188 if (this->getNumberOfChoices(state) > 1) {
189 // Non-deterministic choice present
190 STORM_LOG_ASSERT(isProbabilisticState(state), "State is not probabilistic.");
191 return false;
192 }
193 }
194 return true;
195}
196
197template<typename ValueType, typename RewardModelType>
198bool MarkovAutomaton<ValueType, RewardModelType>::checkIsClosed() const {
199 for (uint64_t state : markovianStates) {
200 if (this->getTransitionMatrix().getRowGroupSize(state) > 1) {
201 return false;
202 }
203 }
204 return true;
205}
206
207template<typename ValueType, typename RewardModelType>
208std::shared_ptr<storm::models::sparse::Ctmc<ValueType, RewardModelType>> MarkovAutomaton<ValueType, RewardModelType>::convertToCtmc() const {
209 STORM_LOG_THROW(isConvertibleToCtmc(), storm::exceptions::InvalidArgumentException, "MA cannot be converted to CTMC.");
210
212 this->getRewardModels(), false);
213 components.transitionMatrix.makeRowGroupingTrivial();
214 components.exitRates = this->getExitRates();
215 if (this->hasChoiceLabeling()) {
216 components.choiceLabeling = this->getChoiceLabeling();
217 }
218 if (this->hasStateValuations()) {
219 components.stateValuations = this->getStateValuations();
220 }
221 if (this->hasChoiceOrigins()) {
222 components.choiceOrigins = this->getChoiceOrigins();
223 }
224 return std::make_shared<storm::models::sparse::Ctmc<ValueType, RewardModelType>>(std::move(components));
225}
226
227template<typename ValueType, typename RewardModelType>
228bool MarkovAutomaton<ValueType, RewardModelType>::checkContainsZenoCycle() const {
229 if (isClosed() && markovianStates.empty()) {
230 return true;
231 }
232 storm::storage::BitVector statesWithZenoCycle =
233 storm::utility::graph::performProb0E(*this, this->getBackwardTransitions(), ~markovianStates, markovianStates);
234 return !statesWithZenoCycle.empty();
235}
236
237template<typename ValueType, typename RewardModelType>
240 out << "Choices: \t" << this->getNumberOfChoices() << '\n';
241 out << "Markovian St.: \t" << this->getMarkovianStates().getNumberOfSetBits() << '\n';
242 out << "Max. Rate: \t";
243 if (this->getMarkovianStates().empty()) {
244 out << "None";
245 } else {
246 out << this->getMaximalExitRate();
247 }
248 out << '\n';
250}
251
252template class MarkovAutomaton<double>;
259} // namespace sparse
260} // namespace models
261} // namespace storm
std::shared_ptr< ModelType > as()
Casts the model into the model type given by the template parameter.
Definition ModelBase.h:38
This class represents a Markov automaton.
void close()
Closes the Markov automaton.
MarkovAutomaton(storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::models::sparse::StateLabeling const &stateLabeling, storm::storage::BitVector const &markovianStates, std::unordered_map< std::string, RewardModelType > const &rewardModels=std::unordered_map< std::string, RewardModelType >())
Constructs a model from the given data.
bool containsZenoCycle() const
Retrieves whether the Markov automaton contains Zeno cycles.
bool isClosed() const
Retrieves whether the Markov automaton is closed.
std::shared_ptr< storm::models::sparse::Ctmc< ValueType, RewardModelType > > convertToCtmc() const
Convert the MA to a CTMC.
bool isProbabilisticState(storm::storage::sparse::state_type state) const
Retrieves whether the given state is a probabilistic state.
bool isMarkovianState(storm::storage::sparse::state_type state) const
Retrieves whether the given state is a Markovian state.
bool isConvertibleToCtmc() const
Determines whether the Markov automaton can be converted to a CTMC without changing any measures.
virtual void printModelInformationToStream(std::ostream &out) const override
Prints information about the model to the specified stream.
std::vector< ValueType > const & getExitRates() const
Retrieves the vector representing the exit rates of the states.
storm::storage::BitVector const & getMarkovianStates() const
Retrieves the set of Markovian states of the model.
ValueType const & getExitRate(storm::storage::sparse::state_type state) const
Retrieves the exit rate of the given state.
ValueType getMaximalExitRate() const
Retrieves the maximal exit rate over all states of the model.
bool isHybridState(storm::storage::sparse::state_type state) const
Retrieves whether the given state is a hybrid state, i.e.
storm::models::sparse::ChoiceLabeling const & getChoiceLabeling() const
Retrieves the labels for the choices of the model.
Definition Model.cpp:335
storm::storage::SparseMatrix< ValueType > const & getTransitionMatrix() const
Retrieves the matrix representing the transitions of the model.
Definition Model.cpp:198
void printModelInformationFooterToStream(std::ostream &out) const
Prints the information footer (reward models, labels and size in memory) of the model to the specifie...
Definition Model.cpp:424
std::unordered_map< std::string, RewardModelType > const & getRewardModels() const
Retrieves the reward models.
Definition Model.cpp:690
bool hasStateValuations() const
Retrieves whether this model was build with state valuations.
Definition Model.cpp:350
storm::storage::sparse::Valuations const & getStateValuations() const
Retrieves the valuations of the states of the model.
Definition Model.cpp:355
std::shared_ptr< storm::storage::sparse::ChoiceOrigins > const & getChoiceOrigins() const
Retrieves the origins of the choices of the model.
Definition Model.cpp:375
bool hasChoiceLabeling() const
Retrieves whether this model has a labeling of the choices.
Definition Model.cpp:330
storm::models::sparse::StateLabeling const & getStateLabeling() const
Returns the state labeling associated with this model.
Definition Model.cpp:320
void printModelInformationHeaderToStream(std::ostream &out) const
Prints the information header (number of states and transitions) of the model to the specified stream...
Definition Model.cpp:416
CRewardModelType RewardModelType
Definition Model.h:33
bool hasChoiceOrigins() const
Retrieves whether this model was build with choice origins.
Definition Model.cpp:370
virtual uint_fast64_t getNumberOfStates() const override
Returns the number of states of the model.
Definition Model.cpp:163
NondeterministicModel(ModelType modelType, storm::storage::sparse::ModelComponents< ValueType, RewardModelType > const &components)
Constructs a model from the given data.
uint_fast64_t getNumberOfChoices(uint_fast64_t state) const
This class manages the labeling of the state space with a number of (atomic) labels.
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:16
bool full() const
Retrieves whether all bits are set in this bit vector.
bool empty() const
Retrieves whether no bits are set to true in this bit vector.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
A class that holds a possibly non-square matrix in the compressed row storage format.
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:28
SubsystemBuilderReturnType< ValueType, RewardModelType > buildSubsystem(storm::models::sparse::Model< ValueType, RewardModelType > const &originalModel, storm::storage::BitVector const &subsystemStates, storm::storage::BitVector const &subsystemActions, bool keepUnreachableStates, SubsystemBuilderOptions options)
storm::storage::BitVector performProb0E(storm::models::sparse::NondeterministicModel< T, RM > const &model, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
Computes the sets of states that have probability 0 of satisfying phi until psi under at least one po...
Definition graph.cpp:960
VT max_if(std::vector< VT > const &values, storm::storage::BitVector const &filter)
Computes the maximum of the entries from the values that are selected by the (non-empty) filter.
Definition vector.h:568
bool isZero(ValueType const &a)
Definition constants.cpp:42
ValueType zero()
Definition constants.cpp:24
storm::storage::SparseMatrix< ValueType > transitionMatrix
std::optional< std::shared_ptr< storm::storage::sparse::ChoiceOrigins > > choiceOrigins
std::optional< storm::models::sparse::ChoiceLabeling > choiceLabeling
std::optional< storm::storage::sparse::Valuations > stateValuations
boost::optional< std::vector< ValueType > > exitRates