18namespace bisimulation {
20template<storm::dd::DdType DdType,
typename ValueType>
25template<storm::dd::DdType DdType,
typename ValueType>
27 std::pair<storm::expressions::Variable, storm::expressions::Variable>
const& blockVariables, uint64_t numberOfBlocks,
29 : partition(partitionAdd),
30 changedStates(changedStates),
31 blockVariables(blockVariables),
32 numberOfBlocks(numberOfBlocks),
33 nextFreeBlockIndex(nextFreeBlockIndex) {
37template<storm::dd::DdType DdType,
typename ValueType>
39 std::pair<storm::expressions::Variable, storm::expressions::Variable>
const& blockVariables, uint64_t numberOfBlocks,
41 : partition(partitionBdd),
42 changedStates(changedStates),
43 blockVariables(blockVariables),
44 numberOfBlocks(numberOfBlocks),
45 nextFreeBlockIndex(nextFreeBlockIndex) {
49template<storm::dd::DdType DdType,
typename ValueType>
51 return this->partition == other.partition && this->blockVariables == other.blockVariables && this->numberOfBlocks == other.numberOfBlocks &&
52 this->nextFreeBlockIndex == other.nextFreeBlockIndex;
55template<storm::dd::DdType DdType,
typename ValueType>
57 uint64_t nextFreeBlockIndex,
62template<storm::dd::DdType DdType,
typename ValueType>
64 uint64_t nextFreeBlockIndex,
69template<storm::dd::DdType DdType,
typename ValueType>
70boost::optional<std::pair<std::shared_ptr<storm::logic::Formula const>, std::shared_ptr<storm::logic::Formula const>>>
72 boost::optional<std::pair<std::shared_ptr<storm::logic::Formula const>, std::shared_ptr<storm::logic::Formula const>>> result;
81 result = std::pair<std::shared_ptr<storm::logic::Formula const>, std::shared_ptr<storm::logic::Formula const>>();
89 result = std::pair<std::shared_ptr<storm::logic::Formula const>, std::shared_ptr<storm::logic::Formula const>>();
90 result.get().first = std::make_shared<storm::logic::BooleanLiteralFormula>(
true);
97template<storm::dd::DdType DdType,
typename ValueType>
100 std::vector<std::shared_ptr<storm::logic::Formula const>>
const& formulas) {
101 auto const& bisimulationSettings = storm::settings::getModule<storm::settings::modules::BisimulationSettings>();
103 boost::optional<std::pair<std::shared_ptr<storm::logic::Formula const>, std::shared_ptr<storm::logic::Formula const>>> constraintTargetFormulas;
105 constraintTargetFormulas = extractConstraintTargetFormulas(*formulas.front());
109 return createDistanceBased(model, *constraintTargetFormulas.get().first, *constraintTargetFormulas.get().second);
115template<storm::dd::DdType DdType,
typename ValueType>
119 std::vector<storm::expressions::Expression> expressionVector;
120 for (
auto const& expression : preservationInformation.
getExpressions()) {
121 expressionVector.emplace_back(expression);
124 return create(model, expressionVector, bisimulationType);
127template<storm::dd::DdType DdType,
typename ValueType>
133 std::unique_ptr<storm::modelchecker::CheckResult> subresult = propositionalChecker.check(constraintFormula);
135 subresult = propositionalChecker.check(targetFormula);
138 return createDistanceBased(model, constraintStates, targetStates);
141template<storm::dd::DdType DdType,
typename ValueType>
147 std::pair<storm::expressions::Variable, storm::expressions::Variable> blockVariables = createBlockVariables(model);
149 auto start = std::chrono::high_resolution_clock::now();
156 uint64_t blockCount = 0;
160 while (!backwardFrontier.
isZero()) {
161 partitionBdd |= backwardFrontier && manager.getEncoding(blockVariables.first, blockCount++,
false);
162 coveredStates |= backwardFrontier;
164 !coveredStates && constraintStates;
169 partitionBdd |= (model.
getReachableStates() && !coveredStates) && manager.getEncoding(blockVariables.first, blockCount++,
false);
175 auto end = std::chrono::high_resolution_clock::now();
176 STORM_LOG_INFO(
"Created distance and label-based initial partition in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()
181 return Partition<DdType, ValueType>(partitionBdd.template toAdd<ValueType>(), blockVariables, blockCount, blockCount);
183 return Partition<DdType, ValueType>(partitionBdd, blockVariables, blockCount, blockCount);
187template<storm::dd::DdType DdType,
typename ValueType>
188std::pair<storm::expressions::Variable, storm::expressions::Variable> Partition<DdType, ValueType>::createBlockVariables(
192 uint64_t numberOfDdVariables = 0;
193 for (
auto const& metaVariable : model.getRowVariables()) {
194 auto const& ddMetaVariable =
manager.getMetaVariable(metaVariable);
195 numberOfDdVariables += ddMetaVariable.getNumberOfDdVariables();
198 auto mdp = model.template as<storm::models::symbolic::Mdp<DdType, ValueType>>();
199 for (
auto const& metaVariable : mdp->getNondeterminismVariables()) {
200 auto const& ddMetaVariable =
manager.getMetaVariable(metaVariable);
201 numberOfDdVariables += ddMetaVariable.getNumberOfDdVariables();
205 return createBlockVariables(manager, numberOfDdVariables);
208template<storm::dd::DdType DdType,
typename ValueType>
210 std::vector<storm::expressions::Expression>
const& expressions,
213 "Currently only strong bisimulation is supported.");
215 std::pair<storm::expressions::Variable, storm::expressions::Variable> blockVariables = createBlockVariables(model);
217 std::vector<storm::dd::Bdd<DdType>> stateSets;
218 for (
auto const& expression : expressions) {
219 stateSets.emplace_back(model.
getStates(expression));
221 auto start = std::chrono::high_resolution_clock::now();
222 std::pair<storm::dd::Bdd<DdType>, uint64_t> partitionBddAndBlockCount = createPartitionBdd(model.
getManager(), model, stateSets, blockVariables.first);
223 auto end = std::chrono::high_resolution_clock::now();
224 STORM_LOG_INFO(
"Created label-based initial partition in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).
count() <<
"ms.");
228 return Partition<DdType, ValueType>(partitionBddAndBlockCount.first.template toAdd<ValueType>(), blockVariables, partitionBddAndBlockCount.second,
229 partitionBddAndBlockCount.second);
231 return Partition<DdType, ValueType>(partitionBddAndBlockCount.first, blockVariables, partitionBddAndBlockCount.second,
232 partitionBddAndBlockCount.second);
236template<storm::dd::DdType DdType,
typename ValueType>
239 std::pair<storm::expressions::Variable, storm::expressions::Variable>
const& blockVariables) {
251template<storm::dd::DdType DdType,
typename ValueType>
253 return this->getStates().getNonZeroCount();
256template<storm::dd::DdType DdType,
typename ValueType>
258 if (this->storedAsAdd()) {
259 return this->asAdd().notZero().
existsAbstract({this->getBlockVariable()});
261 return this->asBdd().existsAbstract({this->getBlockVariable()});
265template<storm::dd::DdType DdType,
typename ValueType>
267 return static_cast<bool>(changedStates);
270template<storm::dd::DdType DdType,
typename ValueType>
272 return boost::get<storm::dd::Add<DdType, ValueType>>(changedStates.get());
275template<storm::dd::DdType DdType,
typename ValueType>
277 return boost::get<storm::dd::Bdd<DdType>>(changedStates.get());
280template<storm::dd::DdType DdType,
typename ValueType>
282 return numberOfBlocks;
285template<storm::dd::DdType DdType,
typename ValueType>
287 return partition.which() == 1;
290template<storm::dd::DdType DdType,
typename ValueType>
292 return partition.which() == 0;
295template<storm::dd::DdType DdType,
typename ValueType>
297 return boost::get<storm::dd::Add<DdType, ValueType>>(partition);
300template<storm::dd::DdType DdType,
typename ValueType>
302 return boost::get<storm::dd::Bdd<DdType>>(partition);
305template<storm::dd::DdType DdType,
typename ValueType>
307 return blockVariables;
310template<storm::dd::DdType DdType,
typename ValueType>
312 return blockVariables.first;
315template<storm::dd::DdType DdType,
typename ValueType>
317 return blockVariables.second;
320template<storm::dd::DdType DdType,
typename ValueType>
322 return nextFreeBlockIndex;
325template<storm::dd::DdType DdType,
typename ValueType>
327 if (this->storedAsBdd()) {
328 return asBdd().getNodeCount();
330 return asAdd().getNodeCount();
334template<storm::dd::DdType DdType>
337 if (currentStateSet.
isZero()) {
340 if (offset == stateSets.size()) {
341 callback(currentStateSet);
343 enumerateBlocksRec(stateSets, currentStateSet && stateSets[offset], offset + 1, blockVariable, callback);
344 enumerateBlocksRec(stateSets, currentStateSet && !stateSets[offset], offset + 1, blockVariable, callback);
348template<storm::dd::DdType DdType,
typename ValueType>
353 uint64_t blockCount = 0;
359 partitionBdd |= (stateSet && manager.getEncoding(blockVariable, blockCount, false));
366 return std::make_pair(partitionBdd, blockCount);
369template<storm::dd::DdType DdType,
typename ValueType>
370std::pair<storm::expressions::Variable, storm::expressions::Variable> Partition<DdType, ValueType>::createBlockVariables(
storm::dd::DdManager<DdType>& manager,
371 uint64_t numberOfDdVariables) {
372 std::vector<storm::expressions::Variable> blockVariables;
373 if (manager.hasMetaVariable(
"blocks")) {
375 while (manager.hasMetaVariable(
"block" + std::to_string(counter))) {
378 blockVariables = manager.addBitVectorMetaVariable(
"blocks" + std::to_string(counter), numberOfDdVariables, 2);
380 blockVariables =
manager.addBitVectorMetaVariable(
"blocks", numberOfDdVariables, 2);
382 return std::make_pair(blockVariables[0], blockVariables[1]);
385template class Partition<storm::dd::DdType::CUDD, double>;
387template class Partition<storm::dd::DdType::Sylvan, double>;
388template class Partition<storm::dd::DdType::Sylvan, storm::RationalNumber>;
389template class Partition<storm::dd::DdType::Sylvan, storm::RationalFunction>;
Bdd< LibraryType > notZero() const
Computes a BDD that represents the function in which all assignments with a function value unequal to...
Bdd< LibraryType > existsAbstract(std::set< storm::expressions::Variable > const &metaVariables) const
Existentially abstracts from the given meta variables.
Bdd< LibraryType > inverseRelationalProduct(Bdd< LibraryType > const &relation, std::set< storm::expressions::Variable > const &rowMetaVariables, std::set< storm::expressions::Variable > const &columnMetaVariables) const
Computes the inverse relational product of the current BDD and the given BDD representing a relation.
bool isZero() const
Retrieves whether this DD represents the constant zero function.
Bdd< LibraryType > swapVariables(std::vector< std::pair< storm::expressions::Variable, storm::expressions::Variable > > const &metaVariablePairs) const
Swaps the given pairs of meta variables in the BDD.
static Partition createTrivialChoicePartition(storm::models::symbolic::NondeterministicModel< DdType, ValueType > const &model, std::pair< storm::expressions::Variable, storm::expressions::Variable > const &blockVariables)
storm::expressions::Variable const & getBlockVariable() const
bool hasChangedStates() const
Retrieves whether this partition has information about the states whose partition block assignment ch...
storm::dd::Bdd< DdType > const & asBdd() const
storm::expressions::Variable const & getPrimedBlockVariable() const
uint64_t getNumberOfBlocks() const
storm::dd::Bdd< DdType > getStates() const
bool operator==(Partition< DdType, ValueType > const &other) const
uint64_t getNextFreeBlockIndex() const
storm::dd::Add< DdType, ValueType > const & changedStatesAsAdd() const
Retrieves the DD representing the states whose partition block assignment changed.
uint64_t getNodeCount() const
static Partition create(storm::models::symbolic::Model< DdType, ValueType > const &model, storm::storage::BisimulationType const &bisimulationType, PreservationInformation< DdType, ValueType > const &preservationInformation)
std::pair< storm::expressions::Variable, storm::expressions::Variable > const & getBlockVariables() const
storm::dd::Bdd< DdType > const & changedStatesAsBdd() const
storm::dd::Add< DdType, ValueType > const & asAdd() const
uint64_t getNumberOfStates() const
Partition< DdType, ValueType > replacePartition(storm::dd::Add< DdType, ValueType > const &newPartitionAdd, uint64_t numberOfBlocks, uint64_t nextFreeBlockIndex, boost::optional< storm::dd::Add< DdType, ValueType > > const &changedStates=boost::none) const
virtual ModelType getType() const
Return the actual type of the model.
Base class for all symbolic models.
storm::dd::DdManager< Type > & getManager() const
Retrieves the manager responsible for the DDs that represent this model.
storm::dd::Add< Type, ValueType > const & getTransitionMatrix() const
Retrieves the matrix representing the transitions of the model.
std::set< storm::expressions::Variable > const & getColumnVariables() const
Retrieves the meta variables used to encode the columns of the transition matrix and the vector indic...
virtual std::set< storm::expressions::Variable > const & getNondeterminismVariables() const
Retrieves all meta variables used to encode the nondeterminism.
std::vector< std::pair< storm::expressions::Variable, storm::expressions::Variable > > const & getRowColumnMetaVariablePairs() const
Retrieves the pairs of row and column meta variables.
std::set< storm::expressions::Variable > const & getRowVariables() const
Retrieves the meta variables used to encode the rows of the transition matrix and the vector indices.
virtual storm::dd::Bdd< Type > getStates(std::string const &label) const
Returns the sets of states labeled with the given label.
storm::dd::Bdd< Type > const & getReachableStates() const
Retrieves the reachable states of the model.
Base class for all nondeterministic symbolic models.
storm::dd::Bdd< Type > const & getIllegalMask() const
Retrieves a BDD characterizing all illegal nondeterminism encodings in the model.
#define STORM_LOG_INFO(message)
#define STORM_LOG_TRACE(message)
#define STORM_LOG_THROW(cond, exception, message)
void enumerateBlocksRec(std::vector< storm::dd::Bdd< DdType > > const &stateSets, storm::dd::Bdd< DdType > const ¤tStateSet, uint64_t offset, storm::expressions::Variable const &blockVariable, std::function< void(storm::dd::Bdd< DdType > const &)> const &callback)
FragmentSpecification propositional()
std::pair< storm::RationalNumber, storm::RationalNumber > count(std::vector< storm::storage::BitVector > const &origSets, std::vector< storm::storage::BitVector > const &intersects, std::vector< storm::storage::BitVector > const &intersectsInfo, storm::RationalNumber val, bool plus, uint64_t remdepth)
SettingsManager const & manager()
Retrieves the settings manager.