#ifndef STORM_STORAGE_STRONGLYCONNECTEDCOMPONENTDECOMPOSITION_H_ #define STORM_STORAGE_STRONGLYCONNECTEDCOMPONENTDECOMPOSITION_H_ #include "src/storage/SparseMatrix.h" #include "src/storage/Decomposition.h" #include "src/storage/StronglyConnectedComponent.h" #include "src/storage/BitVector.h" namespace storm { namespace models { // Forward declare the abstract model class. template <typename ValueType> class AbstractModel; } namespace storage { /*! * This class represents the decomposition of a graph-like structure into its strongly connected components. */ template <typename ValueType> class StronglyConnectedComponentDecomposition : public Decomposition<StronglyConnectedComponent> { public: /* * Creates an empty SCC decomposition. */ StronglyConnectedComponentDecomposition(); /* * Creates an SCC decomposition of the given model. * * @param model The model to decompose into SCCs. * @param dropNaiveSccs A flag that indicates whether trivial SCCs (i.e. SCCs consisting of just one state * without a self-loop) are to be kept in the decomposition. * @param onlyBottomSccs If set to true, only bottom SCCs, i.e. SCCs in which all states have no way of * leaving the SCC), are kept. */ StronglyConnectedComponentDecomposition(storm::models::AbstractModel<ValueType> const& model, bool dropNaiveSccs = false, bool onlyBottomSccs = false); /* * Creates an SCC decomposition of the given block in the given model. * * @param model The model whose block to decompose. * @param block The block to decompose into SCCs. * @param dropNaiveSccs A flag that indicates whether trivial SCCs (i.e. SCCs consisting of just one state * without a self-loop) are to be kept in the decomposition. * @param onlyBottomSccs If set to true, only bottom SCCs, i.e. SCCs in which all states have no way of * leaving the SCC), are kept. */ StronglyConnectedComponentDecomposition(storm::models::AbstractModel<ValueType> const& model, StateBlock const& block, bool dropNaiveSccs = false, bool onlyBottomSccs = false); /* * Creates an SCC decomposition of the given subsystem in the given model. * * @param model The model that contains the block. * @param subsystem A bit vector indicating which subsystem to consider for the decomposition into SCCs. * @param dropNaiveSccs A flag that indicates whether trivial SCCs (i.e. SCCs consisting of just one state * without a self-loop) are to be kept in the decomposition. * @param onlyBottomSccs If set to true, only bottom SCCs, i.e. SCCs in which all states have no way of * leaving the SCC), are kept. */ StronglyConnectedComponentDecomposition(storm::models::AbstractModel<ValueType> const& model, storm::storage::BitVector const& subsystem, bool dropNaiveSccs = false, bool onlyBottomSccs = false); /* * Creates an SCC decomposition of the given subsystem in the given system (whose transition relation is * given by a sparse matrix). * * @param transitionMatrix The transition matrix of the system to decompose. * @param subsystem A bit vector indicating which subsystem to consider for the decomposition into SCCs. * @param dropNaiveSccs A flag that indicates whether trivial SCCs (i.e. SCCs consisting of just one state * without a self-loop) are to be kept in the decomposition. * @param onlyBottomSccs If set to true, only bottom SCCs, i.e. SCCs in which all states have no way of * leaving the SCC), are kept. */ StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, bool dropNaiveSccs = false, bool onlyBottomSccs = false); /*! * Creates an SCC decomposition by copying the given SCC decomposition. * * @oaram other The SCC decomposition to copy. */ StronglyConnectedComponentDecomposition(StronglyConnectedComponentDecomposition const& other); /*! * Assigns the contents of the given SCC decomposition to the current one by copying its contents. * * @oaram other The SCC decomposition from which to copy-assign. */ StronglyConnectedComponentDecomposition& operator=(StronglyConnectedComponentDecomposition const& other); /*! * Creates an SCC decomposition by moving the given SCC decomposition. * * @oaram other The SCC decomposition to move. */ StronglyConnectedComponentDecomposition(StronglyConnectedComponentDecomposition&& other); /*! * Assigns the contents of the given SCC decomposition to the current one by moving its contents. * * @oaram other The SCC decomposition from which to copy-assign. */ StronglyConnectedComponentDecomposition& operator=(StronglyConnectedComponentDecomposition&& other); private: /*! * Performs the SCC decomposition of the given model. As a side-effect this fills the vector of * blocks of the decomposition. * * @param model The model to decompose into SCCs. * @param dropNaiveSccs A flag that indicates whether trivial SCCs (i.e. SCCs consisting of just one state * without a self-loop) are to be kept in the decomposition. * @param onlyBottomSccs If set to true, only bottom SCCs, i.e. SCCs in which all states have no way of * leaving the SCC), are kept. */ void performSccDecomposition(storm::models::AbstractModel<ValueType> const& model, bool dropNaiveSccs, bool onlyBottomSccs); /* * Performs the SCC decomposition of the given block in the given model. As a side-effect this fills * the vector of blocks of the decomposition. * * @param transitionMatrix The transition matrix of the system to decompose. * @param subsystem A bit vector indicating which subsystem to consider for the decomposition into SCCs. * @param dropNaiveSccs A flag that indicates whether trivial SCCs (i.e. SCCs consisting of just one state * without a self-loop) are to be kept in the decomposition. * @param onlyBottomSccs If set to true, only bottom SCCs, i.e. SCCs in which all states have no way of * leaving the SCC), are kept. */ void performSccDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs); /*! * Uses the algorithm by Gabow/Cheriyan/Mehlhorn ("Path-based strongly connected component algorithm") to * compute a mapping of states to their SCCs. All arguments given by (non-const) reference are modified by * the function as a side-effect. * * @param transitionMatrix The transition matrix of the system to decompose. * @param startState The starting state for the search of Tarjan's algorithm. * @param statesWithSelfLoop A bit vector that is to be filled with all states that have a self-loop. This * is later needed for identification of the naive SCCs. * @param subsystem The subsystem to search. * @param currentIndex The next free index that can be assigned to states. * @param hasPreorderNumber A bit that is used to keep track of the states that already have a preorder number. * @param preorderNumbers A vector storing the preorder number for each state. * @param s The stack S used by the algorithm. * @param p The stack S used by the algorithm. * @param stateHasScc A bit vector containing all states that have already been assigned to an SCC. * @param stateToSccMapping A mapping from states to the SCC indices they belong to. As a side effect of this * function this mapping is filled (for all states reachable from the starting state). * @param sccCount The number of SCCs that have been computed. As a side effect of this function, this count * is increased. */ void performSccDecompositionGCM(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint_fast64_t startState, storm::storage::BitVector& statesWithSelfLoop, storm::storage::BitVector const& subsystem, uint_fast64_t& currentIndex, storm::storage::BitVector& hasPreorderNumber, std::vector<uint_fast64_t>& preorderNumbers, std::vector<uint_fast64_t>& s, std::vector<uint_fast64_t>& p, storm::storage::BitVector& stateHasScc, std::vector<uint_fast64_t>& stateToSccMapping, uint_fast64_t& sccCount); }; } } #endif /* STORM_STORAGE_STRONGLYCONNECTEDCOMPONENTDECOMPOSITION_H_ */