Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SymbolicToSparseTransformer.cpp
Go to the documentation of this file.
2
13
15
16namespace storm {
17namespace transformer {
18
20 LabelInformation(std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) {
21 for (auto const& formula : formulas) {
22 std::vector<std::shared_ptr<storm::logic::AtomicLabelFormula const>> atomicLabelFormulas = formula->getAtomicLabelFormulas();
23 for (auto const& labelFormula : atomicLabelFormulas) {
24 atomicLabels.insert(labelFormula->getLabel());
25 }
26
27 std::vector<std::shared_ptr<storm::logic::AtomicExpressionFormula const>> atomicExpressionFormulas = formula->getAtomicExpressionFormulas();
28 for (auto const& expressionFormula : atomicExpressionFormulas) {
29 std::stringstream ss;
30 ss << expressionFormula->getExpression();
31 expressionLabels[ss.str()] = expressionFormula->getExpression();
32 }
33 }
34 }
35
36 std::set<std::string> atomicLabels;
37 std::map<std::string, storm::expressions::Expression> expressionLabels;
38};
39
40template<storm::dd::DdType Type, typename ValueType>
41std::shared_ptr<storm::models::sparse::Dtmc<ValueType>> SymbolicDtmcToSparseDtmcTransformer<Type, ValueType>::translate(
42 storm::models::symbolic::Dtmc<Type, ValueType> const& symbolicDtmc, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) {
43 this->odd = symbolicDtmc.getReachableStates().createOdd();
44 storm::storage::SparseMatrix<ValueType> transitionMatrix = symbolicDtmc.getTransitionMatrix().toMatrix(this->odd, this->odd);
45 std::unordered_map<std::string, storm::models::sparse::StandardRewardModel<ValueType>> rewardModels;
46 for (auto const& rewardModelNameAndModel : symbolicDtmc.getRewardModels()) {
47 std::optional<std::vector<ValueType>> stateRewards;
48 std::optional<std::vector<ValueType>> stateActionRewards;
49 std::optional<storm::storage::SparseMatrix<ValueType>> transitionRewards;
50 if (rewardModelNameAndModel.second.hasStateRewards()) {
51 stateRewards = rewardModelNameAndModel.second.getStateRewardVector().toVector(this->odd);
52 }
53 if (rewardModelNameAndModel.second.hasStateActionRewards()) {
54 stateActionRewards = rewardModelNameAndModel.second.getStateActionRewardVector().toVector(this->odd);
55 }
56 if (rewardModelNameAndModel.second.hasTransitionRewards()) {
57 transitionRewards = rewardModelNameAndModel.second.getTransitionRewardMatrix().toMatrix(this->odd, this->odd);
58 }
59 rewardModels.emplace(rewardModelNameAndModel.first,
60 storm::models::sparse::StandardRewardModel<ValueType>(stateRewards, stateActionRewards, transitionRewards));
61 }
62 storm::models::sparse::StateLabeling labelling(transitionMatrix.getRowGroupCount());
63
64 labelling.addLabel("init", symbolicDtmc.getInitialStates().toVector(this->odd));
65 labelling.addLabel("deadlock", symbolicDtmc.getDeadlockStates().toVector(this->odd));
66 if (formulas.empty()) {
67 for (auto const& label : symbolicDtmc.getLabels()) {
68 labelling.addLabel(label, symbolicDtmc.getStates(label).toVector(this->odd));
69 }
70 } else {
71 LabelInformation labelInfo(formulas);
72 for (auto const& label : labelInfo.atomicLabels) {
73 labelling.addLabel(label, symbolicDtmc.getStates(label).toVector(this->odd));
74 }
75 for (auto const& expressionLabel : labelInfo.expressionLabels) {
76 labelling.addLabel(expressionLabel.first, symbolicDtmc.getStates(expressionLabel.second).toVector(this->odd));
77 }
78 }
79 return std::make_shared<storm::models::sparse::Dtmc<ValueType>>(transitionMatrix, labelling, rewardModels);
80}
81
82template<storm::dd::DdType Type, typename ValueType>
86
87template<storm::dd::DdType Type, typename ValueType>
88std::shared_ptr<storm::models::sparse::Mdp<ValueType>> SymbolicMdpToSparseMdpTransformer<Type, ValueType>::translate(
89 storm::models::symbolic::Mdp<Type, ValueType> const& symbolicMdp, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) {
90 storm::dd::Odd odd = symbolicMdp.getReachableStates().createOdd();
91
92 // Collect action reward vectors that need translation
93 std::vector<storm::dd::Add<Type, ValueType>> symbolicActionRewardVectors;
94 std::map<std::string, uint64_t> rewardNameToActionRewardIndexMap;
95 for (auto const& rewardModelNameAndModel : symbolicMdp.getRewardModels()) {
96 if (rewardModelNameAndModel.second.hasStateActionRewards()) {
97 rewardNameToActionRewardIndexMap.emplace(rewardModelNameAndModel.first, symbolicActionRewardVectors.size());
98 symbolicActionRewardVectors.push_back(rewardModelNameAndModel.second.getStateActionRewardVector());
99 }
100 }
101 // Build transition matrix and (potentially) actionRewardVectors.
103 std::vector<std::vector<ValueType>> actionRewardVectors;
104 if (symbolicActionRewardVectors.empty()) {
105 transitionMatrix = symbolicMdp.getTransitionMatrix().toMatrix(symbolicMdp.getNondeterminismVariables(), odd, odd);
106 } else {
107 auto matrRewards = symbolicMdp.getTransitionMatrix().toMatrixVectors(symbolicActionRewardVectors, symbolicMdp.getNondeterminismVariables(), odd, odd);
108 transitionMatrix = std::move(matrRewards.first);
109 actionRewardVectors = std::move(matrRewards.second);
110 }
111
112 // Translate reward models
113 std::unordered_map<std::string, storm::models::sparse::StandardRewardModel<ValueType>> rewardModels;
114 for (auto const& rewardModelNameAndModel : symbolicMdp.getRewardModels()) {
115 std::optional<std::vector<ValueType>> stateRewards;
116 std::optional<std::vector<ValueType>> stateActionRewards;
117 std::optional<storm::storage::SparseMatrix<ValueType>> transitionRewards;
118 if (rewardModelNameAndModel.second.hasStateRewards()) {
119 stateRewards = rewardModelNameAndModel.second.getStateRewardVector().toVector(odd);
120 }
121 auto actRewIndexIt = rewardNameToActionRewardIndexMap.find(rewardModelNameAndModel.first);
122 if (actRewIndexIt != rewardNameToActionRewardIndexMap.end()) {
123 stateActionRewards = std::move(actionRewardVectors[actRewIndexIt->second]);
124 }
125 STORM_LOG_THROW(!rewardModelNameAndModel.second.hasTransitionRewards(), storm::exceptions::NotImplementedException,
126 "Translation of symbolic to explicit transition rewards is not yet supported.");
127 rewardModels.emplace(rewardModelNameAndModel.first,
128 storm::models::sparse::StandardRewardModel<ValueType>(stateRewards, stateActionRewards, transitionRewards));
129 }
130
131 storm::models::sparse::StateLabeling labelling(transitionMatrix.getRowGroupCount());
132
133 labelling.addLabel("init", symbolicMdp.getInitialStates().toVector(odd));
134 labelling.addLabel("deadlock", symbolicMdp.getDeadlockStates().toVector(odd));
135 if (formulas.empty()) {
136 for (auto const& label : symbolicMdp.getLabels()) {
137 labelling.addLabel(label, symbolicMdp.getStates(label).toVector(odd));
138 }
139 } else {
140 LabelInformation labelInfo(formulas);
141 for (auto const& label : labelInfo.atomicLabels) {
142 labelling.addLabel(label, symbolicMdp.getStates(label).toVector(odd));
143 }
144 for (auto const& expressionLabel : labelInfo.expressionLabels) {
145 labelling.addLabel(expressionLabel.first, symbolicMdp.getStates(expressionLabel.second).toVector(odd));
146 }
147 }
148
149 return std::make_shared<storm::models::sparse::Mdp<ValueType>>(transitionMatrix, labelling, rewardModels);
150}
151
152template<storm::dd::DdType Type, typename ValueType>
153std::shared_ptr<storm::models::sparse::Ctmc<ValueType>> SymbolicCtmcToSparseCtmcTransformer<Type, ValueType>::translate(
154 storm::models::symbolic::Ctmc<Type, ValueType> const& symbolicCtmc, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) {
155 storm::dd::Odd odd = symbolicCtmc.getReachableStates().createOdd();
156 storm::storage::SparseMatrix<ValueType> transitionMatrix = symbolicCtmc.getTransitionMatrix().toMatrix(odd, odd);
157 std::unordered_map<std::string, storm::models::sparse::StandardRewardModel<ValueType>> rewardModels;
158 for (auto const& rewardModelNameAndModel : symbolicCtmc.getRewardModels()) {
159 std::optional<std::vector<ValueType>> stateRewards;
160 std::optional<std::vector<ValueType>> stateActionRewards;
161 std::optional<storm::storage::SparseMatrix<ValueType>> transitionRewards;
162 if (rewardModelNameAndModel.second.hasStateRewards()) {
163 stateRewards = rewardModelNameAndModel.second.getStateRewardVector().toVector(odd);
164 }
165 if (rewardModelNameAndModel.second.hasStateActionRewards()) {
166 stateActionRewards = rewardModelNameAndModel.second.getStateActionRewardVector().toVector(odd);
167 }
168 if (rewardModelNameAndModel.second.hasTransitionRewards()) {
169 transitionRewards = rewardModelNameAndModel.second.getTransitionRewardMatrix().toMatrix(odd, odd);
170 }
171 rewardModels.emplace(rewardModelNameAndModel.first,
172 storm::models::sparse::StandardRewardModel<ValueType>(stateRewards, stateActionRewards, transitionRewards));
173 }
174 storm::models::sparse::StateLabeling labelling(transitionMatrix.getRowGroupCount());
175
176 labelling.addLabel("init", symbolicCtmc.getInitialStates().toVector(odd));
177 labelling.addLabel("deadlock", symbolicCtmc.getDeadlockStates().toVector(odd));
178 if (formulas.empty()) {
179 for (auto const& label : symbolicCtmc.getLabels()) {
180 labelling.addLabel(label, symbolicCtmc.getStates(label).toVector(odd));
181 }
182 } else {
183 LabelInformation labelInfo(formulas);
184 for (auto const& label : labelInfo.atomicLabels) {
185 labelling.addLabel(label, symbolicCtmc.getStates(label).toVector(odd));
186 }
187 for (auto const& expressionLabel : labelInfo.expressionLabels) {
188 labelling.addLabel(expressionLabel.first, symbolicCtmc.getStates(expressionLabel.second).toVector(odd));
189 }
190 }
191
192 return std::make_shared<storm::models::sparse::Ctmc<ValueType>>(transitionMatrix, labelling, rewardModels);
193}
194
195template<storm::dd::DdType Type, typename ValueType>
196std::shared_ptr<storm::models::sparse::MarkovAutomaton<ValueType>> SymbolicMaToSparseMaTransformer<Type, ValueType>::translate(
197 storm::models::symbolic::MarkovAutomaton<Type, ValueType> const& symbolicMa, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) {
198 storm::dd::Odd odd = symbolicMa.getReachableStates().createOdd();
199 // Collect action reward vectors that need translation
200 std::vector<storm::dd::Add<Type, ValueType>> symbolicActionRewardVectors;
201 std::map<std::string, uint64_t> rewardNameToActionRewardIndexMap;
202 for (auto const& rewardModelNameAndModel : symbolicMa.getRewardModels()) {
203 if (rewardModelNameAndModel.second.hasStateActionRewards()) {
204 rewardNameToActionRewardIndexMap.emplace(rewardModelNameAndModel.first, symbolicActionRewardVectors.size());
205 symbolicActionRewardVectors.push_back(rewardModelNameAndModel.second.getStateActionRewardVector());
206 }
207 }
208 // Build transition matrix and (potentially) actionRewardVectors.
210 std::vector<std::vector<ValueType>> actionRewardVectors;
211 if (symbolicActionRewardVectors.empty()) {
212 transitionMatrix = symbolicMa.getTransitionMatrix().toMatrix(symbolicMa.getNondeterminismVariables(), odd, odd);
213 } else {
214 auto matrRewards = symbolicMa.getTransitionMatrix().toMatrixVectors(symbolicActionRewardVectors, symbolicMa.getNondeterminismVariables(), odd, odd);
215 transitionMatrix = std::move(matrRewards.first);
216 actionRewardVectors = std::move(matrRewards.second);
217 }
218
219 // Translate reward models
220 std::unordered_map<std::string, storm::models::sparse::StandardRewardModel<ValueType>> rewardModels;
221 for (auto const& rewardModelNameAndModel : symbolicMa.getRewardModels()) {
222 std::optional<std::vector<ValueType>> stateRewards;
223 std::optional<std::vector<ValueType>> stateActionRewards;
224 std::optional<storm::storage::SparseMatrix<ValueType>> transitionRewards;
225 if (rewardModelNameAndModel.second.hasStateRewards()) {
226 stateRewards = rewardModelNameAndModel.second.getStateRewardVector().toVector(odd);
227 }
228 auto actRewIndexIt = rewardNameToActionRewardIndexMap.find(rewardModelNameAndModel.first);
229 if (actRewIndexIt != rewardNameToActionRewardIndexMap.end()) {
230 stateActionRewards = std::move(actionRewardVectors[actRewIndexIt->second]);
231 }
232 STORM_LOG_THROW(!rewardModelNameAndModel.second.hasTransitionRewards(), storm::exceptions::NotImplementedException,
233 "Translation of symbolic to explicit transition rewards is not yet supported.");
234 rewardModels.emplace(rewardModelNameAndModel.first,
235 storm::models::sparse::StandardRewardModel<ValueType>(stateRewards, stateActionRewards, transitionRewards));
236 }
237
238 storm::models::sparse::StateLabeling labelling(transitionMatrix.getRowGroupCount());
239
240 labelling.addLabel("init", symbolicMa.getInitialStates().toVector(odd));
241 labelling.addLabel("deadlock", symbolicMa.getDeadlockStates().toVector(odd));
242 if (formulas.empty()) {
243 for (auto const& label : symbolicMa.getLabels()) {
244 labelling.addLabel(label, symbolicMa.getStates(label).toVector(odd));
245 }
246 } else {
247 LabelInformation labelInfo(formulas);
248 for (auto const& label : labelInfo.atomicLabels) {
249 labelling.addLabel(label, symbolicMa.getStates(label).toVector(odd));
250 }
251 for (auto const& expressionLabel : labelInfo.expressionLabels) {
252 labelling.addLabel(expressionLabel.first, symbolicMa.getStates(expressionLabel.second).toVector(odd));
253 }
254 }
255 storm::storage::BitVector markovianStates = symbolicMa.getMarkovianStates().toVector(odd);
256 storm::storage::sparse::ModelComponents<ValueType> components(std::move(transitionMatrix), std::move(labelling), std::move(rewardModels), false,
257 std::move(markovianStates));
258 components.exitRates = symbolicMa.getExitRateVector().toVector(odd);
259
260 return std::make_shared<storm::models::sparse::MarkovAutomaton<ValueType>>(std::move(components));
261}
262
267
272
277
282
283} // namespace transformer
284} // namespace storm
std::pair< storm::storage::SparseMatrix< ValueType >, std::vector< std::vector< ValueType > > > toMatrixVectors(std::vector< storm::dd::Add< LibraryType, ValueType > > const &vectors, std::set< storm::expressions::Variable > const &groupMetaVariables, storm::dd::Odd const &rowOdd, storm::dd::Odd const &columnOdd) const
Converts the ADD to a row-grouped (sparse) matrix and the given vectors to row-grouped vectors.
Definition Add.cpp:962
storm::storage::SparseMatrix< ValueType > toMatrix() const
Converts the ADD to a (sparse) matrix.
Definition Add.cpp:634
std::vector< ValueType > toVector() const
Converts the ADD to a vector.
Definition Add.cpp:552
Odd createOdd() const
Creates an ODD based on the current BDD.
Definition Bdd.cpp:571
storm::storage::BitVector toVector(storm::dd::Odd const &rowOdd) const
Converts the BDD to a bit vector.
Definition Bdd.cpp:497
void addLabel(std::string const &label)
Adds a new label to the labelings.
This class manages the labeling of the state space with a number of (atomic) labels.
This class represents a continuous-time Markov chain.
Definition Ctmc.h:15
This class represents a discrete-time Markov chain.
Definition Dtmc.h:15
This class represents a discrete-time Markov decision process.
storm::dd::Bdd< Type > const & getMarkovianStates() const
storm::dd::Add< Type, ValueType > const & getExitRateVector() const
This class represents a discrete-time Markov decision process.
Definition Mdp.h:15
storm::dd::Add< Type, ValueType > const & getTransitionMatrix() const
Retrieves the matrix representing the transitions of the model.
Definition Model.cpp:177
storm::dd::Bdd< Type > const & getDeadlockStates() const
Definition Model.cpp:112
std::vector< std::string > getLabels() const
Definition Model.cpp:319
storm::dd::Bdd< Type > const & getInitialStates() const
Retrieves the initial states of the model.
Definition Model.cpp:107
std::unordered_map< std::string, RewardModelType > & getRewardModels()
Definition Model.cpp:303
virtual storm::dd::Bdd< Type > getStates(std::string const &label) const
Returns the sets of states labeled with the given label.
Definition Model.cpp:117
storm::dd::Bdd< Type > const & getReachableStates() const
Retrieves the reachable states of the model.
Definition Model.cpp:102
virtual std::set< storm::expressions::Variable > const & getNondeterminismVariables() const override
Retrieves the meta variables used to encode the nondeterminism in the model.
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:18
A class that holds a possibly non-square matrix in the compressed row storage format.
index_type getRowGroupCount() const
Returns the number of row groups in the matrix.
static std::shared_ptr< storm::models::sparse::Ctmc< ValueType > > translate(storm::models::symbolic::Ctmc< Type, ValueType > const &symbolicCtmc, std::vector< std::shared_ptr< storm::logic::Formula const > > const &formulas=std::vector< std::shared_ptr< storm::logic::Formula const > >())
std::shared_ptr< storm::models::sparse::Dtmc< ValueType > > translate(storm::models::symbolic::Dtmc< Type, ValueType > const &symbolicDtmc, std::vector< std::shared_ptr< storm::logic::Formula const > > const &formulas=std::vector< std::shared_ptr< storm::logic::Formula const > >())
static std::shared_ptr< storm::models::sparse::MarkovAutomaton< ValueType > > translate(storm::models::symbolic::MarkovAutomaton< Type, ValueType > const &symbolicMa, std::vector< std::shared_ptr< storm::logic::Formula const > > const &formulas=std::vector< std::shared_ptr< storm::logic::Formula const > >())
static std::shared_ptr< storm::models::sparse::Mdp< ValueType > > translate(storm::models::symbolic::Mdp< Type, ValueType > const &symbolicMdp, std::vector< std::shared_ptr< storm::logic::Formula const > > const &formulas=std::vector< std::shared_ptr< storm::logic::Formula const > >())
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
LabParser.cpp.
Definition cli.cpp:18
boost::optional< std::vector< ValueType > > exitRates
std::map< std::string, storm::expressions::Expression > expressionLabels
LabelInformation(std::vector< std::shared_ptr< storm::logic::Formula const > > const &formulas)