#include "storm/utility/dd.h" #include "storm/storage/dd/DdManager.h" #include "storm/storage/dd/Add.h" #include "storm/storage/dd/Bdd.h" #include "storm/adapters/CarlAdapter.h" #include "storm/utility/macros.h" namespace storm { namespace utility { namespace dd { template storm::dd::Bdd computeReachableStates(storm::dd::Bdd const& initialStates, storm::dd::Bdd const& transitions, std::set const& rowMetaVariables, std::set const& columnMetaVariables) { STORM_LOG_TRACE("Computing reachable states: transition matrix BDD has " << transitions.getNodeCount() << " node(s) and " << transitions.getNonZeroCount() << " non-zero(s), " << initialStates.getNonZeroCount() << " initial states)."); auto start = std::chrono::high_resolution_clock::now(); storm::dd::Bdd reachableStates = initialStates; // Perform the BFS to discover all reachable states. bool changed = true; uint_fast64_t iteration = 0; do { changed = false; storm::dd::Bdd tmp = reachableStates.relationalProduct(transitions, rowMetaVariables, columnMetaVariables); storm::dd::Bdd newReachableStates = tmp && (!reachableStates); // Check whether new states were indeed discovered. if (!newReachableStates.isZero()) { changed = true; } reachableStates |= newReachableStates; ++iteration; STORM_LOG_TRACE("Iteration " << iteration << " of reachability computation completed: " << reachableStates.getNonZeroCount() << " reachable states found."); } while (changed); auto end = std::chrono::high_resolution_clock::now(); STORM_LOG_TRACE("Reachability computation completed in " << iteration << " iterations (" << std::chrono::duration_cast(end - start).count() << "ms)."); return reachableStates; } template storm::dd::Add getRowColumnDiagonal(storm::dd::DdManager const& ddManager, std::vector> const& rowColumnMetaVariablePairs) { storm::dd::Add result = ddManager.template getAddOne(); for (auto const& pair : rowColumnMetaVariablePairs) { result *= ddManager.template getIdentity(pair.first).equals(ddManager.template getIdentity(pair.second)).template toAdd(); result *= ddManager.getRange(pair.first).template toAdd() * ddManager.getRange(pair.second).template toAdd(); } return result; } template storm::dd::Bdd getRowColumnDiagonal(storm::dd::DdManager const& ddManager, std::vector> const& rowColumnMetaVariablePairs) { storm::dd::Bdd diagonal = ddManager.getBddOne(); for (auto const& pair : rowColumnMetaVariablePairs) { diagonal &= ddManager.template getIdentity(pair.first).equals(ddManager.template getIdentity(pair.second)); diagonal &= ddManager.getRange(pair.first) && ddManager.getRange(pair.second); } return diagonal; } template storm::dd::Bdd computeReachableStates(storm::dd::Bdd const& initialStates, storm::dd::Bdd const& transitions, std::set const& rowMetaVariables, std::set const& columnMetaVariables); template storm::dd::Bdd computeReachableStates(storm::dd::Bdd const& initialStates, storm::dd::Bdd const& transitions, std::set const& rowMetaVariables, std::set const& columnMetaVariables); template storm::dd::Add getRowColumnDiagonal(storm::dd::DdManager const& ddManager, std::vector> const& rowColumnMetaVariablePairs); template storm::dd::Add getRowColumnDiagonal(storm::dd::DdManager const& ddManager, std::vector> const& rowColumnMetaVariablePairs); template storm::dd::Bdd getRowColumnDiagonal(storm::dd::DdManager const& ddManager, std::vector> const& rowColumnMetaVariablePairs); template storm::dd::Bdd getRowColumnDiagonal(storm::dd::DdManager const& ddManager, std::vector> const& rowColumnMetaVariablePairs); template storm::dd::Add getRowColumnDiagonal(storm::dd::DdManager const& ddManager, std::vector> const& rowColumnMetaVariablePairs); } } }