4 changed files with 230 additions and 165 deletions
			
			
		- 
					143src/storm/modelchecker/helper/infinitehorizon/HybridInfiniteHorizonHelper.cpp
 - 
					87src/storm/modelchecker/helper/infinitehorizon/HybridInfiniteHorizonHelper.h
 - 
					101src/storm/modelchecker/helper/infinitehorizon/HybridNondeterministicInfiniteHorizonHelper.cpp
 - 
					64src/storm/modelchecker/helper/infinitehorizon/HybridNondeterministicInfiniteHorizonHelper.h
 
@ -0,0 +1,143 @@ | 
				
			|||
#include "HybridInfiniteHorizonHelper.h"
 | 
				
			|||
 | 
				
			|||
#include "storm/modelchecker/helper/infinitehorizon/SparseNondeterministicInfiniteHorizonHelper.h"
 | 
				
			|||
#include "storm/modelchecker/helper/infinitehorizon/SparseDeterministicInfiniteHorizonHelper.h"
 | 
				
			|||
#include "storm/modelchecker/helper/utility/SetInformationFromOtherHelper.h"
 | 
				
			|||
 | 
				
			|||
#include "storm/models/symbolic/NondeterministicModel.h"
 | 
				
			|||
 | 
				
			|||
#include "storm/storage/SparseMatrix.h"
 | 
				
			|||
 | 
				
			|||
#include "storm/utility/macros.h"
 | 
				
			|||
 | 
				
			|||
#include "storm/exceptions/NotSupportedException.h"
 | 
				
			|||
 | 
				
			|||
namespace storm { | 
				
			|||
    namespace modelchecker { | 
				
			|||
        namespace helper { | 
				
			|||
             | 
				
			|||
            template <typename ValueType, storm::dd::DdType DdType, bool Nondeterministic> | 
				
