#ifndef STORM_MODELCHECKER_REACHABILITY_SPARSEDTMCELIMINATIONMODELCHECKER_H_ #define STORM_MODELCHECKER_REACHABILITY_SPARSEDTMCELIMINATIONMODELCHECKER_H_ #include "src/storage/sparse/StateType.h" #include "src/models/sparse/Dtmc.h" #include "src/modelchecker/propositional/SparsePropositionalModelChecker.h" #include "src/utility/constants.h" namespace storm { namespace storage { template class StronglyConnectedComponentDecomposition; } namespace modelchecker { template class SparseDtmcEliminationModelChecker : public SparsePropositionalModelChecker { public: typedef typename SparseDtmcModelType::ValueType ValueType; typedef typename SparseDtmcModelType::RewardModelType RewardModelType; /*! * Creates an elimination-based model checker for the given model. * * @param model The model to analyze. * @param computeResultsForInitialStatesOnly If set to true, the results are only computed for */ explicit SparseDtmcEliminationModelChecker(storm::models::sparse::Dtmc const& model, bool computeResultsForInitialStatesOnly = true); // The implemented methods of the AbstractModelChecker interface. virtual bool canHandle(storm::logic::Formula const& formula) const override; virtual std::unique_ptr computeBoundedUntilProbabilities(storm::logic::BoundedUntilFormula const& pathFormula, bool qualitative = false, boost::optional const& optimalityType = boost::optional()) override; virtual std::unique_ptr computeUntilProbabilities(storm::logic::UntilFormula const& pathFormula, bool qualitative = false, boost::optional const& optimalityType = boost::optional()) override; virtual std::unique_ptr computeReachabilityRewards(storm::logic::ReachabilityRewardFormula const& rewardPathFormula, boost::optional const& rewardModelName = boost::optional(), bool qualitative = false, boost::optional const& optimalityType = boost::optional()) override; virtual std::unique_ptr computeConditionalProbabilities(storm::logic::ConditionalPathFormula const& pathFormula, bool qualitative = false, boost::optional const& optimalityType = boost::optional()) override; virtual std::unique_ptr computeLongRunAverage(storm::logic::StateFormula const& stateFormula, bool qualitative = false, boost::optional const& optimalityType = boost::optional()) override; private: class FlexibleSparseMatrix { public: typedef uint_fast64_t index_type; typedef ValueType value_type; typedef std::vector> row_type; typedef typename row_type::iterator iterator; typedef typename row_type::const_iterator const_iterator; FlexibleSparseMatrix() = default; FlexibleSparseMatrix(index_type rows); void reserveInRow(index_type row, index_type numberOfElements); row_type& getRow(index_type); row_type const& getRow(index_type) const; index_type getNumberOfRows() const; void print() const; bool empty() const; void filter(storm::storage::BitVector const& rowFilter, storm::storage::BitVector const& columnFilter); /*! * Checks whether the given state has a self-loop with an arbitrary probability in the probability matrix. * * @param state The state for which to check whether it possesses a self-loop. * @return True iff the given state has a self-loop with an arbitrary probability in the probability matrix. */ bool hasSelfLoop(storm::storage::sparse::state_type state); private: std::vector data; }; class StatePriorityQueue { public: virtual bool hasNextState() const = 0; virtual storm::storage::sparse::state_type popNextState() = 0; virtual void update(storm::storage::sparse::state_type state, FlexibleSparseMatrix const& transitionMatrix, FlexibleSparseMatrix const& backwardTransitions, std::vector const& oneStepProbabilities); virtual std::size_t size() const = 0; }; class StaticStatePriorityQueue : public StatePriorityQueue { public: StaticStatePriorityQueue(std::vector const& sortedStates); virtual bool hasNextState() const override; virtual storm::storage::sparse::state_type popNextState() override; virtual std::size_t size() const override; private: std::vector sortedStates; uint_fast64_t currentPosition; }; struct PriorityComparator { bool operator()(std::pair const& first, std::pair const& second) { return (first.second < second.second) || (first.second == second.second && first.first < second.first) ; } }; typedef std::function const& oneStepProbabilities)> PenaltyFunctionType; class DynamicPenaltyStatePriorityQueue : public StatePriorityQueue { public: DynamicPenaltyStatePriorityQueue(std::vector> const& sortedStatePenaltyPairs, PenaltyFunctionType const& penaltyFunction); virtual bool hasNextState() const override; virtual storm::storage::sparse::state_type popNextState() override; virtual void update(storm::storage::sparse::state_type state, FlexibleSparseMatrix const& transitionMatrix, FlexibleSparseMatrix const& backwardTransitions, std::vector const& oneStepProbabilities) override; virtual std::size_t size() const override; private: std::set, PriorityComparator> priorityQueue; std::unordered_map stateToPriorityMapping; PenaltyFunctionType penaltyFunction; }; static std::vector computeLongRunValues(storm::storage::SparseMatrix const& transitionMatrix, storm::storage::SparseMatrix const& backwardTransitions, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& statesWithProbabilityGreater0, storm::storage::StronglyConnectedComponentDecomposition const& bsccDecomposition, bool computeResultsForInitialStatesOnly, std::vector& stateValues); static std::vector computeReachabilityValues(storm::storage::SparseMatrix const& transitionMatrix, std::vector& values, storm::storage::SparseMatrix const& backwardTransitions, storm::storage::BitVector const& initialStates, bool computeResultsForInitialStatesOnly, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector const& oneStepProbabilitiesToTarget); static std::unique_ptr createStatePriorityQueue(boost::optional> const& stateDistances, FlexibleSparseMatrix const& transitionMatrix, FlexibleSparseMatrix const& backwardTransitions, std::vector& oneStepProbabilities, storm::storage::BitVector const& states); static std::unique_ptr createNaivePriorityQueue(storm::storage::BitVector const& states); static void performPrioritizedStateElimination(std::unique_ptr& priorityQueue, FlexibleSparseMatrix& transitionMatrix, FlexibleSparseMatrix& backwardTransitions, std::vector& values, storm::storage::BitVector const& initialStates, bool computeResultsForInitialStatesOnly); static void performOrdinaryStateElimination(FlexibleSparseMatrix& transitionMatrix, FlexibleSparseMatrix& backwardTransitions, storm::storage::BitVector const& subsystem, storm::storage::BitVector const& initialStates, bool computeResultsForInitialStatesOnly, std::vector& values, boost::optional>& additionalStateValues, boost::optional> const& distanceBasedPriorities); static void performOrdinaryStateElimination(FlexibleSparseMatrix& transitionMatrix, FlexibleSparseMatrix& backwardTransitions, storm::storage::BitVector const& subsystem, storm::storage::BitVector const& initialStates, bool computeResultsForInitialStatesOnly, std::vector& values, boost::optional> const& distanceBasedPriorities); static uint_fast64_t performHybridStateElimination(storm::storage::SparseMatrix const& forwardTransitions, FlexibleSparseMatrix& transitionMatrix, FlexibleSparseMatrix& backwardTransitions, storm::storage::BitVector const& subsystem, storm::storage::BitVector const& initialStates, bool computeResultsForInitialStatesOnly, std::vector& values, boost::optional> const& distanceBasedPriorities); static uint_fast64_t treatScc(FlexibleSparseMatrix& matrix, std::vector& values, storm::storage::BitVector const& entryStates, storm::storage::BitVector const& scc, storm::storage::BitVector const& initialStates, storm::storage::SparseMatrix const& forwardTransitions, FlexibleSparseMatrix& backwardTransitions, bool eliminateEntryStates, uint_fast64_t level, uint_fast64_t maximalSccSize, std::vector& entryStateQueue, bool computeResultsForInitialStatesOnly, boost::optional> const& distanceBasedPriorities = boost::none); static FlexibleSparseMatrix getFlexibleSparseMatrix(storm::storage::SparseMatrix const& matrix, bool setAllValuesToOne = false); typedef std::function ValueUpdateCallback; typedef std::function PredecessorUpdateCallback; typedef std::function PriorityUpdateCallback; typedef std::function PredecessorFilterCallback; static void eliminateState(storm::storage::sparse::state_type state, FlexibleSparseMatrix& matrix, FlexibleSparseMatrix& backwardTransitions, ValueUpdateCallback const& valueUpdateCallback, PredecessorUpdateCallback const& predecessorCallback, boost::optional const& priorityUpdateCallback = boost::none, boost::optional const& predecessorFilterCallback = boost::none, bool removeForwardTransitions = true); static std::vector getDistanceBasedPriorities(storm::storage::SparseMatrix const& transitionMatrix, storm::storage::SparseMatrix const& transitionMatrixTransposed, storm::storage::BitVector const& initialStates, std::vector const& oneStepProbabilities, bool forward, bool reverse); static std::vector getStateDistances(storm::storage::SparseMatrix const& transitionMatrix, storm::storage::SparseMatrix const& transitionMatrixTransposed, storm::storage::BitVector const& initialStates, std::vector const& oneStepProbabilities, bool forward); static uint_fast64_t computeStatePenalty(storm::storage::sparse::state_type const& state, FlexibleSparseMatrix const& transitionMatrix, FlexibleSparseMatrix const& backwardTransitions, std::vector const& oneStepProbabilities); static uint_fast64_t computeStatePenaltyRegularExpression(storm::storage::sparse::state_type const& state, FlexibleSparseMatrix const& transitionMatrix, FlexibleSparseMatrix const& backwardTransitions, std::vector const& oneStepProbabilities); static bool checkConsistent(FlexibleSparseMatrix& transitionMatrix, FlexibleSparseMatrix& backwardTransitions); // A flag that indicates whether this model checker is supposed to produce results for all states or just for the initial states. bool computeResultsForInitialStatesOnly; }; } // namespace modelchecker } // namespace storm #endif /* STORM_MODELCHECKER_REACHABILITY_SPARSEDTMCELIMINATIONMODELCHECKER_H_ */