3#include <boost/algorithm/string/join.hpp>
25template<storm::dd::DdType Type,
typename ValueType>
30 std::set<storm::expressions::Variable>
const& columnVariables,
31 std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>>
const& rowColumnMetaVariablePairs,
32 std::map<std::string, storm::expressions::Expression> labelToExpressionMap,
33 std::unordered_map<std::string, RewardModelType>
const& rewardModels)
36 reachableStates(reachableStates),
37 transitionMatrix(transitionMatrix),
38 rowVariables(rowVariables),
39 rowExpressionAdapter(rowExpressionAdapter),
40 columnVariables(columnVariables),
41 rowColumnMetaVariablePairs(rowColumnMetaVariablePairs),
42 labelToExpressionMap(labelToExpressionMap),
43 rewardModels(rewardModels) {
44 this->labelToBddMap.emplace(
"init", initialStates);
45 this->labelToBddMap.emplace(
"deadlock", deadlockStates);
48template<storm::dd::DdType Type,
typename ValueType>
52 std::set<storm::expressions::Variable>
const& columnVariables,
53 std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>>
const& rowColumnMetaVariablePairs,
54 std::map<std::string,
storm::dd::Bdd<Type>> labelToBddMap, std::unordered_map<std::string, RewardModelType>
const& rewardModels)
57 reachableStates(reachableStates),
58 transitionMatrix(transitionMatrix),
59 rowVariables(rowVariables),
60 rowExpressionAdapter(nullptr),
61 columnVariables(columnVariables),
62 rowColumnMetaVariablePairs(rowColumnMetaVariablePairs),
63 labelToBddMap(labelToBddMap),
64 rewardModels(rewardModels) {
65 STORM_LOG_THROW(this->labelToBddMap.find(
"init") == this->labelToBddMap.end(), storm::exceptions::WrongFormatException,
"Illegal custom label 'init'.");
66 STORM_LOG_THROW(this->labelToBddMap.find(
"deadlock") == this->labelToBddMap.end(), storm::exceptions::WrongFormatException,
67 "Illegal custom label 'deadlock'.");
68 this->labelToBddMap.emplace(
"init", initialStates);
69 this->labelToBddMap.emplace(
"deadlock", deadlockStates);
72template<storm::dd::DdType Type,
typename ValueType>
74 return reachableStates.getNonZeroCount();
77template<storm::dd::DdType Type,
typename ValueType>
79 return transitionMatrix.getNonZeroCount();
82template<storm::dd::DdType Type,
typename ValueType>
84 return reachableStates.getNonZeroCount();
87template<storm::dd::DdType Type,
typename ValueType>
92template<storm::dd::DdType Type,
typename ValueType>
97template<storm::dd::DdType Type,
typename ValueType>
99 return reachableStates;
102template<storm::dd::DdType Type,
typename ValueType>
104 return labelToBddMap.at(
"init");
107template<storm::dd::DdType Type,
typename ValueType>
109 return labelToBddMap.at(
"deadlock");
112template<storm::dd::DdType Type,
typename ValueType>
115 auto bddIt = labelToBddMap.find(label);
116 if (bddIt != labelToBddMap.end()) {
117 return bddIt->second;
120 auto expressionIt = labelToExpressionMap.find(label);
121 STORM_LOG_THROW(expressionIt != labelToExpressionMap.end(), storm::exceptions::IllegalArgumentException,
122 "The label " << label <<
" is invalid for the labeling of the model.");
123 return this->getStates(expressionIt->second);
127template<storm::dd::DdType Type,
typename ValueType>
129 auto expressionIt = labelToExpressionMap.find(label);
130 STORM_LOG_THROW(expressionIt != labelToExpressionMap.end(), storm::exceptions::IllegalArgumentException,
131 "Cannot retrieve the expression for the label " << label <<
".");
132 return expressionIt->second;
135template<storm::dd::DdType Type,
typename ValueType>
138 return this->getReachableStates();
139 }
else if (expression.
isFalse()) {
140 return manager->getBddZero();
144 std::stringstream stream;
145 stream << expression;
146 auto bddIt = labelToBddMap.find(stream.str());
147 if (bddIt != labelToBddMap.end()) {
148 return bddIt->second;
152 STORM_LOG_THROW(rowExpressionAdapter !=
nullptr, storm::exceptions::InvalidOperationException,
153 "Cannot create BDD for expression without expression adapter.");
154 return rowExpressionAdapter->translateExpression(expression).toBdd() && this->reachableStates;
157template<storm::dd::DdType Type,
typename ValueType>
159 auto bddIt = labelToBddMap.find(label);
160 if (bddIt != labelToBddMap.end()) {
164 auto expressionIt = labelToExpressionMap.find(label);
165 if (expressionIt != labelToExpressionMap.end()) {
172template<storm::dd::DdType Type,
typename ValueType>
174 return transitionMatrix;
177template<storm::dd::DdType Type,
typename ValueType>
179 return transitionMatrix;
182template<storm::dd::DdType Type,
typename ValueType>
184 return this->getTransitionMatrix().notZero();
187template<storm::dd::DdType Type,
typename ValueType>
192template<storm::dd::DdType Type,
typename ValueType>
194 return columnVariables;
197template<storm::dd::DdType Type,
typename ValueType>
199 std::set<storm::expressions::Variable> result;
200 std::set_union(this->getRowVariables().begin(), this->getRowVariables().end(), this->getNondeterminismVariables().begin(),
201 this->getNondeterminismVariables().end(), std::inserter(result, result.begin()));
205template<storm::dd::DdType Type,
typename ValueType>
207 std::set<storm::expressions::Variable> result;
208 std::set_union(this->getColumnVariables().begin(), this->getColumnVariables().end(), this->getNondeterminismVariables().begin(),
209 this->getNondeterminismVariables().end(), std::inserter(result, result.begin()));
213template<storm::dd::DdType Type,
typename ValueType>
215 return emptyVariableSet;
218template<storm::dd::DdType Type,
typename ValueType>
220 return rowColumnMetaVariablePairs;
223template<storm::dd::DdType Type,
typename ValueType>
225 return labelToExpressionMap;
228template<storm::dd::DdType Type,
typename ValueType>
230 return labelToBddMap;
233template<storm::dd::DdType Type,
typename ValueType>
235 return (storm::utility::dd::getRowColumnDiagonal<Type>(this->getManager(), this->getRowColumnMetaVariablePairs()) && this->getReachableStates())
236 .template toAdd<ValueType>();
239template<storm::dd::DdType Type,
typename ValueType>
241 return this->rewardModels.find(rewardModelName) != this->rewardModels.end();
244template<storm::dd::DdType Type,
typename ValueType>
246 auto it = this->rewardModels.find(rewardModelName);
247 if (it == this->rewardModels.end()) {
248 if (rewardModelName.empty()) {
249 if (this->hasUniqueRewardModel()) {
250 return this->getUniqueRewardModel();
253 "Unable to refer to default reward model, because there is no default model or it is not unique.");
256 STORM_LOG_THROW(
false, storm::exceptions::IllegalArgumentException,
"The requested reward model '" << rewardModelName <<
"' does not exist.");
262template<storm::dd::DdType Type,
typename ValueType>
264 STORM_LOG_THROW(this->hasUniqueRewardModel(), storm::exceptions::InvalidOperationException,
265 "Cannot retrieve unique reward model, because there is no unique one.");
266 return this->rewardModels.cbegin()->second;
269template<storm::dd::DdType Type,
typename ValueType>
271 STORM_LOG_THROW(this->hasUniqueRewardModel(), storm::exceptions::InvalidOperationException,
272 "Cannot retrieve name of unique reward model, because there is no unique one.");
273 return this->rewardModels.cbegin()->first;
276template<storm::dd::DdType Type,
typename ValueType>
278 STORM_LOG_THROW(this->hasUniqueRewardModel(), storm::exceptions::InvalidOperationException,
279 "Cannot retrieve unique reward model, because there is no unique one.");
280 return this->rewardModels.begin()->second;
283template<storm::dd::DdType Type,
typename ValueType>
285 return this->rewardModels.size() == 1;
288template<storm::dd::DdType Type,
typename ValueType>
290 return !this->rewardModels.empty();
293template<storm::dd::DdType Type,
typename ValueType>
295 return this->rewardModels;
298template<storm::dd::DdType Type,
typename ValueType>
300 return this->rewardModels;
303template<storm::dd::DdType Type,
typename ValueType>
305 this->printModelInformationHeaderToStream(out);
306 this->printModelInformationFooterToStream(out);
309template<storm::dd::DdType Type,
typename ValueType>
311 std::vector<std::string> labels;
312 for (
auto const& entry : labelToExpressionMap) {
313 labels.push_back(entry.first);
318template<storm::dd::DdType Type,
typename ValueType>
320 out <<
"-------------------------------------------------------------- \n";
321 out <<
"Model type: \t" << (storm::IsIntervalType<ValueType> ?
"I" :
"") << this->getType() <<
" (symbolic)\n";
322 out <<
"States: \t" << this->getNumberOfStates() <<
" (" << reachableStates.getNodeCount() <<
" nodes)\n";
323 out <<
"Transitions: \t" << this->getNumberOfTransitions() <<
" (" << transitionMatrix.getNodeCount() <<
" nodes)\n";
326template<storm::dd::DdType Type,
typename ValueType>
328 this->printRewardModelsInformationToStream(out);
329 this->printDdVariableInformationToStream(out);
330 out <<
"\nLabels: \t" << (this->labelToExpressionMap.size() + this->labelToBddMap.size()) <<
'\n';
331 for (
auto const& label : labelToBddMap) {
332 out <<
" * " << label.first <<
" -> " << label.second.getNonZeroCount() <<
" state(s) (" << label.second.getNodeCount() <<
" nodes)\n";
334 for (
auto const& label : labelToExpressionMap) {
335 out <<
" * " << label.first <<
'\n';
337 out <<
"-------------------------------------------------------------- \n";
340template<storm::dd::DdType Type,
typename ValueType>
342 if (this->rewardModels.size()) {
343 std::vector<std::string> rewardModelNames;
344 std::for_each(this->rewardModels.cbegin(), this->rewardModels.cend(),
345 [&rewardModelNames](
typename std::pair<std::string, RewardModelType>
const& nameRewardModelPair) {
346 if (nameRewardModelPair.first.empty()) {
347 rewardModelNames.push_back(
"(default)");
349 rewardModelNames.push_back(nameRewardModelPair.first);
352 out <<
"Reward Models: " << boost::join(rewardModelNames,
", ") <<
'\n';
354 out <<
"Reward Models: none\n";
358template<storm::dd::DdType Type,
typename ValueType>
360 uint_fast64_t rowVariableCount = 0;
361 for (
auto const& metaVariable : this->rowVariables) {
362 rowVariableCount += this->getManager().getMetaVariable(metaVariable).getNumberOfDdVariables();
364 uint_fast64_t columnVariableCount = 0;
365 for (
auto const& metaVariable : this->columnVariables) {
366 columnVariableCount += this->getManager().getMetaVariable(metaVariable).getNumberOfDdVariables();
369 out <<
"Variables: \t" <<
"rows: " << this->rowVariables.size() <<
" meta variables (" << rowVariableCount <<
" DD variables)"
370 <<
", columns: " << this->columnVariables.size() <<
" meta variables (" << columnVariableCount <<
" DD variables)";
373template<storm::dd::DdType Type,
typename ValueType>
375 return this->rowExpressionAdapter;
378template<storm::dd::DdType Type,
typename ValueType>
383template<storm::dd::DdType Type,
typename ValueType>
388template<storm::dd::DdType Type,
typename ValueType>
393template<storm::dd::DdType Type,
typename ValueType>
395 return std::is_same<ValueType, storm::RationalFunction>::value;
398template<storm::dd::DdType Type,
typename ValueType>
400 this->getTransitionMatrix().exportToDot(filename,
true);
401 this->getInitialStates().exportToDot(filename,
true);
402 for (
auto const& lab : this->getLabels()) {
403 this->getStates(lab).exportToDot(filename,
true);
407template<storm::dd::DdType Type,
typename ValueType>
409 if (!this->supportsParameters()) {
413 for (
auto it = this->getTransitionMatrix().begin(
false); it != this->getTransitionMatrix().end(); ++it) {
422template<storm::dd::DdType Type,
typename ValueType>
424 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"This value type does not support parameters.");
427template<storm::dd::DdType Type,
typename ValueType>
429 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"This value type does not support parameters.");
434 this->parameters.insert(parameters.begin(), parameters.end());
442template<storm::dd::DdType Type,
typename ValueType>
443template<
typename NewValueType>
446 STORM_LOG_TRACE(
"Converting value type of symbolic model from " <<
typeid(
ValueType).name() <<
" to " <<
typeid(NewValueType).name() <<
".");
450 return this->
template as<storm::models::symbolic::Dtmc<Type, ValueType>>()->
template toValueType<NewValueType>();
452 return this->
template as<storm::models::symbolic::Ctmc<Type, ValueType>>()->
template toValueType<NewValueType>();
454 return this->
template as<storm::models::symbolic::Mdp<Type, ValueType>>()->
template toValueType<NewValueType>();
456 return this->
template as<storm::models::symbolic::MarkovAutomaton<Type, ValueType>>()->
template toValueType<NewValueType>();
458 return this->
template as<storm::models::symbolic::StochasticTwoPlayerGame<Type, ValueType>>()->
template toValueType<NewValueType>();
465template<storm::dd::DdType Type,
typename ValueType>
466template<
typename NewValueType>
471 return std::make_shared<storm::models::symbolic::Dtmc<Type, ValueType>>(*this->
template as<storm::models::symbolic::Dtmc<Type, ValueType>>());
473 return std::make_shared<storm::models::symbolic::Ctmc<Type, ValueType>>(*this->
template as<storm::models::symbolic::Ctmc<Type, ValueType>>());
475 return std::make_shared<storm::models::symbolic::Mdp<Type, ValueType>>(*this->
template as<storm::models::symbolic::Mdp<Type, ValueType>>());
477 return std::make_shared<storm::models::symbolic::MarkovAutomaton<Type, ValueType>>(
478 *this->
template as<storm::models::symbolic::MarkovAutomaton<Type, ValueType>>());
480 return std::make_shared<storm::models::symbolic::StochasticTwoPlayerGame<Type, ValueType>>(
481 *this->
template as<storm::models::symbolic::StochasticTwoPlayerGame<Type, ValueType>>());
489template class Model<storm::dd::DdType::CUDD, double>;
490template typename std::enable_if<std::is_same<double, double>::value, std::shared_ptr<Model<storm::dd::DdType::CUDD, double>>>::type
491Model<storm::dd::DdType::CUDD, double>::toValueType<double>()
const;
493template class Model<storm::dd::DdType::Sylvan, double>;
494template class Model<storm::dd::DdType::Sylvan, storm::RationalNumber>;
495template typename std::enable_if<std::is_same<double, double>::value, std::shared_ptr<Model<storm::dd::DdType::Sylvan, double>>>::type
496Model<storm::dd::DdType::Sylvan, double>::toValueType<double>()
const;
497template typename std::enable_if<std::is_same<storm::RationalNumber, storm::RationalNumber>::value,
498 std::shared_ptr<Model<storm::dd::DdType::Sylvan, storm::RationalNumber>>>::type
499Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType<storm::RationalNumber>()
const;
500template typename std::enable_if<std::is_same<storm::RationalFunction, storm::RationalFunction>::value,
501 std::shared_ptr<Model<storm::dd::DdType::Sylvan, storm::RationalFunction>>>::type
502Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::toValueType<storm::RationalFunction>()
const;
503template typename std::enable_if<!std::is_same<storm::RationalNumber, double>::value, std::shared_ptr<Model<storm::dd::DdType::Sylvan, double>>>::type
504Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType<double>()
const;
505template class Model<storm::dd::DdType::Sylvan, storm::RationalFunction>;
bool isFalse() const
Checks if the expression is equal to the boolean literal false.
bool isTrue() const
Checks if the expression is equal to the boolean literal true.
virtual bool isExact() const
Checks whether the model is exact.
virtual bool isSymbolicModel() const
Checks whether the model is a symbolic model.
virtual std::optional< storm::dd::DdType > getDdType() const
virtual bool hasParameters() const
Checks whether the model has parameters.
virtual bool supportsParameters() const
Checks whether the model supports parameters.
Base class for all symbolic models.
storm::dd::DdManager< Type > & getManager() const
Retrieves the manager responsible for the DDs that represent this model.
RewardModelType const & getRewardModel(std::string const &rewardModelName) const
Retrieves the reward model with the given name, if one exists.
storm::dd::Add< Type, ValueType > const & getTransitionMatrix() const
Retrieves the matrix representing the transitions of the model.
storm::dd::Bdd< Type > const & getDeadlockStates() const
virtual void printModelInformationToStream(std::ostream &out) const override
Prints information about the model to the specified stream.
virtual storm::expressions::Expression getExpression(std::string const &label) const
Returns the expression for the given label.
RewardModelType const & getUniqueRewardModel() const
Retrieves the unique reward model, if there exists exactly one.
virtual std::string const & getUniqueRewardModelName() const override
Retrieves the name of the unique reward model, if there exists exactly one.
virtual storm::dd::Bdd< Type > getQualitativeTransitionMatrix(bool keepNondeterminism=true) const
Retrieves the matrix qualitatively (i.e.
std::set< storm::expressions::Variable > const & getColumnVariables() const
Retrieves the meta variables used to encode the columns of the transition matrix and the vector indic...
std::shared_ptr< storm::dd::DdManager< Type > > const & getManagerAsSharedPointer() const
Retrieves the manager responsible for the DDs that represent this model.
Model(Model< Type, ValueType > const &other)=default
std::vector< std::string > getLabels() const
storm::dd::Add< Type, ValueType > getRowColumnIdentity() const
Retrieves an ADD that represents the diagonal of the transition matrix.
void printRewardModelsInformationToStream(std::ostream &out) const
Prints information about the reward models to the specified stream.
std::map< std::string, storm::dd::Bdd< Type > > const & getLabelToBddMap() const
Retrieves the mapping of labels to their defining expressions.
storm::dd::Bdd< Type > const & getInitialStates() const
Retrieves the initial states of the model.
virtual std::set< storm::expressions::Variable > const & getNondeterminismVariables() const
Retrieves all meta variables used to encode the nondeterminism.
void printModelInformationFooterToStream(std::ostream &out) const
Prints the information footer (reward models, labels) of the model to the specified stream.
std::vector< std::pair< storm::expressions::Variable, storm::expressions::Variable > > const & getRowColumnMetaVariablePairs() const
Retrieves the pairs of row and column meta variables.
std::set< storm::expressions::Variable > const & getRowVariables() const
Retrieves the meta variables used to encode the rows of the transition matrix and the vector indices.
virtual bool hasLabel(std::string const &label) const
Retrieves whether the given label is a valid label in this model.
std::map< std::string, storm::expressions::Expression > const & getLabelToExpressionMap() const
Retrieves the mapping of labels to their defining expressions.
void printModelInformationHeaderToStream(std::ostream &out) const
Prints the information header (number of states and transitions) of the model to the specified stream...
std::unordered_map< std::string, RewardModelType > & getRewardModels()
virtual uint_fast64_t getNumberOfChoices() const override
Returns the number of choices ine the model.
std::set< storm::expressions::Variable > getRowAndNondeterminismVariables() const
Retrieves all meta variables used to encode rows and nondetermism.
std::set< storm::expressions::Variable > getColumnAndNondeterminismVariables() const
Retrieves all meta variables used to encode columns and nondetermism.
virtual storm::dd::Bdd< Type > getStates(std::string const &label) const
Returns the sets of states labeled with the given label.
virtual uint_fast64_t getNumberOfTransitions() const override
Returns the number of (non-zero) transitions of the model.
bool hasRewardModel() const
Retrieves whether the model has at least one reward model.
virtual bool hasUniqueRewardModel() const override
Retrieves whether the model has a unique reward model.
storm::dd::Bdd< Type > const & getReachableStates() const
Retrieves the reachable states of the model.
virtual uint_fast64_t getNumberOfStates() const override
Returns the number of states of the model.
#define STORM_LOG_WARN(message)
#define STORM_LOG_TRACE(message)
#define STORM_LOG_THROW(cond, exception, message)
bool isConstant(ValueType const &)