Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
DirectEncodingExporter.cpp
Go to the documentation of this file.
2
14
15namespace storm {
16namespace io {
17
18template<typename ValueType>
19void explicitExportSparseModel(std::ostream& os, std::shared_ptr<storm::models::sparse::Model<ValueType>> sparseModel,
20 std::vector<std::string> const& parameters, DirectEncodingOptions const& options) {
21 // Notice that for CTMCs we write the rate matrix instead of probabilities
22
23 // Initialize
24 std::vector<ValueType> exitRates; // Only for CTMCs and MAs.
25 if (sparseModel->getType() == storm::models::ModelType::Ctmc) {
26 exitRates = sparseModel->template as<storm::models::sparse::Ctmc<ValueType>>()->getExitRateVector();
27 } else if (sparseModel->getType() == storm::models::ModelType::MarkovAutomaton) {
28 exitRates = sparseModel->template as<storm::models::sparse::MarkovAutomaton<ValueType>>()->getExitRates();
29 }
30
31 // Write header
32 os << "// Exported by storm\n";
33 os << "// Original model type: " << sparseModel->getType() << '\n';
34 os << "@type: " << sparseModel->getType() << '\n';
35 os << "@parameters\n";
36 if (parameters.empty()) {
37 for (std::string const& parameter : getParameters(sparseModel)) {
38 os << parameter << " ";
39 }
40 } else {
41 for (std::string const& parameter : parameters) {
42 os << parameter << " ";
43 }
44 }
45 os << '\n';
46
47 // Optionally write placeholders which only need to be parsed once
48 // This is used to reduce the parsing effort for rational functions
49 // Placeholders begin with the dollar symbol $
50 std::unordered_map<ValueType, std::string> placeholders;
51 if (options.allowPlaceholders) {
52 placeholders = generatePlaceholders(sparseModel, exitRates);
53 }
54 if (!placeholders.empty()) {
55 os << "@placeholders\n";
56 for (auto const& entry : placeholders) {
57 os << "$" << entry.second << " : " << entry.first << '\n';
58 }
59 }
60
61 os << "@reward_models\n";
62 for (auto const& rewardModel : sparseModel->getRewardModels()) {
63 os << rewardModel.first << " ";
64 }
65 os << '\n';
66 os << "@nr_states\n" << sparseModel->getNumberOfStates() << '\n';
67 os << "@nr_choices\n" << sparseModel->getNumberOfChoices() << '\n';
68 os << "@model\n";
69
70 storm::storage::SparseMatrix<ValueType> const& matrix = sparseModel->getTransitionMatrix();
71
72 // Iterate over states and export state information and outgoing transitions
73 for (typename storm::storage::SparseMatrix<ValueType>::index_type group = 0; group < matrix.getRowGroupCount(); ++group) {
74 os << "state " << group;
75
76 // Write exit rates for CTMCs and MAs
77 if (!exitRates.empty()) {
78 os << " !";
79 writeValue(os, exitRates.at(group), placeholders);
80 }
81
82 if (sparseModel->getType() == storm::models::ModelType::Pomdp) {
83 os << " {" << sparseModel->template as<storm::models::sparse::Pomdp<ValueType>>()->getObservation(group) << "}";
84 }
85
86 // Write state rewards
87 bool first = true;
88 for (auto const& rewardModelEntry : sparseModel->getRewardModels()) {
89 if (first) {
90 os << " [";
91 first = false;
92 } else {
93 os << ", ";
94 }
95
96 if (rewardModelEntry.second.hasStateRewards()) {
97 writeValue(os, rewardModelEntry.second.getStateRewardVector().at(group), placeholders);
98 } else {
99 os << "0";
100 }
101 }
102
103 if (!first) {
104 os << "]";
105 }
106
107 // Write labels. Only labels with a whitespace are put in (double) quotation marks.
108 for (auto const& label : sparseModel->getStateLabeling().getLabelsOfState(group)) {
109 STORM_LOG_THROW(std::count(label.begin(), label.end(), '\"') == 0, storm::exceptions::NotSupportedException,
110 "Labels with quotation marks are not supported in the DRN format and therefore may not be exported.");
111 // TODO consider escaping the quotation marks. Not sure whether that is a good idea.
112 if (std::count_if(label.begin(), label.end(), isspace) > 0) {
113 os << " \"" << label << "\"";
114 } else {
115 os << " " << label;
116 }
117 }
118 os << '\n';
119 // Write state valuations as comments
120 if (sparseModel->hasStateValuations()) {
121 os << "//" << sparseModel->getStateValuations().getStateInfo(group) << '\n';
122 }
123
124 // Write probabilities
125 typename storm::storage::SparseMatrix<ValueType>::index_type start = matrix.hasTrivialRowGrouping() ? group : matrix.getRowGroupIndices()[group];
126 typename storm::storage::SparseMatrix<ValueType>::index_type end = matrix.hasTrivialRowGrouping() ? group + 1 : matrix.getRowGroupIndices()[group + 1];
127
128 // Iterate over all actions
129 for (typename storm::storage::SparseMatrix<ValueType>::index_type row = start; row < end; ++row) {
130 // Write choice
131 if (sparseModel->hasChoiceLabeling()) {
132 os << "\taction ";
133 bool lfirst = true;
134 if (sparseModel->getChoiceLabeling().getLabelsOfChoice(row).empty()) {
135 os << "__NOLABEL__";
136 }
137 for (auto const& label : sparseModel->getChoiceLabeling().getLabelsOfChoice(row)) {
138 if (!lfirst) {
139 os << "_";
140 lfirst = false;
141 }
142 os << label;
143 }
144 } else {
145 os << "\taction " << row - start;
146 }
147
148 // Write action rewards
149 bool first = true;
150 for (auto const& rewardModelEntry : sparseModel->getRewardModels()) {
151 if (first) {
152 os << " [";
153 first = false;
154 } else {
155 os << ", ";
156 }
157
158 if (rewardModelEntry.second.hasStateActionRewards()) {
159 writeValue(os, rewardModelEntry.second.getStateActionRewardVector().at(row), placeholders);
160 } else {
161 os << "0";
162 }
163 }
164 if (!first) {
165 os << "]";
166 }
167 os << '\n';
168
169 // Write transitions
170 for (auto it = matrix.begin(row); it != matrix.end(row); ++it) {
171 ValueType prob = it->getValue();
172 os << "\t\t" << it->getColumn() << " : ";
173 writeValue(os, prob, placeholders);
174 os << '\n';
175 }
176 }
177 } // end state iteration
178}
179
180template<typename ValueType>
181std::vector<std::string> getParameters(std::shared_ptr<storm::models::sparse::Model<ValueType>>) {
182 return {};
183}
184
185template<>
186std::vector<std::string> getParameters(std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> sparseModel) {
187 std::vector<std::string> parameters;
188 std::set<storm::RationalFunctionVariable> parametersProb = storm::models::sparse::getProbabilityParameters(*sparseModel);
189 std::set<storm::RationalFunctionVariable> parametersReward = storm::models::sparse::getRewardParameters(*sparseModel);
190 parametersProb.insert(parametersReward.begin(), parametersReward.end());
191 for (auto const& parameter : parametersProb) {
192 std::stringstream stream;
193 stream << parameter;
194 parameters.push_back(stream.str());
195 }
196 return parameters;
197}
198
199template<typename ValueType>
200std::unordered_map<ValueType, std::string> generatePlaceholders(std::shared_ptr<storm::models::sparse::Model<ValueType>>, std::vector<ValueType>) {
201 return {};
202}
203
212void createPlaceholder(std::unordered_map<storm::RationalFunction, std::string>& placeholders, storm::RationalFunction const& value, size_t& i) {
213 if (!storm::utility::isConstant(value)) {
214 auto ret = placeholders.insert(std::make_pair(value, std::to_string(i)));
215 if (ret.second) {
216 // New element was inserted
217 ++i;
218 }
219 }
220}
221
222template<>
223std::unordered_map<storm::RationalFunction, std::string> generatePlaceholders(
224 std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> sparseModel, std::vector<storm::RationalFunction> exitRates) {
225 std::unordered_map<storm::RationalFunction, std::string> placeholders;
226 size_t i = 0;
227
228 // Exit rates
229 for (auto const& exitRate : exitRates) {
230 createPlaceholder(placeholders, exitRate, i);
231 }
232
233 // Rewards
234 for (auto const& rewardModelEntry : sparseModel->getRewardModels()) {
235 if (rewardModelEntry.second.hasStateRewards()) {
236 for (auto const& reward : rewardModelEntry.second.getStateRewardVector()) {
237 createPlaceholder(placeholders, reward, i);
238 }
239 }
240 if (rewardModelEntry.second.hasStateActionRewards()) {
241 for (auto const& reward : rewardModelEntry.second.getStateActionRewardVector()) {
242 createPlaceholder(placeholders, reward, i);
243 }
244 }
245 }
246
247 // Transition probabilities
248 for (auto const& entry : sparseModel->getTransitionMatrix()) {
249 createPlaceholder(placeholders, entry.getValue(), i);
250 }
251
252 return placeholders;
253}
254
255template<typename ValueType>
256void writeValue(std::ostream& os, ValueType value, std::unordered_map<ValueType, std::string> const& placeholders) {
257 if (storm::utility::isConstant(value)) {
258 os << value;
259 return;
260 }
261
262 // Try to use placeholder
263 auto it = placeholders.find(value);
264 if (it != placeholders.end()) {
265 // Use placeholder
266 os << "$" << it->second;
267 } else {
268 os << value;
269 }
270}
271
272// Template instantiations
273template void explicitExportSparseModel<double>(std::ostream& os, std::shared_ptr<storm::models::sparse::Model<double>> sparseModel,
274 std::vector<std::string> const& parameters, DirectEncodingOptions const& options);
276 std::shared_ptr<storm::models::sparse::Model<storm::RationalNumber>> sparseModel,
277 std::vector<std::string> const& parameters, DirectEncodingOptions const& options);
280 std::vector<std::string> const& parameters, DirectEncodingOptions const& options);
281template void explicitExportSparseModel<storm::Interval>(std::ostream& os, std::shared_ptr<storm::models::sparse::Model<storm::Interval>> sparseModel,
282 std::vector<std::string> const& parameters, DirectEncodingOptions const& options);
283} // namespace io
284} // namespace storm
Base class for all sparse models.
Definition Model.h:33
A class that holds a possibly non-square matrix in the compressed row storage format.
const_iterator begin(index_type row) const
Retrieves an iterator that points to the beginning of the given row.
const_iterator end(index_type row) const
Retrieves an iterator that points past the end of the given row.
index_type getRowGroupCount() const
Returns the number of row groups in the matrix.
bool hasTrivialRowGrouping() const
Retrieves whether the matrix has a trivial row grouping.
std::vector< index_type > const & getRowGroupIndices() const
Returns the grouping of rows of this matrix.
SparseMatrixIndexType index_type
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
void explicitExportSparseModel(std::ostream &os, std::shared_ptr< storm::models::sparse::Model< ValueType > > sparseModel, std::vector< std::string > const &parameters, DirectEncodingOptions const &options)
Exports a sparse model into the explicit DRN format.
template void explicitExportSparseModel< storm::Interval >(std::ostream &os, std::shared_ptr< storm::models::sparse::Model< storm::Interval > > sparseModel, std::vector< std::string > const &parameters, DirectEncodingOptions const &options)
template void explicitExportSparseModel< storm::RationalFunction >(std::ostream &os, std::shared_ptr< storm::models::sparse::Model< storm::RationalFunction > > sparseModel, std::vector< std::string > const &parameters, DirectEncodingOptions const &options)
void createPlaceholder(std::unordered_map< storm::RationalFunction, std::string > &placeholders, storm::RationalFunction const &value, size_t &i)
Helper function to create a possible placeholder.
void writeValue(std::ostream &os, ValueType value, std::unordered_map< ValueType, std::string > const &placeholders)
Write value to stream while using the placeholders.
std::vector< std::string > getParameters(std::shared_ptr< storm::models::sparse::Model< ValueType > >)
Accumulate parameters in the model.
template void explicitExportSparseModel< storm::RationalNumber >(std::ostream &os, std::shared_ptr< storm::models::sparse::Model< storm::RationalNumber > > sparseModel, std::vector< std::string > const &parameters, DirectEncodingOptions const &options)
std::unordered_map< ValueType, std::string > generatePlaceholders(std::shared_ptr< storm::models::sparse::Model< ValueType > >, std::vector< ValueType >)
Generate placeholders for rational functions in the model.
template void explicitExportSparseModel< double >(std::ostream &os, std::shared_ptr< storm::models::sparse::Model< double > > sparseModel, std::vector< std::string > const &parameters, DirectEncodingOptions const &options)
std::set< storm::RationalFunctionVariable > getRewardParameters(Model< storm::RationalFunction > const &model)
Get all parameters occurring in rewards.
Definition Model.cpp:707
std::set< storm::RationalFunctionVariable > getProbabilityParameters(Model< storm::RationalFunction > const &model)
Get all probability parameters occurring on transitions.
Definition Model.cpp:703
bool isConstant(ValueType const &)
Definition constants.cpp:66
LabParser.cpp.
Definition cli.cpp:18