20template<storm::dd::DdType DdType,
typename ValueType>
25 return std::make_unique<NondeterministicModelPartitionRefiner<DdType, ValueType>>(
26 *model.template as<storm::models::symbolic::NondeterministicModel<DdType, ValueType>>(), initialPartition, bisimulationOptions);
28 return std::make_unique<PartitionRefiner<DdType, ValueType>>(model, initialPartition, bisimulationOptions);
32template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
37 preservationInformation(model),
38 bisimulationOptions(bisimulationOptions),
39 refiner(
createRefiner(model,
Partition<
DdType, ValueType>::create(model, bisimulationType, preservationInformation), bisimulationOptions)) {
43template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
48 preservationInformation(preservationInformation),
49 bisimulationOptions(bisimulationOptions),
50 refiner(
createRefiner(model,
Partition<
DdType, ValueType>::create(model, bisimulationType, preservationInformation), bisimulationOptions)) {
54template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
59 preservationInformation(model, formulas),
60 bisimulationOptions(bisimulationOptions),
61 refiner(
createRefiner(model,
Partition<
DdType, ValueType>::create(model, bisimulationType, formulas, bisimulationOptions), bisimulationOptions)) {
65template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
70 preservationInformation(preservationInformation),
71 bisimulationOptions(bisimulationOptions),
72 refiner(
createRefiner(model, initialPartition, bisimulationOptions)) {
76template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
79template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
80void BisimulationDecomposition<DdType, ValueType, ExportValueType>::initialize() {
81 verboseProgress = bisimulationOptions.verbose;
82 showProgressDelay = bisimulationOptions.showProgressDelay;
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.");
89 STORM_LOG_INFO(
"Initial partition has " << refiner->getStatePartition().getNumberOfBlocks() <<
" blocks.");
90 STORM_LOG_TRACE(
"Initial partition has " << refiner->getStatePartition().getNodeCount() <<
" nodes.");
93template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
96 STORM_LOG_ASSERT(this->refiner->getStatus() != Status::FixedPoint,
"Can only proceed if no fixpoint has been reached yet.");
98 auto start = std::chrono::high_resolution_clock::now();
99 auto timeOfLastMessage = start;
100 uint64_t iterations = 0;
103 refined = refiner->refine(mode);
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();
116 auto end = std::chrono::high_resolution_clock::now();
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).");
124template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
127 STORM_LOG_ASSERT(this->refiner->getStatus() != Status::FixedPoint,
"Can only proceed if no fixpoint has been reached yet.");
130 auto start = std::chrono::high_resolution_clock::now();
131 auto timeOfLastMessage = start;
132 uint64_t iterations = 0;
134 while (refined && iterations < steps) {
135 refined = refiner->refine(mode);
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();
152template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
154 return this->refiner->getStatus() == Status::FixedPoint;
157template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
160 std::shared_ptr<storm::models::Model<ExportValueType>> quotient;
161 if (this->refiner->getStatus() == Status::FixedPoint) {
164 quotient = extractor.
extract(model, refiner->getStatePartition(), preservationInformation);
167 storm::exceptions::InvalidOperationException,
"Can only extract partial quotient for discrete-time models.");
170 if (!partialQuotientExtractor) {
171 partialQuotientExtractor = std::make_unique<bisimulation::PartialQuotientExtractor<DdType, ValueType, ExportValueType>>(model, quotientFormat);
174 quotient = partialQuotientExtractor->extract(refiner->getStatePartition(), preservationInformation);
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);
189template class BisimulationDecomposition<storm::dd::DdType::CUDD, double>;
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>;
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 "ientFormat) const
Retrieves the quotient model after the bisimulation decomposition was computed.
~BisimulationDecomposition()
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)
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)