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