Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
BisimulationDecomposition.cpp
Go to the documentation of this file.
2
16
17namespace storm {
18namespace dd {
19
20using namespace bisimulation;
21
22template<storm::dd::DdType DdType, typename ValueType>
23std::unique_ptr<PartitionRefiner<DdType, ValueType>> createRefiner(storm::models::symbolic::Model<DdType, ValueType> const& model,
24 Partition<DdType, ValueType> const& initialPartition) {
26 return std::make_unique<NondeterministicModelPartitionRefiner<DdType, ValueType>>(
27 *model.template as<storm::models::symbolic::NondeterministicModel<DdType, ValueType>>(), initialPartition);
28 } else {
29 return std::make_unique<PartitionRefiner<DdType, ValueType>>(model, initialPartition);
30 }
31}
32
33template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
35 storm::storage::BisimulationType const& bisimulationType)
36 : model(model),
37 preservationInformation(model),
38 refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, preservationInformation))) {
39 this->initialize();
40}
41
42template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
46 : model(model),
47 preservationInformation(preservationInformation),
48 refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, preservationInformation))) {
49 this->initialize();
50}
51
52template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
54 storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas,
55 storm::storage::BisimulationType const& bisimulationType)
56 : model(model),
57 preservationInformation(model, formulas),
58 refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, formulas))) {
59 this->initialize();
60}
61
62template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
66 : model(model), preservationInformation(preservationInformation), refiner(createRefiner(model, initialPartition)) {
67 this->initialize();
68}
69
70template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
72
73template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
75 auto const& generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>();
76 verboseProgress = generalSettings.isVerboseSet();
77 showProgressDelay = generalSettings.getShowProgressDelay();
78
79 auto start = std::chrono::high_resolution_clock::now();
80 this->refineWrtRewardModels();
81 auto end = std::chrono::high_resolution_clock::now();
82 STORM_LOG_INFO("Refining with respect to reward models took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms.");
83
84 STORM_LOG_INFO("Initial partition has " << refiner->getStatePartition().getNumberOfBlocks() << " blocks.");
85 STORM_LOG_TRACE("Initial partition has " << refiner->getStatePartition().getNodeCount() << " nodes.");
86}
87
88template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
90 STORM_LOG_ASSERT(refiner, "No suitable refiner.");
91 STORM_LOG_ASSERT(this->refiner->getStatus() != Status::FixedPoint, "Can only proceed if no fixpoint has been reached yet.");
92
93 auto start = std::chrono::high_resolution_clock::now();
94 auto timeOfLastMessage = start;
95 uint64_t iterations = 0;
96 bool refined = true;
97 while (refined) {
98 refined = refiner->refine(mode);
99
100 ++iterations;
101
102 auto now = std::chrono::high_resolution_clock::now();
103 auto durationSinceLastMessage = std::chrono::duration_cast<std::chrono::milliseconds>(now - timeOfLastMessage).count();
104 if (static_cast<uint64_t>(durationSinceLastMessage) >= showProgressDelay * 1000 || verboseProgress) {
105 auto durationSinceStart = std::chrono::duration_cast<std::chrono::milliseconds>(now - start).count();
106 STORM_LOG_INFO("State partition after " << iterations << " iterations (" << durationSinceStart << "ms) has "
107 << refiner->getStatePartition().getNumberOfBlocks() << " blocks.");
108 timeOfLastMessage = std::chrono::high_resolution_clock::now();
109 }
110 }
111 auto end = std::chrono::high_resolution_clock::now();
112
113 STORM_LOG_INFO("Partition refinement completed in "
114 << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms (" << iterations
115 << " iterations, signature: " << std::chrono::duration_cast<std::chrono::milliseconds>(refiner->getTotalSignatureTime()).count()
116 << "ms, refinement: " << std::chrono::duration_cast<std::chrono::milliseconds>(refiner->getTotalRefinementTime()).count() << "ms).");
117}
118
119template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
121 STORM_LOG_ASSERT(refiner, "No suitable refiner.");
122 STORM_LOG_ASSERT(this->refiner->getStatus() != Status::FixedPoint, "Can only proceed if no fixpoint has been reached yet.");
123 STORM_LOG_ASSERT(steps > 0, "Can only perform positive number of steps.");
124
125 auto start = std::chrono::high_resolution_clock::now();
126 auto timeOfLastMessage = start;
127 uint64_t iterations = 0;
128 bool refined = true;
129 while (refined && iterations < steps) {
130 refined = refiner->refine(mode);
131
132 ++iterations;
133
134 auto now = std::chrono::high_resolution_clock::now();
135 auto durationSinceLastMessage = std::chrono::duration_cast<std::chrono::seconds>(now - timeOfLastMessage).count();
136 if (static_cast<uint64_t>(durationSinceLastMessage) >= showProgressDelay || verboseProgress) {
137 auto durationSinceStart = std::chrono::duration_cast<std::chrono::seconds>(now - start).count();
138 STORM_LOG_INFO("State partition after " << iterations << " iterations (" << durationSinceStart << "ms) has "
139 << refiner->getStatePartition().getNumberOfBlocks() << " blocks.");
140 timeOfLastMessage = std::chrono::high_resolution_clock::now();
141 }
142 }
143
144 return !refined;
145}
146
147template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
149 return this->refiner->getStatus() == Status::FixedPoint;
150}
151
152template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
153std::shared_ptr<storm::models::Model<ExportValueType>> BisimulationDecomposition<DdType, ValueType, ExportValueType>::getQuotient(
154 storm::dd::bisimulation::QuotientFormat const& quotientFormat) const {
155 std::shared_ptr<storm::models::Model<ExportValueType>> quotient;
156 if (this->refiner->getStatus() == Status::FixedPoint) {
157 STORM_LOG_INFO("Starting full quotient extraction.");
159 quotient = extractor.extract(model, refiner->getStatePartition(), preservationInformation);
160 } else {
162 storm::exceptions::InvalidOperationException, "Can only extract partial quotient for discrete-time models.");
163
164 STORM_LOG_INFO("Starting partial quotient extraction.");
165 if (!partialQuotientExtractor) {
166 partialQuotientExtractor = std::make_unique<bisimulation::PartialQuotientExtractor<DdType, ValueType, ExportValueType>>(model, quotientFormat);
167 }
168
169 quotient = partialQuotientExtractor->extract(refiner->getStatePartition(), preservationInformation);
170 }
171
172 STORM_LOG_INFO("Quotient extraction done.");
173 return quotient;
174}
175
176template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
178 for (auto const& rewardModelName : this->preservationInformation.getRewardModelNames()) {
179 auto const& rewardModel = this->model.getRewardModel(rewardModelName);
180 refiner->refineWrtRewardModel(rewardModel);
181 }
182}
183
184template class BisimulationDecomposition<storm::dd::DdType::CUDD, double>;
185
186template class BisimulationDecomposition<storm::dd::DdType::Sylvan, double>;
187template class BisimulationDecomposition<storm::dd::DdType::Sylvan, storm::RationalNumber>;
188template class BisimulationDecomposition<storm::dd::DdType::Sylvan, storm::RationalNumber, double>;
189template class BisimulationDecomposition<storm::dd::DdType::Sylvan, storm::RationalFunction>;
190
191} // namespace dd
192} // namespace storm
bool getReachedFixedPoint() const
Retrieves whether a fixed point has been reached.
void compute(bisimulation::SignatureMode const &mode=bisimulation::SignatureMode::Eager)
Performs partition refinement until a fixpoint has been reached.
std::shared_ptr< storm::models::Model< ExportValueType > > getQuotient(storm::dd::bisimulation::QuotientFormat const &quotientFormat) const
Retrieves the quotient model after the bisimulation decomposition was computed.
BisimulationDecomposition(storm::models::symbolic::Model< DdType, ValueType > const &model, storm::storage::BisimulationType const &bisimulationType)
std::shared_ptr< storm::models::Model< ExportValueType > > extract(storm::models::symbolic::Model< DdType, ValueType > const &model, Partition< DdType, ValueType > const &partition, PreservationInformation< DdType, ValueType > const &preservationInformation)
bool isOfType(storm::models::ModelType const &modelType) const
Checks whether the model is of the given type.
Definition ModelBase.cpp:27
Base class for all symbolic models.
Definition Model.h:42
#define STORM_LOG_INFO(message)
Definition logging.h:24
#define STORM_LOG_TRACE(message)
Definition logging.h:12
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
std::unique_ptr< PartitionRefiner< DdType, ValueType > > createRefiner(storm::models::symbolic::Model< DdType, ValueType > const &model, Partition< DdType, ValueType > const &initialPartition)