Storm 1.14.0.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,
25 BisimulationOptions const& bisimulationOptions) {
27 return std::make_unique<NondeterministicModelPartitionRefiner<DdType, ValueType>>(
28 *model.template as<storm::models::symbolic::NondeterministicModel<DdType, ValueType>>(), initialPartition, bisimulationOptions);
29 } else {
30 return std::make_unique<PartitionRefiner<DdType, ValueType>>(model, initialPartition, bisimulationOptions);
31 }
32}
33
34template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
36 storm::storage::BisimulationType const& bisimulationType,
37 bisimulation::BisimulationOptions const& bisimulationOptions)
38 : model(model),
39 preservationInformation(model),
40 bisimulationOptions(bisimulationOptions),
41 refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, preservationInformation), bisimulationOptions)) {
42 this->initialize();
43}
44
45template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
48 bisimulation::PreservationInformation<DdType, ValueType> const& preservationInformation, bisimulation::BisimulationOptions const& bisimulationOptions)
49 : model(model),
50 preservationInformation(preservationInformation),
51 bisimulationOptions(bisimulationOptions),
52 refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, preservationInformation), bisimulationOptions)) {
53 this->initialize();
54}
55
56template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
58 storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas,
59 storm::storage::BisimulationType const& bisimulationType, bisimulation::BisimulationOptions const& bisimulationOptions)
60 : model(model),
61 preservationInformation(model, formulas),
62 bisimulationOptions(bisimulationOptions),
63 refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, formulas, bisimulationOptions), bisimulationOptions)) {
64 this->initialize();
65}
66
67template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
70 bisimulation::PreservationInformation<DdType, ValueType> const& preservationInformation, bisimulation::BisimulationOptions const& bisimulationOptions)
71 : model(model),
72 preservationInformation(preservationInformation),
73 bisimulationOptions(bisimulationOptions),
74 refiner(createRefiner(model, initialPartition, bisimulationOptions)) {
75 this->initialize();
76}
77
78template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
80
81template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
82void BisimulationDecomposition<DdType, ValueType, ExportValueType>::initialize() {
84 verboseProgress = generalSettings.isVerboseSet();
85 showProgressDelay = generalSettings.getShowProgressDelay();
86
87 auto start = std::chrono::high_resolution_clock::now();
88 this->refineWrtRewardModels();
89 auto end = std::chrono::high_resolution_clock::now();
90 STORM_LOG_INFO("Refining with respect to reward models took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms.");
91
92 STORM_LOG_INFO("Initial partition has " << refiner->getStatePartition().getNumberOfBlocks() << " blocks.");
93 STORM_LOG_TRACE("Initial partition has " << refiner->getStatePartition().getNodeCount() << " nodes.");
94}
95
96template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
98 STORM_LOG_ASSERT(refiner, "No suitable refiner.");
99 STORM_LOG_ASSERT(this->refiner->getStatus() != Status::FixedPoint, "Can only proceed if no fixpoint has been reached yet.");
100
101 auto start = std::chrono::high_resolution_clock::now();
102 auto timeOfLastMessage = start;
103 uint64_t iterations = 0;
104 bool refined = true;
105 while (refined) {
106 refined = refiner->refine(mode);
107
108 ++iterations;
109
110 auto now = std::chrono::high_resolution_clock::now();
111 auto durationSinceLastMessage = std::chrono::duration_cast<std::chrono::milliseconds>(now - timeOfLastMessage).count();
112 if (static_cast<uint64_t>(durationSinceLastMessage) >= showProgressDelay * 1000 || verboseProgress) {
113 auto durationSinceStart = std::chrono::duration_cast<std::chrono::milliseconds>(now - start).count();
114 STORM_LOG_INFO("State partition after " << iterations << " iterations (" << durationSinceStart << "ms) has "
115 << refiner->getStatePartition().getNumberOfBlocks() << " blocks.");
116 timeOfLastMessage = std::chrono::high_resolution_clock::now();
117 }
118 }
119 auto end = std::chrono::high_resolution_clock::now();
120
121 STORM_LOG_INFO("Partition refinement completed in "
122 << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms (" << iterations
123 << " iterations, signature: " << std::chrono::duration_cast<std::chrono::milliseconds>(refiner->getTotalSignatureTime()).count()
124 << "ms, refinement: " << std::chrono::duration_cast<std::chrono::milliseconds>(refiner->getTotalRefinementTime()).count() << "ms).");
125}
126
127template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
129 STORM_LOG_ASSERT(refiner, "No suitable refiner.");
130 STORM_LOG_ASSERT(this->refiner->getStatus() != Status::FixedPoint, "Can only proceed if no fixpoint has been reached yet.");
131 STORM_LOG_ASSERT(steps > 0, "Can only perform positive number of steps.");
132
133 auto start = std::chrono::high_resolution_clock::now();
134 auto timeOfLastMessage = start;
135 uint64_t iterations = 0;
136 bool refined = true;
137 while (refined && iterations < steps) {
138 refined = refiner->refine(mode);
139
140 ++iterations;
141
142 auto now = std::chrono::high_resolution_clock::now();
143 auto durationSinceLastMessage = std::chrono::duration_cast<std::chrono::seconds>(now - timeOfLastMessage).count();
144 if (static_cast<uint64_t>(durationSinceLastMessage) >= showProgressDelay || verboseProgress) {
145 auto durationSinceStart = std::chrono::duration_cast<std::chrono::seconds>(now - start).count();
146 STORM_LOG_INFO("State partition after " << iterations << " iterations (" << durationSinceStart << "ms) has "
147 << refiner->getStatePartition().getNumberOfBlocks() << " blocks.");
148 timeOfLastMessage = std::chrono::high_resolution_clock::now();
149 }
150 }
151
152 return !refined;
153}
154
155template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
157 return this->refiner->getStatus() == Status::FixedPoint;
158}
159
160template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
161std::shared_ptr<storm::models::Model<ExportValueType>> BisimulationDecomposition<DdType, ValueType, ExportValueType>::getQuotient(
162 storm::dd::bisimulation::QuotientFormat const& quotientFormat) const {
163 std::shared_ptr<storm::models::Model<ExportValueType>> quotient;
164 if (this->refiner->getStatus() == Status::FixedPoint) {
165 STORM_LOG_INFO("Starting full quotient extraction.");
166 QuotientExtractor<DdType, ValueType, ExportValueType> extractor(quotientFormat, bisimulationOptions);
167 quotient = extractor.extract(model, refiner->getStatePartition(), preservationInformation);
168 } else {
170 storm::exceptions::InvalidOperationException, "Can only extract partial quotient for discrete-time models.");
171
172 STORM_LOG_INFO("Starting partial quotient extraction.");
173 if (!partialQuotientExtractor) {
174 partialQuotientExtractor = std::make_unique<bisimulation::PartialQuotientExtractor<DdType, ValueType, ExportValueType>>(model, quotientFormat);
175 }
176
177 quotient = partialQuotientExtractor->extract(refiner->getStatePartition(), preservationInformation);
178 }
179
180 STORM_LOG_INFO("Quotient extraction done.");
181 return quotient;
182}
183
184template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType>
185void BisimulationDecomposition<DdType, ValueType, ExportValueType>::refineWrtRewardModels() {
186 for (auto const& rewardModelName : this->preservationInformation.getRewardModelNames()) {
187 auto const& rewardModel = this->model.getRewardModel(rewardModelName);
188 refiner->refineWrtRewardModel(rewardModel);
189 }
190}
191
192template class BisimulationDecomposition<storm::dd::DdType::CUDD, double>;
193
194template class BisimulationDecomposition<storm::dd::DdType::Sylvan, double>;
195template class BisimulationDecomposition<storm::dd::DdType::Sylvan, storm::RationalNumber>;
196template class BisimulationDecomposition<storm::dd::DdType::Sylvan, storm::RationalNumber, double>;
197template class BisimulationDecomposition<storm::dd::DdType::Sylvan, storm::RationalFunction>;
198
199} // namespace dd
200} // namespace storm
bool getReachedFixedPoint() const
Retrieves whether a fixed point has been reached.
BisimulationDecomposition(storm::models::symbolic::Model< DdType, ValueType > const &model, storm::storage::BisimulationType const &bisimulationType, bisimulation::BisimulationOptions const &bisimulationOptions=bisimulation::BisimulationOptions())
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.
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:27
#define STORM_LOG_TRACE(message)
Definition logging.h:15
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:28
std::unique_ptr< PartitionRefiner< DdType, ValueType > > createRefiner(storm::models::symbolic::Model< DdType, ValueType > const &model, Partition< DdType, ValueType > const &initialPartition, BisimulationOptions const &bisimulationOptions)
SettingsType const & getModule()
Get module.