15namespace bisimulation {
17template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
20 : model(model), quotientFormat(quotientFormat) {
22 STORM_LOG_ERROR(
"Only DD-based partial quotient extraction is currently supported. Switching to DD-based extraction.");
27template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
30 auto start = std::chrono::high_resolution_clock::now();
31 std::shared_ptr<storm::models::Model<ExportValueType>> result;
34 "Only DD-based partial quotient extraction is currently supported.");
35 result = extractDdQuotient(partition, preservationInformation);
36 auto end = std::chrono::high_resolution_clock::now();
37 STORM_LOG_TRACE(
"Quotient extraction completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() <<
"ms.");
39 STORM_LOG_THROW(result, storm::exceptions::NotSupportedException,
"Quotient could not be extracted.");
44template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
47 auto modelType = model.getType();
52 "Mismatching partition.");
54 std::set<storm::expressions::Variable> blockVariableSet = {partition.
getBlockVariable()};
56 std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> blockMetaVariablePairs = {
61 auto start = std::chrono::high_resolution_clock::now();
62 partitionAsBdd = partitionAsBdd.
renameVariables(model.getColumnVariables(), model.getRowVariables());
64 storm::dd::Bdd<DdType> initialStates = (model.getInitialStates() && partitionAsBdd).existsAbstract(model.getRowVariables());
66 std::map<std::string, storm::dd::Bdd<DdType>> preservedLabelBdds;
67 for (
auto const& label : preservationInformation.getLabels()) {
68 preservedLabelBdds.emplace(label, (model.getStates(label) && partitionAsBdd).existsAbstract(model.getRowVariables()));
70 for (
auto const& expression : preservationInformation.getExpressions()) {
71 std::stringstream stream;
73 std::string expressionAsString = stream.str();
75 auto it = preservedLabelBdds.find(expressionAsString);
76 if (it != preservedLabelBdds.end()) {
77 STORM_LOG_WARN(
"Duplicate label '" << expressionAsString <<
"', dropping second label definition.");
79 preservedLabelBdds.emplace(stream.str(), (model.getStates(expression) && partitionAsBdd).existsAbstract(model.getRowVariables()));
82 auto end = std::chrono::high_resolution_clock::now();
83 STORM_LOG_TRACE(
"Quotient labels extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).
count() <<
"ms.");
85 start = std::chrono::high_resolution_clock::now();
86 std::set<storm::expressions::Variable> blockAndRowVariables;
87 std::set_union(blockVariableSet.begin(), blockVariableSet.end(), model.getRowVariables().begin(), model.getRowVariables().end(),
88 std::inserter(blockAndRowVariables, blockAndRowVariables.end()));
89 std::set<storm::expressions::Variable> blockPrimeAndColumnVariables;
90 std::set_union(blockPrimeVariableSet.begin(), blockPrimeVariableSet.end(), model.getColumnVariables().begin(), model.getColumnVariables().end(),
91 std::inserter(blockPrimeAndColumnVariables, blockPrimeAndColumnVariables.end()));
94 partitionAsAdd.
renameVariables(blockAndRowVariables, blockPrimeAndColumnVariables), model.getColumnVariables());
96 quotientTransitionMatrix = quotientTransitionMatrix * partitionAsAdd;
97 end = std::chrono::high_resolution_clock::now();
100 if (std::is_same<ValueType, storm::RationalNumber>::value) {
101 STORM_LOG_ASSERT(quotientTransitionMatrix.
greater(storm::utility::one<ValueType>()).isZero(),
"Illegal entries in quotient matrix.");
103 STORM_LOG_ASSERT(quotientTransitionMatrix.
greater(storm::utility::one<ValueType>() + storm::utility::convertNumber<ValueType>(1e-6)).isZero(),
104 "Illegal entries in quotient matrix.");
107 STORM_LOG_TRACE(
"Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).
count() <<
"ms.");
110 std::set<storm::expressions::Variable> nonSourceVariables;
111 std::set_union(blockPrimeVariableSet.begin(), blockPrimeVariableSet.end(), model.getRowVariables().begin(), model.getRowVariables().end(),
112 std::inserter(nonSourceVariables, nonSourceVariables.begin()));
115 start = std::chrono::high_resolution_clock::now();
116 std::unordered_map<std::string, storm::models::symbolic::StandardRewardModel<DdType, ValueType>> quotientRewardModels;
117 for (
auto const& rewardModelName : preservationInformation.getRewardModelNames()) {
118 auto const& rewardModel = model.getRewardModel(rewardModelName);
120 boost::optional<storm::dd::Add<DdType, ValueType>> quotientStateRewards;
121 if (rewardModel.hasStateRewards()) {
122 quotientStateRewards = rewardModel.getStateRewardVector() * partitionAsAdd;
125 boost::optional<storm::dd::Add<DdType, ValueType>> quotientStateActionRewards;
126 if (rewardModel.hasStateActionRewards()) {
127 quotientStateActionRewards = rewardModel.getStateActionRewardVector() * partitionAsAdd;
131 quotientStateRewards, quotientStateActionRewards, boost::none));
133 end = std::chrono::high_resolution_clock::now();
134 STORM_LOG_TRACE(
"Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).
count() <<
"ms.");
136 std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> result;
138 result = std::make_shared<storm::models::symbolic::Mdp<DdType, ValueType>>(
139 model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet,
140 blockPrimeVariableSet, blockMetaVariablePairs, model.getRowVariables(), preservedLabelBdds, quotientRewardModels);
142 std::set<storm::expressions::Variable> allNondeterminismVariables;
143 std::set_union(model.getRowVariables().begin(), model.getRowVariables().end(), model.getNondeterminismVariables().begin(),
144 model.getNondeterminismVariables().end(), std::inserter(allNondeterminismVariables, allNondeterminismVariables.begin()));
146 result = std::make_shared<storm::models::symbolic::StochasticTwoPlayerGame<DdType, ValueType>>(
147 model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet,
148 blockPrimeVariableSet, blockMetaVariablePairs, model.getRowVariables(), model.getNondeterminismVariables(), allNondeterminismVariables,
149 preservedLabelBdds, quotientRewardModels);
151 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Unsupported quotient type.");
154 return result->template toValueType<ExportValueType>();
156 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Cannot extract partial quotient for this model type.");
160template class PartialQuotientExtractor<storm::dd::DdType::CUDD, double>;
161template class PartialQuotientExtractor<storm::dd::DdType::Sylvan, double>;
163template class PartialQuotientExtractor<storm::dd::DdType::Sylvan, storm::RationalNumber>;
164template class PartialQuotientExtractor<storm::dd::DdType::Sylvan, storm::RationalNumber, double>;
165template class PartialQuotientExtractor<storm::dd::DdType::Sylvan, storm::RationalFunction>;
Bdd< LibraryType > greater(Add< LibraryType, ValueType > const &other) const
Retrieves the function that maps all evaluations to one whose function value in the first ADD are gre...
Add< LibraryType, ValueType > renameVariables(std::set< storm::expressions::Variable > const &from, std::set< storm::expressions::Variable > const &to) const
Renames the given meta variables in the ADD.
Add< LibraryType, ValueType > multiplyMatrix(Add< LibraryType, ValueType > const &otherMatrix, std::set< storm::expressions::Variable > const &summationMetaVariables) const
Multiplies the current ADD (representing a matrix) with the given matrix by summing over the given me...
Bdd< LibraryType > notZero() const
Computes a BDD that represents the function in which all assignments with a function value unequal to...
Bdd< LibraryType > existsAbstract(std::set< storm::expressions::Variable > const &metaVariables) const
Existentially abstracts from the given meta variables.
Bdd< LibraryType > renameVariables(std::set< storm::expressions::Variable > const &from, std::set< storm::expressions::Variable > const &to) const
Renames the given meta variables in the BDD.
storm::expressions::Variable const & getBlockVariable() const
storm::dd::Bdd< DdType > const & asBdd() const
storm::expressions::Variable const & getPrimedBlockVariable() const
storm::dd::Bdd< DdType > getStates() const
storm::dd::Add< DdType, ValueType > const & asAdd() const
uint64_t getNumberOfStates() const
Base class for all symbolic models.
#define STORM_LOG_WARN(message)
#define STORM_LOG_TRACE(message)
#define STORM_LOG_ERROR(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
std::pair< storm::RationalNumber, storm::RationalNumber > count(std::vector< storm::storage::BitVector > const &origSets, std::vector< storm::storage::BitVector > const &intersects, std::vector< storm::storage::BitVector > const &intersectsInfo, storm::RationalNumber val, bool plus, uint64_t remdepth)