			|||
            HybridInfiniteHorizonHelper<ValueType, DdType, Nondeterministic>::HybridInfiniteHorizonHelper(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix) : _model(model), _transitionMatrix(transitionMatrix), _markovianStates(nullptr), _exitRates(nullptr) { | 
				
			|||
                // Intentionally left empty.
 | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template <typename ValueType, storm::dd::DdType DdType, bool Nondeterministic> | 
				
			|||
            HybridInfiniteHorizonHelper<ValueType, DdType, Nondeterministic>::HybridInfiniteHorizonHelper(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& markovianStates, storm::dd::Add<DdType, ValueType> const& exitRateVector) : _model(model), _transitionMatrix(transitionMatrix), _markovianStates(&markovianStates), _exitRates(&exitRateVector) { | 
				
			|||
                // Intentionally left empty.
 | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template <typename ValueType, storm::dd::DdType DdType, bool Nondeterministic> | 
				
			|||
            HybridInfiniteHorizonHelper<ValueType, DdType, Nondeterministic>::HybridInfiniteHorizonHelper(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector) : _model(model), _transitionMatrix(transitionMatrix), _markovianStates(nullptr), _exitRates(&exitRateVector) { | 
				
			|||
                // Intentionally left empty.
 | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template <typename ValueType, storm::dd::DdType DdType, bool Nondeterministic> | 
				
			|||
            std::unique_ptr<HybridQuantitativeCheckResult<DdType, ValueType>> HybridInfiniteHorizonHelper<ValueType, DdType, Nondeterministic>::computeLongRunAverageProbabilities(Environment const& env, storm::dd::Bdd<DdType> const& psiStates) { | 
				
			|||
                // Convert this query to an instance for the sparse engine.
 | 
				
			|||
                // Create ODD for the translation.
 | 
				
			|||
                storm::dd::Odd odd = _model.getReachableStates().createOdd(); | 
				
			|||
                // Translate all required components
 | 
				
			|||
                storm::storage::SparseMatrix<ValueType> explicitTransitionMatrix; | 
				
			|||
                if (_model.isNondeterministicModel()) { | 
				
			|||
                    explicitTransitionMatrix = _transitionMatrix.toMatrix(dynamic_cast<storm::models::symbolic::NondeterministicModel<DdType, ValueType> const&>(_model).getNondeterminismVariables(), odd, odd); | 
				
			|||
                } else { | 
				
			|||
                    explicitTransitionMatrix = _transitionMatrix.toMatrix(odd, odd); | 
				
			|||
                } | 
				
			|||
                std::vector<ValueType> explicitExitRateVector; | 
				
			|||
                storm::storage::BitVector explicitMarkovianStates; | 
				
			|||
                if (isContinuousTime()) { | 
				
			|||
                    explicitExitRateVector = _exitRates->toVector(odd); | 
				
			|||
                    if (_markovianStates) { | 
				
			|||
                        explicitMarkovianStates = _markovianStates->toVector(odd); | 
				
			|||
                    } | 
				
			|||
                } | 
				
			|||
                auto sparseHelper = createSparseHelper(explicitTransitionMatrix, explicitMarkovianStates, explicitExitRateVector, odd); | 
				
			|||
                auto explicitResult = sparseHelper->computeLongRunAverageProbabilities(env, psiStates.toVector(odd)); | 
				
			|||
                return std::make_unique<HybridQuantitativeCheckResult<DdType, ValueType>>(_model.getReachableStates(), _model.getManager().getBddZero(), _model.getManager().template getAddZero<ValueType>(), _model.getReachableStates(), std::move(odd), std::move(explicitResult)); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template <typename ValueType, storm::dd::DdType DdType, bool Nondeterministic> | 
				
			|||
            std::unique_ptr<HybridQuantitativeCheckResult<DdType, ValueType>> HybridInfiniteHorizonHelper<ValueType, DdType, Nondeterministic>::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::StandardRewardModel<DdType, ValueType> const& rewardModel) { | 
				
			|||
                // Convert this query to an instance for the sparse engine.
 | 
				
			|||
                // Create ODD for the translation.
 | 
				
			|||
                storm::dd::Odd odd = _model.getReachableStates().createOdd(); | 
				
			|||
                 | 
				
			|||
                // Translate all required components
 | 
				
			|||
                // Transitions and rewards
 | 
				
			|||
                storm::storage::SparseMatrix<ValueType> explicitTransitionMatrix; | 
				
			|||
                std::vector<ValueType> explicitStateRewards, explicitActionRewards; | 
				
			|||
                if (rewardModel.hasStateRewards()) { | 
				
			|||
                    explicitStateRewards = rewardModel.getStateRewardVector().toVector(odd); | 
				
			|||
                } | 
				
			|||
                if (_model.isNondeterministicModel() && rewardModel.hasStateActionRewards()) { | 
				
			|||
                    // Matrix and action-based vector have to be produced at the same time to guarantee the correct order
 | 
				
			|||
                    auto matrixRewards = _transitionMatrix.toMatrixVector(rewardModel.getStateActionRewardVector(), dynamic_cast<storm::models::symbolic::NondeterministicModel<DdType, ValueType> const&>(_model).getNondeterminismVariables(), odd, odd); | 
				
			|||
                    explicitTransitionMatrix = std::move(matrixRewards.first); | 
				
			|||
                    explicitActionRewards = std::move(matrixRewards.second); | 
				
			|||
                } else { | 
				
			|||
                    // Translate matrix only
 | 
				
			|||
                    explicitTransitionMatrix = _transitionMatrix.toMatrix(dynamic_cast<storm::models::symbolic::NondeterministicModel<DdType, ValueType> const&>(_model).getNondeterminismVariables(), odd, odd); | 
				
			|||
                    if (rewardModel.hasStateActionRewards()) { | 
				
			|||
                        // For deterministic models we can translate the action rewards easily
 | 
				
			|||
                        explicitActionRewards = rewardModel.getStateActionRewardVector().toVector(odd); | 
				
			|||
                    } | 
				
			|||
                } | 
				
			|||
                STORM_LOG_THROW(!rewardModel.hasTransitionRewards(), storm::exceptions::NotSupportedException, "Transition rewards are not supported in this engine."); | 
				
			|||
                // Continuous time information
 | 
				
			|||
                std::vector<ValueType> explicitExitRateVector; | 
				
			|||
                storm::storage::BitVector explicitMarkovianStates; | 
				
			|||
                if (isContinuousTime()) { | 
				
			|||
                    explicitExitRateVector = _exitRates->toVector(odd); | 
				
			|||
                    if (_markovianStates) { | 
				
			|||
                        explicitMarkovianStates = _markovianStates->toVector(odd); | 
				
			|||
                    } | 
				
			|||
                } | 
				
			|||
                auto sparseHelper = createSparseHelper(explicitTransitionMatrix, explicitMarkovianStates, explicitExitRateVector, odd); | 
				
			|||
                auto explicitResult = sparseHelper->computeLongRunAverageValues(env, rewardModel.hasStateRewards() ? &explicitStateRewards : nullptr, rewardModel.hasStateActionRewards() ? &explicitActionRewards : nullptr); | 
				
			|||
                return std::make_unique<HybridQuantitativeCheckResult<DdType, ValueType>>(_model.getReachableStates(), _model.getManager().getBddZero(), _model.getManager().template getAddZero<ValueType>(), _model.getReachableStates(), std::move(odd), std::move(explicitResult)); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template <typename ValueType, storm::dd::DdType DdType, bool Nondeterministic> | 
				
			|||
            bool HybridInfiniteHorizonHelper<ValueType, DdType, Nondeterministic>::isContinuousTime() const { | 
				
			|||
                STORM_LOG_ASSERT((_markovianStates == nullptr) || (_exitRates != nullptr), "Inconsistent information given: Have Markovian states but no exit rates." ); | 
				
			|||
                return _exitRates != nullptr; | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template <typename ValueType, storm::dd::DdType DdType, bool Nondeterministic> | 
				
			|||
            template <bool N, std::enable_if_t<N, int>> | 
				
			|||
            std::unique_ptr<SparseInfiniteHorizonHelper<ValueType, Nondeterministic>> HybridInfiniteHorizonHelper<ValueType, DdType, Nondeterministic>::createSparseHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, std::vector<ValueType> const& exitRates, storm::dd::Odd const& odd) const { | 
				
			|||
                std::unique_ptr<SparseInfiniteHorizonHelper<ValueType, Nondeterministic>> result; | 
				
			|||
                if (isContinuousTime()) { | 
				
			|||
                    result = std::make_unique<storm::modelchecker::helper::SparseNondeterministicInfiniteHorizonHelper<ValueType>>(transitionMatrix, markovianStates, exitRates); | 
				
			|||
                } else { | 
				
			|||
                    result = std::make_unique<storm::modelchecker::helper::SparseNondeterministicInfiniteHorizonHelper<ValueType>>(transitionMatrix); | 
				
			|||
                } | 
				
			|||
                storm::modelchecker::helper::setInformationFromOtherHelperNondeterministic(*result, *this, [&odd](storm::dd::Bdd<DdType> const& s){ return s.toVector(odd); }); | 
				
			|||
                STORM_LOG_WARN_COND(!this->isProduceSchedulerSet(), "Scheduler extraction not supported in Hybrid engine."); | 
				
			|||
                return result; | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template <typename ValueType, storm::dd::DdType DdType, bool Nondeterministic> | 
				
			|||
            template <bool N, std::enable_if_t<!N, int>> | 
				
			|||
            std::unique_ptr<SparseInfiniteHorizonHelper<ValueType, Nondeterministic>> HybridInfiniteHorizonHelper<ValueType, DdType, Nondeterministic>::createSparseHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, std::vector<ValueType> const& exitRates, storm::dd::Odd const& odd) const { | 
				
			|||
                std::unique_ptr<SparseInfiniteHorizonHelper<ValueType, Nondeterministic>> result; | 
				
			|||
                if (isContinuousTime()) { | 
				
			|||
                    result = std::make_unique<storm::modelchecker::helper::SparseDeterministicInfiniteHorizonHelper<ValueType>>(transitionMatrix, exitRates); | 
				
			|||
                } else { | 
				
			|||
                    result = std::make_unique<storm::modelchecker::helper::SparseDeterministicInfiniteHorizonHelper<ValueType>>(transitionMatrix); | 
				
			|||
                } | 
				
			|||
                storm::modelchecker::helper::setInformationFromOtherHelperDeterministic(*result, *this, [&odd](storm::dd::Bdd<DdType> const& s){ return s.toVector(odd); }); | 
				
			|||
                return result; | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template class HybridInfiniteHorizonHelper<double, storm::dd::DdType::CUDD, false>; | 
				
			|||
            template class HybridInfiniteHorizonHelper<double, storm::dd::DdType::CUDD, true>; | 
				
			|||
            template class HybridInfiniteHorizonHelper<double, storm::dd::DdType::Sylvan, false>; | 
				
			|||
            template class HybridInfiniteHorizonHelper<double, storm::dd::DdType::Sylvan, true>; | 
				
			|||
            template class HybridInfiniteHorizonHelper<storm::RationalNumber, storm::dd::DdType::Sylvan, false>; | 
				
			|||
            template class HybridInfiniteHorizonHelper<storm::RationalNumber, storm::dd::DdType::Sylvan, true>; | 
				
			|||
            template class HybridInfiniteHorizonHelper<storm::RationalFunction, storm::dd::DdType::Sylvan, false>; | 
				
			|||
             | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
@ -0,0 +1,87 @@ | 
				
			|||
#pragma once | 
				
			|||
#include "storm/modelchecker/helper/SingleValueModelCheckerHelper.h" | 
				
			|||
 | 
				
			|||
#include "storm/modelchecker/results/HybridQuantitativeCheckResult.h" | 
				
			|||
 | 
				
			|||
#include "storm/models/symbolic/Model.h" | 
				
			|||
#include "storm/models/symbolic/StandardRewardModel.h" | 
				
			|||
 | 
				
			|||
#include "storm/storage/dd/DdManager.h" | 
				
			|||
#include "storm/storage/dd/Add.h" | 
				
			|||
#include "storm/storage/dd/Bdd.h" | 
				
			|||
 | 
				
			|||
namespace storm { | 
				
			|||
    class Environment; | 
				
			|||
     | 
				
			|||
    namespace storage { | 
				
			|||
        template <typename ValueType> class SparseMatrix; | 
				
			|||
        class BitVector; | 
				
			|||
    } | 
				
			|||
     | 
				
			|||
    namespace modelchecker { | 
				
			|||
        namespace helper { | 
				
			|||
         | 
				
			|||
            template <typename ValueType, bool Nondeterministic> class SparseInfiniteHorizonHelper; | 
				
			|||
             | 
				
			|||
            /*! | 
				
			|||
             * Helper class for model checking queries that depend on the long run behavior of the (nondeterministic) system. | 
				
			|||
             */ | 
				
			|||
            template <typename ValueType, storm::dd::DdType DdType, bool Nondeterministic> | 
				
			|||
            class HybridInfiniteHorizonHelper : public SingleValueModelCheckerHelper<ValueType, DdType> { | 
				
			|||
 | 
				
			|||
            public: | 
				
			|||
                /*! | 
				
			|||
                 * Initializes the helper for a discrete time model (MDP or DTMC) | 
				
			|||
                 */ | 
				
			|||
                HybridInfiniteHorizonHelper(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix); | 
				
			|||
                 | 
				
			|||
                /*! | 
				
			|||
                 * Initializes the helper for a Markov Automaton | 
				
			|||
                 */ | 
				
			|||
                HybridInfiniteHorizonHelper(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& markovianStates, storm::dd::Add<DdType, ValueType> const& _exitRates); | 
				
			|||
                 | 
				
			|||
                /*! | 
				
			|||
                 * Initializes the helper for a CTMC | 
				
			|||
                 * @note The transition matrix must be probabilistic | 
				
			|||
                 */ | 
				
			|||
                HybridInfiniteHorizonHelper(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Add<DdType, ValueType> const& _exitRates); | 
				
			|||
                 | 
				
			|||
                /*! | 
				
			|||
                 * Computes the long run average probabilities, i.e., the fraction of the time we are in a psiState | 
				
			|||
                 * @return a value for each state | 
				
			|||
                 */ | 
				
			|||
                std::unique_ptr<HybridQuantitativeCheckResult<DdType, ValueType>> computeLongRunAverageProbabilities(Environment const& env, storm::dd::Bdd<DdType> const& psiStates); | 
				
			|||
                 | 
				
			|||
                /*! | 
				
			|||
                 * Computes the long run average rewards, i.e., the average reward collected per time unit | 
				
			|||
                 * @return a value for each state | 
				
			|||
                 */ | 
				
			|||
                std::unique_ptr<HybridQuantitativeCheckResult<DdType, ValueType>> computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::StandardRewardModel<DdType, ValueType> const& rewardModel); | 
				
			|||
                 | 
				
			|||
            protected: | 
				
			|||
                 | 
				
			|||
                /*! | 
				
			|||
                 * @return true iff this is a computation on a continuous time model (i.e. MA) | 
				
			|||
                 */ | 
				
			|||
                bool isContinuousTime() const; | 
				
			|||
                 | 
				
			|||
                /*! | 
				
			|||
                 * @return a sparse infinite horizon helper with the provided explicit model information. | 
				
			|||
                 * @param exitRates exit rates (ignored for discrete time models) | 
				
			|||
                 * @param markovianStates Markovian states or (ignored for non-MA) | 
				
			|||
                 */ | 
				
			|||
                template <bool N = Nondeterministic, std::enable_if_t<N, int> = 0> | 
				
			|||
                std::unique_ptr<SparseInfiniteHorizonHelper<ValueType, Nondeterministic>> createSparseHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, std::vector<ValueType> const& exitRates, storm::dd::Odd const& odd) const; | 
				
			|||
                template <bool N = Nondeterministic, std::enable_if_t<!N, int> = 0> | 
				
			|||
                std::unique_ptr<SparseInfiniteHorizonHelper<ValueType, Nondeterministic>> createSparseHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, std::vector<ValueType> const& exitRates, storm::dd::Odd const& odd) const; | 
				
			|||
                 | 
				
			|||
 | 
				
			|||
            private: | 
				
			|||
                storm::models::symbolic::Model<DdType, ValueType> const& _model; | 
				
			|||
                storm::dd::Add<DdType, ValueType> const& _transitionMatrix; | 
				
			|||
                storm::dd::Bdd<DdType> const* _markovianStates; | 
				
			|||
                storm::dd::Add<DdType, ValueType> const* _exitRates; | 
				
			|||
            }; | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
@ -1,101 +0,0 @@ | 
				
			|||
#include "HybridNondeterministicInfiniteHorizonHelper.h"
 | 
				
			|||
 | 
				
			|||
#include "storm/modelchecker/helper/infinitehorizon/SparseNondeterministicInfiniteHorizonHelper.h"
 | 
				
			|||
#include "storm/modelchecker/helper/utility/SetInformationFromOtherHelper.h"
 | 
				
			|||
 | 
				
			|||
#include "storm/storage/SparseMatrix.h"
 | 
				
			|||
 | 
				
			|||
#include "storm/utility/macros.h"
 | 
				
			|||
 | 
				
			|||
#include "storm/exceptions/NotSupportedException.h"
 | 
				
			|||
 | 
				
			|||
namespace storm { | 
				
			|||
    namespace modelchecker { | 
				
			|||
        namespace helper { | 
				
			|||
             | 
				
			|||
            template <typename ValueType, storm::dd::DdType DdType> | 
				
			|||
            HybridNondeterministicInfiniteHorizonHelper<ValueType, DdType>::HybridNondeterministicInfiniteHorizonHelper(storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix) : _model(model), _transitionMatrix(transitionMatrix), _markovianStates(nullptr), _exitRates(nullptr) { | 
				
			|||
                // Intentionally left empty.
 | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template <typename ValueType, storm::dd::DdType DdType> | 
				
			|||
            HybridNondeterministicInfiniteHorizonHelper<ValueType, DdType>::HybridNondeterministicInfiniteHorizonHelper(storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& markovianStates, storm::dd::Add<DdType, ValueType> const& exitRateVector) : _model(model), _transitionMatrix(transitionMatrix), _markovianStates(&markovianStates), _exitRates(&exitRateVector) { | 
				
			|||
                // Intentionally left empty.
 | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template <typename ValueType, storm::dd::DdType DdType> | 
				
			|||
            std::unique_ptr<HybridQuantitativeCheckResult<DdType, ValueType>> HybridNondeterministicInfiniteHorizonHelper<ValueType, DdType>::computeLongRunAverageProbabilities(Environment const& env, storm::dd::Bdd<DdType> const& psiStates) { | 
				
			|||
                // Convert this query to an instance for the sparse engine.
 | 
				
			|||
                // Create ODD for the translation.
 | 
				
			|||
                storm::dd::Odd odd = _model.getReachableStates().createOdd(); | 
				
			|||
                storm::storage::SparseMatrix<ValueType> explicitTransitionMatrix = _transitionMatrix.toMatrix(_model.getNondeterminismVariables(), odd, odd); | 
				
			|||
                std::unique_ptr<storm::modelchecker::helper::SparseNondeterministicInfiniteHorizonHelper<ValueType>> sparseHelper; | 
				
			|||
                std::vector<ValueType> explicitExitRateVector; | 
				
			|||
                storm::storage::BitVector explicitMarkovianStates; | 
				
			|||
                if (isContinuousTime()) { | 
				
			|||
                    explicitExitRateVector = _exitRates->toVector(odd); | 
				
			|||
                    explicitMarkovianStates = _markovianStates->toVector(odd); | 
				
			|||
                    sparseHelper = std::make_unique<storm::modelchecker::helper::SparseNondeterministicInfiniteHorizonHelper<ValueType>>(explicitTransitionMatrix, explicitMarkovianStates, explicitExitRateVector); | 
				
			|||
                } else { | 
				
			|||
                    sparseHelper = std::make_unique<storm::modelchecker::helper::SparseNondeterministicInfiniteHorizonHelper<ValueType>>(explicitTransitionMatrix); | 
				
			|||
                } | 
				
			|||
                storm::modelchecker::helper::setInformationFromOtherHelperNondeterministic(*sparseHelper, *this, [&odd](storm::dd::Bdd<DdType> const& s){ return s.toVector(odd); }); | 
				
			|||
                STORM_LOG_WARN_COND(!this->isProduceSchedulerSet(), "Scheduler extraction not supported in Hybrid engine."); | 
				
			|||
                auto explicitResult = sparseHelper->computeLongRunAverageProbabilities(env, psiStates.toVector(odd)); | 
				
			|||
                return std::make_unique<HybridQuantitativeCheckResult<DdType, ValueType>>(_model.getReachableStates(), _model.getManager().getBddZero(), _model.getManager().template getAddZero<ValueType>(), _model.getReachableStates(), std::move(odd), std::move(explicitResult)); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template <typename ValueType, storm::dd::DdType DdType> | 
				
			|||
            std::unique_ptr<HybridQuantitativeCheckResult<DdType, ValueType>> HybridNondeterministicInfiniteHorizonHelper<ValueType, DdType>::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::StandardRewardModel<DdType, ValueType> const& rewardModel) { | 
				
			|||
                // Convert this query to an instance for the sparse engine.
 | 
				
			|||
                // Create ODD for the translation.
 | 
				
			|||
                storm::dd::Odd odd = _model.getReachableStates().createOdd(); | 
				
			|||
                 | 
				
			|||
                // Create matrix and reward vectors
 | 
				
			|||
                storm::storage::SparseMatrix<ValueType> explicitTransitionMatrix; | 
				
			|||
                std::vector<ValueType> explicitStateRewards, explicitActionRewards; | 
				
			|||
                if (rewardModel.hasStateRewards()) { | 
				
			|||
                    explicitStateRewards = rewardModel.getStateRewardVector().toVector(odd); | 
				
			|||
                } | 
				
			|||
                if (rewardModel.hasStateActionRewards()) { | 
				
			|||
                    // Matrix and action-based vector have to be produced at the same time to guarantee the correct order
 | 
				
			|||
                    auto matrixRewards = _transitionMatrix.toMatrixVector(rewardModel.getStateActionRewardVector(), _model.getNondeterminismVariables(), odd, odd); | 
				
			|||
                    explicitTransitionMatrix = std::move(matrixRewards.first); | 
				
			|||
                    explicitActionRewards = std::move(matrixRewards.second); | 
				
			|||
                } else { | 
				
			|||
                    // Translate matrix only
 | 
				
			|||
                    explicitTransitionMatrix = _transitionMatrix.toMatrix(_model.getNondeterminismVariables(), odd, odd); | 
				
			|||
                } | 
				
			|||
                STORM_LOG_THROW(!rewardModel.hasTransitionRewards(), storm::exceptions::NotSupportedException, "Transition rewards are not supported in this engine."); | 
				
			|||
                 | 
				
			|||
                // Create remaining components and helper
 | 
				
			|||
                std::vector<ValueType> explicitExitRateVector; | 
				
			|||
                storm::storage::BitVector explicitMarkovianStates; | 
				
			|||
                std::unique_ptr<storm::modelchecker::helper::SparseNondeterministicInfiniteHorizonHelper<ValueType>> sparseHelper; | 
				
			|||
                if (isContinuousTime()) { | 
				
			|||
                    explicitExitRateVector = _exitRates->toVector(odd); | 
				
			|||
                    explicitMarkovianStates = _markovianStates->toVector(odd); | 
				
			|||
                    sparseHelper = std::make_unique<storm::modelchecker::helper::SparseNondeterministicInfiniteHorizonHelper<ValueType>>(explicitTransitionMatrix, explicitMarkovianStates, explicitExitRateVector); | 
				
			|||
                } else { | 
				
			|||
                    sparseHelper = std::make_unique<storm::modelchecker::helper::SparseNondeterministicInfiniteHorizonHelper<ValueType>>(explicitTransitionMatrix); | 
				
			|||
                } | 
				
			|||
                storm::modelchecker::helper::setInformationFromOtherHelperNondeterministic(*sparseHelper, *this, [&odd](storm::dd::Bdd<DdType> const& s){ return s.toVector(odd); }); | 
				
			|||
 | 
				
			|||
                STORM_LOG_WARN_COND(!this->isProduceSchedulerSet(), "Scheduler extraction not supported in Hybrid engine."); | 
				
			|||
                auto explicitResult = sparseHelper->computeLongRunAverageValues(env, rewardModel.hasStateRewards() ? &explicitStateRewards : nullptr, rewardModel.hasStateActionRewards() ? &explicitActionRewards : nullptr); | 
				
			|||
                return std::make_unique<HybridQuantitativeCheckResult<DdType, ValueType>>(_model.getReachableStates(), _model.getManager().getBddZero(), _model.getManager().template getAddZero<ValueType>(), _model.getReachableStates(), std::move(odd), std::move(explicitResult)); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template <typename ValueType, storm::dd::DdType DdType> | 
				
			|||
            bool HybridNondeterministicInfiniteHorizonHelper<ValueType, DdType>::isContinuousTime() const { | 
				
			|||
                STORM_LOG_ASSERT((_markovianStates == nullptr) == (_exitRates == nullptr), "Inconsistent information given: Have Markovian states but no exit rates (or vice versa)." ); | 
				
			|||
                return _markovianStates != nullptr; | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template class HybridNondeterministicInfiniteHorizonHelper<double, storm::dd::DdType::CUDD>; | 
				
			|||
            template class HybridNondeterministicInfiniteHorizonHelper<double, storm::dd::DdType::Sylvan>; | 
				
			|||
            template class HybridNondeterministicInfiniteHorizonHelper<storm::RationalNumber, storm::dd::DdType::Sylvan>; | 
				
			|||
             | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
@ -1,64 +0,0 @@ | 
				
			|||
#pragma once | 
				
			|||
#include "storm/modelchecker/helper/SingleValueModelCheckerHelper.h" | 
				
			|||
 | 
				
			|||
#include "storm/modelchecker/results/HybridQuantitativeCheckResult.h" | 
				
			|||
 | 
				
			|||
#include "storm/models/symbolic/NondeterministicModel.h" | 
				
			|||
#include "storm/models/symbolic/StandardRewardModel.h" | 
				
			|||
 | 
				
			|||
#include "storm/storage/dd/DdManager.h" | 
				
			|||
#include "storm/storage/dd/Add.h" | 
				
			|||
#include "storm/storage/dd/Bdd.h" | 
				
			|||
 | 
				
			|||
namespace storm { | 
				
			|||
    class Environment; | 
				
			|||
     | 
				
			|||
    namespace modelchecker { | 
				
			|||
        namespace helper { | 
				
			|||
         | 
				
			|||
            /*! | 
				
			|||
             * Helper class for model checking queries that depend on the long run behavior of the (nondeterministic) system. | 
				
			|||
             */ | 
				
			|||
            template <typename ValueType, storm::dd::DdType DdType> | 
				
			|||
            class HybridNondeterministicInfiniteHorizonHelper : public SingleValueModelCheckerHelper<ValueType, DdType> { | 
				
			|||
 | 
				
			|||
            public: | 
				
			|||
                /*! | 
				
			|||
                 * Initializes the helper for a discrete time (i.e. MDP) | 
				
			|||
                 */ | 
				
			|||
                HybridNondeterministicInfiniteHorizonHelper(storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix); | 
				
			|||
                 | 
				
			|||
                /*! | 
				
			|||
                 * Initializes the helper for a continuous time (i.e. MA) | 
				
			|||
                 */ | 
				
			|||
                HybridNondeterministicInfiniteHorizonHelper(storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& markovianStates, storm::dd::Add<DdType, ValueType> const& _exitRates); | 
				
			|||
                 | 
				
			|||
                /*! | 
				
			|||
                 * Computes the long run average probabilities, i.e., the fraction of the time we are in a psiState | 
				
			|||
                 * @return a value for each state | 
				
			|||
                 */ | 
				
			|||
                std::unique_ptr<HybridQuantitativeCheckResult<DdType, ValueType>> computeLongRunAverageProbabilities(Environment const& env, storm::dd::Bdd<DdType> const& psiStates); | 
				
			|||
                 | 
				
			|||
                /*! | 
				
			|||
                 * Computes the long run average rewards, i.e., the average reward collected per time unit | 
				
			|||
                 * @return a value for each state | 
				
			|||
                 */ | 
				
			|||
                std::unique_ptr<HybridQuantitativeCheckResult<DdType, ValueType>> computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::StandardRewardModel<DdType, ValueType> const& rewardModel); | 
				
			|||
                 | 
				
			|||
            protected: | 
				
			|||
                 | 
				
			|||
                /*! | 
				
			|||
                 * @return true iff this is a computation on a continuous time model (i.e. MA) | 
				
			|||
                 */ | 
				
			|||
                bool isContinuousTime() const; | 
				
			|||
 | 
				
			|||
 | 
				
			|||
            private: | 
				
			|||
                storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& _model; | 
				
			|||
                storm::dd::Add<DdType, ValueType> const& _transitionMatrix; | 
				
			|||
                storm::dd::Bdd<DdType> const* _markovianStates; | 
				
			|||
                storm::dd::Add<DdType, ValueType> const* _exitRates; | 
				
			|||
            }; | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue