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