20using namespace bisimulation;
22template<storm::dd::DdType DdType,
typename ValueType>
26 return std::make_unique<NondeterministicModelPartitionRefiner<DdType, ValueType>>(
27 *model.template as<storm::models::symbolic::NondeterministicModel<DdType, ValueType>>(), initialPartition);
29 return std::make_unique<PartitionRefiner<DdType, ValueType>>(model, initialPartition);
33template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
37 preservationInformation(model),
42template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
47 preservationInformation(preservationInformation),
52template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
57 preservationInformation(model, formulas),
62template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
66 : model(model), preservationInformation(preservationInformation), refiner(
createRefiner(model, initialPartition)) {
70template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
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();
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.");
84 STORM_LOG_INFO(
"Initial partition has " << refiner->getStatePartition().getNumberOfBlocks() <<
" blocks.");
85 STORM_LOG_TRACE(
"Initial partition has " << refiner->getStatePartition().getNodeCount() <<
" nodes.");
88template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
91 STORM_LOG_ASSERT(this->refiner->getStatus() != Status::FixedPoint,
"Can only proceed if no fixpoint has been reached yet.");
93 auto start = std::chrono::high_resolution_clock::now();
94 auto timeOfLastMessage = start;
95 uint64_t iterations = 0;
98 refined = refiner->refine(mode);
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();
111 auto end = std::chrono::high_resolution_clock::now();
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).");
119template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
122 STORM_LOG_ASSERT(this->refiner->getStatus() != Status::FixedPoint,
"Can only proceed if no fixpoint has been reached yet.");
125 auto start = std::chrono::high_resolution_clock::now();
126 auto timeOfLastMessage = start;
127 uint64_t iterations = 0;
129 while (refined && iterations < steps) {
130 refined = refiner->refine(mode);
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();
147template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
149 return this->refiner->getStatus() == Status::FixedPoint;
152template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
155 std::shared_ptr<storm::models::Model<ExportValueType>> quotient;
156 if (this->refiner->getStatus() == Status::FixedPoint) {
159 quotient = extractor.
extract(model, refiner->getStatePartition(), preservationInformation);
162 storm::exceptions::InvalidOperationException,
"Can only extract partial quotient for discrete-time models.");
165 if (!partialQuotientExtractor) {
166 partialQuotientExtractor = std::make_unique<bisimulation::PartialQuotientExtractor<DdType, ValueType, ExportValueType>>(model, quotientFormat);
169 quotient = partialQuotientExtractor->extract(refiner->getStatePartition(), preservationInformation);
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);
184template class BisimulationDecomposition<storm::dd::DdType::CUDD, double>;
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>;
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 "ientFormat) const
Retrieves the quotient model after the bisimulation decomposition was computed.
~BisimulationDecomposition()
BisimulationDecomposition(storm::models::symbolic::Model< DdType, ValueType > const &model, storm::storage::BisimulationType const &bisimulationType)
bool isOfType(storm::models::ModelType const &modelType) const
Checks whether the model is of the given type.
Base class for all symbolic models.
#define STORM_LOG_INFO(message)
#define STORM_LOG_TRACE(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
std::unique_ptr< PartitionRefiner< DdType, ValueType > > createRefiner(storm::models::symbolic::Model< DdType, ValueType > const &model, Partition< DdType, ValueType > const &initialPartition)