#include "src/storage/Decomposition.h" #include #include "src/storage/StronglyConnectedComponent.h" #include "src/storage/MaximalEndComponent.h" #include "src/utility/constants.h" namespace storm { namespace storage { template Decomposition::Decomposition() : blocks() { // Intentionally left empty. } template Decomposition::Decomposition(Decomposition const& other) : blocks(other.blocks) { // Intentionally left empty. } template Decomposition& Decomposition::operator=(Decomposition const& other) { this->blocks = other.blocks; return *this; } template Decomposition::Decomposition(Decomposition&& other) : blocks(std::move(other.blocks)) { // Intentionally left empty. } template Decomposition& Decomposition::operator=(Decomposition&& other) { this->blocks = std::move(other.blocks); return *this; } template std::size_t Decomposition::size() const { return blocks.size(); } template bool Decomposition::empty() const { return blocks.empty(); } template typename Decomposition::iterator Decomposition::begin() { return blocks.begin(); } template typename Decomposition::iterator Decomposition::end() { return blocks.end(); } template typename Decomposition::const_iterator Decomposition::begin() const { return blocks.begin(); } template typename Decomposition::const_iterator Decomposition::end() const { return blocks.end(); } template BlockType const& Decomposition::getBlock(uint_fast64_t index) const { return blocks.at(index); } template BlockType& Decomposition::getBlock(uint_fast64_t index) { return blocks.at(index); } template BlockType const& Decomposition::operator[](uint_fast64_t index) const { return blocks[index]; } template BlockType& Decomposition::operator[](uint_fast64_t index) { return blocks[index]; } template template storm::storage::SparseMatrix Decomposition::extractPartitionDependencyGraph(storm::storage::SparseMatrix const& matrix) const { // First, we need to create a mapping of states to their block index, to ease the computation of dependency // transitions later. std::vector stateToBlockMap(matrix.getRowGroupCount()); for (uint_fast64_t i = 0; i < this->size(); ++i) { for (auto state : this->getBlock(i)) { stateToBlockMap[state] = i; } } // The resulting sparse matrix will have as many rows/columns as there are blocks in the partition. storm::storage::SparseMatrixBuilder dependencyGraphBuilder(this->size(), this->size()); for (uint_fast64_t currentBlockIndex = 0; currentBlockIndex < this->size(); ++currentBlockIndex) { // Get the next block. block_type const& block = this->getBlock(currentBlockIndex); // Now, we determine the blocks which are reachable (in one step) from the current block. boost::container::flat_set allTargetBlocks; for (auto state : block) { for (auto const& transitionEntry : matrix.getRowGroup(state)) { uint_fast64_t targetBlock = stateToBlockMap[transitionEntry.getColumn()]; // We only need to consider transitions that are actually leaving the SCC. if (targetBlock != currentBlockIndex) { allTargetBlocks.insert(targetBlock); } } } // Now we can just enumerate all the target blocks and insert the corresponding transitions. for (auto const& targetBlock : allTargetBlocks) { dependencyGraphBuilder.addNextValue(currentBlockIndex, targetBlock, storm::utility::one()); } } return dependencyGraphBuilder.build(); } template std::ostream& operator<<(std::ostream& out, Decomposition const& decomposition) { out << "["; if (decomposition.size() > 0) { for (uint_fast64_t blockIndex = 0; blockIndex < decomposition.size() - 1; ++blockIndex) { out << decomposition.blocks[blockIndex] << ", "; } out << decomposition.blocks.back(); } out << "]"; return out; } template storm::storage::SparseMatrix Decomposition::extractPartitionDependencyGraph(storm::storage::SparseMatrix const& matrix) const; template storm::storage::SparseMatrix Decomposition::extractPartitionDependencyGraph(storm::storage::SparseMatrix const& matrix) const; template class Decomposition; template std::ostream& operator<<(std::ostream& out, Decomposition const& decomposition); template storm::storage::SparseMatrix Decomposition::extractPartitionDependencyGraph(storm::storage::SparseMatrix const& matrix) const; template storm::storage::SparseMatrix Decomposition::extractPartitionDependencyGraph(storm::storage::SparseMatrix const& matrix) const; template class Decomposition; template std::ostream& operator<<(std::ostream& out, Decomposition const& decomposition); template class Decomposition; template std::ostream& operator<<(std::ostream& out, Decomposition const& decomposition); } // namespace storage } // namespace storm