5 changed files with 205 additions and 181 deletions
			
			
		- 
					13src/storm/transformer/ChoiceSelector.cpp
 - 
					127src/storm/transformer/SubsystemBuilder.cpp
 - 
					189src/storm/transformer/SubsystemBuilder.h
 - 
					54src/storm/utility/graph.cpp
 - 
					3src/storm/utility/graph.h
 
@ -0,0 +1,127 @@ | 
			
		|||||
 | 
				#include "storm/transformer/SubsystemBuilder.h"
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#include <boost/optional.hpp>
 | 
			
		||||
 | 
				#include <storm/exceptions/UnexpectedException.h>
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#include "storm/models/sparse/StandardRewardModel.h"
 | 
			
		||||
 | 
				#include "storm/utility/constants.h"
 | 
			
		||||
 | 
				#include "storm/utility/graph.h"
 | 
			
		||||
 | 
				#include "storm/utility/macros.h"
 | 
			
		||||
 | 
				#include "storm/utility/vector.h"
 | 
			
		||||
 | 
				#include "storm/models/sparse/Dtmc.h"
 | 
			
		||||
 | 
				#include "storm/models/sparse/Mdp.h"
 | 
			
		||||
 | 
				#include "storm/models/sparse/Ctmc.h"
 | 
			
		||||
 | 
				#include "storm/models/sparse/MarkovAutomaton.h"
 | 
			
		||||
 | 
				#include "storm/storage/sparse/ModelComponents.h"
 | 
			
		||||
 | 
				#include "storm/utility/builder.h"
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#include "storm/exceptions/InvalidArgumentException.h"
 | 
			
		||||
 | 
				#include "storm/exceptions/UnexpectedException.h"
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				namespace storm { | 
			
		||||
 | 
				    namespace transformer { | 
			
		||||
 | 
				         | 
			
		||||
 | 
				        template <typename ValueType, typename RewardModelType> | 
			
		||||
 | 
				        void transformModelSpecificComponents(storm::models::sparse::Model<ValueType, RewardModelType> const& originalModel, | 
			
		||||
 | 
				                               storm::storage::BitVector const& subsystem, | 
			
		||||
 | 
				                               storm::storage::sparse::ModelComponents<ValueType, RewardModelType>& components) { | 
			
		||||
 | 
				            if (originalModel.isOfType(storm::models::ModelType::MarkovAutomaton)) { | 
			
		||||
 | 
				                auto const& ma = *originalModel.template as<storm::models::sparse::MarkovAutomaton<ValueType, RewardModelType>>(); | 
			
		||||
 | 
				                components.markovianStates = ma.getMarkovianStates() % subsystem; | 
			
		||||
 | 
				                components.exitRates = storm::utility::vector::filterVector(ma.getExitRates(), subsystem); | 
			
		||||
 | 
				                components.rateTransitions = false; // Note that originalModel.getTransitionMatrix() contains probabilities
 | 
			
		||||
 | 
				            } else if (originalModel.isOfType(storm::models::ModelType::Ctmc)) { | 
			
		||||
 | 
				                auto const& ctmc = *originalModel.template as<storm::models::sparse::Ctmc<ValueType, RewardModelType>>(); | 
			
		||||
 | 
				                components.exitRates = storm::utility::vector::filterVector(ctmc.getExitRateVector(), subsystem); | 
			
		||||
 | 
				                components.rateTransitions = true; | 
			
		||||
 | 
				            } else { | 
			
		||||
 | 
				                STORM_LOG_THROW(originalModel.isOfType(storm::models::ModelType::Dtmc) || originalModel.isOfType(storm::models::ModelType::Mdp), storm::exceptions::UnexpectedException, "Unexpected model type."); | 
			
		||||
 | 
				            } | 
			
		||||
 | 
				        } | 
			
		||||
 | 
				         | 
			
		||||
 | 
				        template<typename RewardModelType> | 
			
		||||
 | 
				        RewardModelType transformRewardModel(RewardModelType const& originalRewardModel, storm::storage::BitVector const& subsystem, storm::storage::BitVector const& subsystemActions) { | 
			
		||||
 | 
				            boost::optional<std::vector<typename RewardModelType::ValueType>> stateRewardVector; | 
			
		||||
 | 
				            boost::optional<std::vector<typename RewardModelType::ValueType>> stateActionRewardVector; | 
			
		||||
 | 
				            boost::optional<storm::storage::SparseMatrix<typename RewardModelType::ValueType>> transitionRewardMatrix; | 
			
		||||
 | 
				            if (originalRewardModel.hasStateRewards()){ | 
			
		||||
 | 
				                stateRewardVector = storm::utility::vector::filterVector(originalRewardModel.getStateRewardVector(), subsystem); | 
			
		||||
 | 
				            } | 
			
		||||
 | 
				            if (originalRewardModel.hasStateActionRewards()){ | 
			
		||||
 | 
				                stateActionRewardVector = storm::utility::vector::filterVector(originalRewardModel.getStateActionRewardVector(), subsystemActions); | 
			
		||||
 | 
				            } | 
			
		||||
 | 
				            if (originalRewardModel.hasTransitionRewards()){ | 
			
		||||
 | 
				                transitionRewardMatrix = originalRewardModel.getTransitionRewardMatrix().getSubmatrix(false, subsystemActions, subsystem); | 
			
		||||
 | 
				            } | 
			
		||||
 | 
				            return RewardModelType(std::move(stateRewardVector), std::move(stateActionRewardVector), std::move(transitionRewardMatrix)); | 
			
		||||
 | 
				        } | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				        template <typename ValueType, typename RewardModelType> | 
			
		||||
 | 
				        SubsystemBuilderReturnType<ValueType, RewardModelType> internalBuildSubsystem(storm::models::sparse::Model<ValueType, RewardModelType> const& originalModel, storm::storage::BitVector const& subsystemStates, storm::storage::BitVector const& subsystemActions) { | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				            SubsystemBuilderReturnType<ValueType, RewardModelType> result; | 
			
		||||
 | 
				            uint_fast64_t subsystemStateCount = subsystemStates.getNumberOfSetBits(); | 
			
		||||
 | 
				            result.newToOldStateIndexMapping.reserve(subsystemStateCount); | 
			
		||||
 | 
				            result.keptActions = storm::storage::BitVector(originalModel.getTransitionMatrix().getRowCount(), false); | 
			
		||||
 | 
				            for (auto subsysState : subsystemStates) { | 
			
		||||
 | 
				                result.newToOldStateIndexMapping.push_back(subsysState); | 
			
		||||
 | 
				                bool stateHasOneChoiceLeft = false; | 
			
		||||
 | 
				                for (uint_fast64_t row = subsystemActions.getNextSetIndex(originalModel.getTransitionMatrix().getRowGroupIndices()[subsysState]); row < originalModel.getTransitionMatrix().getRowGroupIndices()[subsysState+1]; row = subsystemActions.getNextSetIndex(row+1)) { | 
			
		||||
 | 
				                    bool allRowEntriesStayInSubsys = true; | 
			
		||||
 | 
				                    for (auto const& entry : originalModel.getTransitionMatrix().getRow(row)) { | 
			
		||||
 | 
				                        if (!subsystemStates.get(entry.getColumn())) { | 
			
		||||
 | 
				                            allRowEntriesStayInSubsys = false; | 
			
		||||
 | 
				                            break; | 
			
		||||
 | 
				                        } | 
			
		||||
 | 
				                    } | 
			
		||||
 | 
				                    stateHasOneChoiceLeft |= allRowEntriesStayInSubsys; | 
			
		||||
 | 
				                    result.keptActions.set(row, allRowEntriesStayInSubsys); | 
			
		||||
 | 
				                } | 
			
		||||
 | 
				                 STORM_LOG_THROW(stateHasOneChoiceLeft, storm::exceptions::InvalidArgumentException, "The subsystem would contain a deadlock state."); | 
			
		||||
 | 
				            } | 
			
		||||
 | 
				             | 
			
		||||
 | 
				            // Transform the components of the model
 | 
			
		||||
 | 
				            storm::storage::sparse::ModelComponents<ValueType, RewardModelType> components; | 
			
		||||
 | 
				            components.transitionMatrix = originalModel.getTransitionMatrix().getSubmatrix(false, result.keptActions, subsystemStates); | 
			
		||||
 | 
				            components.stateLabeling = originalModel.getStateLabeling().getSubLabeling(subsystemStates); | 
			
		||||
 | 
				            for (auto const& rewardModel : originalModel.getRewardModels()){ | 
			
		||||
 | 
				                components.rewardModels.insert(std::make_pair(rewardModel.first, transformRewardModel(rewardModel.second, subsystemStates, result.keptActions))); | 
			
		||||
 | 
				            } | 
			
		||||
 | 
				            if (originalModel.hasChoiceLabeling()) { | 
			
		||||
 | 
				                components.choiceLabeling = originalModel.getChoiceLabeling().getSubLabeling(result.keptActions); | 
			
		||||
 | 
				            } | 
			
		||||
 | 
				            if (originalModel.hasStateValuations()) { | 
			
		||||
 | 
				                components.stateValuations = originalModel.getStateValuations().selectStates(subsystemStates); | 
			
		||||
 | 
				            } | 
			
		||||
 | 
				            if (originalModel.hasChoiceOrigins()) { | 
			
		||||
 | 
				                components.choiceOrigins = originalModel.getChoiceOrigins()->selectChoices(result.keptActions); | 
			
		||||
 | 
				            } | 
			
		||||
 | 
				             | 
			
		||||
 | 
				            transformModelSpecificComponents<ValueType, RewardModelType>(originalModel, subsystemStates, components); | 
			
		||||
 | 
				             | 
			
		||||
 | 
				            result.model = storm::utility::builder::buildModelFromComponents(originalModel.getType(), std::move(components)); | 
			
		||||
 | 
				            STORM_LOG_DEBUG("Subsystem Builder is done. Resulting model has " << result.model->getNumberOfStates() << " states."); | 
			
		||||
 | 
				            return result; | 
			
		||||
 | 
				        } | 
			
		||||
 | 
				         | 
			
		||||
 | 
				        template <typename ValueType, typename RewardModelType> | 
			
		||||
 | 
				        SubsystemBuilderReturnType<ValueType, RewardModelType> buildSubsystem(storm::models::sparse::Model<ValueType, RewardModelType> const& originalModel, storm::storage::BitVector const& subsystemStates, storm::storage::BitVector const& subsystemActions, bool keepUnreachableStates) { | 
			
		||||
 | 
				            STORM_LOG_DEBUG("Invoked subsystem builder on model with " << originalModel.getNumberOfStates() << " states."); | 
			
		||||
 | 
				            storm::storage::BitVector initialStates = originalModel.getInitialStates() & subsystemStates; | 
			
		||||
 | 
				            STORM_LOG_THROW(!initialStates.empty(), storm::exceptions::InvalidArgumentException, "The subsystem would not contain any initial states"); | 
			
		||||
 | 
				             | 
			
		||||
 | 
				            STORM_LOG_THROW(!subsystemStates.empty(), storm::exceptions::InvalidArgumentException, "Invoked SubsystemBuilder for an empty subsystem."); | 
			
		||||
 | 
				            if (keepUnreachableStates) { | 
			
		||||
 | 
				                return internalBuildSubsystem(originalModel, subsystemStates, subsystemActions); | 
			
		||||
 | 
				            } else { | 
			
		||||
 | 
				                auto actualSubsystem = storm::utility::graph::getReachableStates(originalModel.getTransitionMatrix(), initialStates, subsystemStates, storm::storage::BitVector(subsystemStates.size(), false), false, 0, subsystemActions); | 
			
		||||
 | 
				                return internalBuildSubsystem(originalModel, actualSubsystem, subsystemActions); | 
			
		||||
 | 
				            } | 
			
		||||
 | 
				        } | 
			
		||||
 | 
				         | 
			
		||||
 | 
				        template SubsystemBuilderReturnType<double> buildSubsystem(storm::models::sparse::Model<double> const& originalModel, storm::storage::BitVector const& subsystemStates, storm::storage::BitVector const& subsystemActions, bool keepUnreachableStates = true); | 
			
		||||
 | 
				        template SubsystemBuilderReturnType<double, storm::models::sparse::StandardRewardModel<storm::Interval>> buildSubsystem(storm::models::sparse::Model<double, storm::models::sparse::StandardRewardModel<storm::Interval>> const& originalModel, storm::storage::BitVector const& subsystemStates, storm::storage::BitVector const& subsystemActions, bool keepUnreachableStates = true); | 
			
		||||
 | 
				        template SubsystemBuilderReturnType<storm::RationalNumber> buildSubsystem(storm::models::sparse::Model<storm::RationalNumber> const& originalModel, storm::storage::BitVector const& subsystemStates, storm::storage::BitVector const& subsystemActions, bool keepUnreachableStates = true); | 
			
		||||
 | 
				        template SubsystemBuilderReturnType<storm::RationalFunction> buildSubsystem(storm::models::sparse::Model<storm::RationalFunction> const& originalModel, storm::storage::BitVector const& subsystemStates, storm::storage::BitVector const& subsystemActions, bool keepUnreachableStates = true); | 
			
		||||
 | 
				    } | 
			
		||||
 | 
				} | 
			
		||||
@ -1,170 +1,43 @@ | 
			
		|||||
#ifndef STORM_TRANSFORMER_SUBSYSTEMBUILDER_H | 
				 | 
			
		||||
#define STORM_TRANSFORMER_SUBSYSTEMBUILDER_H | 
				 | 
			
		||||
 | 
				 | 
			
		||||
 | 
				#pragma once | 
			
		||||
 | 
				
 | 
			
		||||
#include <memory> | 
				#include <memory> | 
			
		||||
#include <boost/optional.hpp> | 
				 | 
			
		||||
 | 
				#include <vector> | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#include "storm/storage/BitVector.h" | 
			
		||||
 | 
				#include "storm/models/sparse/Model.h" | 
			
		||||
#include "storm/models/sparse/StandardRewardModel.h" | 
				#include "storm/models/sparse/StandardRewardModel.h" | 
			
		||||
#include "storm/utility/constants.h" | 
				 | 
			
		||||
#include "storm/utility/graph.h" | 
				 | 
			
		||||
#include "storm/utility/macros.h" | 
				 | 
			
		||||
#include "storm/utility/vector.h" | 
				 | 
			
		||||
#include "storm/models/sparse/Dtmc.h" | 
				 | 
			
		||||
#include "storm/models/sparse/Mdp.h" | 
				 | 
			
		||||
#include "storm/models/sparse/Ctmc.h" | 
				 | 
			
		||||
#include "storm/models/sparse/MarkovAutomaton.h" | 
				 | 
			
		||||
#include "storm/storage/sparse/ModelComponents.h" | 
				 | 
			
		||||
#include "storm/utility/builder.h" | 
				 | 
			
		||||
 | 
				 | 
			
		||||
#include "storm/exceptions/InvalidArgumentException.h" | 
				 | 
			
		||||
#include "storm/exceptions/InvalidStateException.h" | 
				 | 
			
		||||
 | 
				
 | 
			
		||||
namespace storm { | 
				namespace storm { | 
			
		||||
    namespace transformer { | 
				    namespace transformer { | 
			
		||||
         | 
				         | 
			
		||||
 | 
				        template <typename ValueType, typename RewardModelType = storm::models::sparse::StandardRewardModel<ValueType>> | 
			
		||||
 | 
				        struct SubsystemBuilderReturnType { | 
			
		||||
 | 
				            // The resulting model | 
			
		||||
 | 
				            std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>> model; | 
			
		||||
 | 
				            // Gives for each state in the resulting model the corresponding state in the original model. | 
			
		||||
 | 
				            std::vector<uint_fast64_t> newToOldStateIndexMapping; | 
			
		||||
 | 
				            // marks the actions of the original model that are still available in the subsystem | 
			
		||||
 | 
				            storm::storage::BitVector keptActions; | 
			
		||||
 | 
				        }; | 
			
		||||
 | 
				         | 
			
		||||
        /* | 
				        /* | 
			
		||||
         * Removes all states that are not part of the subsystem | 
				 | 
			
		||||
 | 
				         * Removes all states and actions that are not part of the subsystem. | 
			
		||||
 | 
				         * A state is part of the subsystem iff | 
			
		||||
 | 
				         *    * it is selected in subsystemStates AND | 
			
		||||
 | 
				         *    * keepUnreachableStates is true or the state is reachable from the initial states | 
			
		||||
 | 
				         * An action is part of the subsystem iff | 
			
		||||
 | 
				         *    * it is selected in subsystemActions AND | 
			
		||||
 | 
				         *    * it originates from a state that is part of the subsystem AND | 
			
		||||
 | 
				         *    * it does not contain a transition leading to a state outside of the subsystem. | 
			
		||||
 | 
				         * | 
			
		||||
 | 
				         * If this introduces a deadlock state (i.e., a state without an action) an exception is thrown. | 
			
		||||
 | 
				         * | 
			
		||||
 | 
				         * @param originalModel The original model. | 
			
		||||
 | 
				         * @param subsystemStates The selected states. | 
			
		||||
 | 
				         * @param subsystemActions The selected actions | 
			
		||||
 | 
				         * @param keepUnreachableStates if true, states that are not reachable from the initial state are kept | 
			
		||||
         */ | 
				         */ | 
			
		||||
        template <typename SparseModelType> | 
				 | 
			
		||||
        class SubsystemBuilder { | 
				 | 
			
		||||
        public: | 
				 | 
			
		||||
 | 
				 | 
			
		||||
            struct SubsystemBuilderReturnType { | 
				 | 
			
		||||
                // The resulting model | 
				 | 
			
		||||
                std::shared_ptr<SparseModelType> model; | 
				 | 
			
		||||
                // Gives for each state in the resulting model the corresponding state in the original model. | 
				 | 
			
		||||
                std::vector<uint_fast64_t> newToOldStateIndexMapping; | 
				 | 
			
		||||
                // marks the actions of the original model that are still available in the subsystem | 
				 | 
			
		||||
                storm::storage::BitVector keptActions; | 
				 | 
			
		||||
            }; | 
				 | 
			
		||||
             | 
				 | 
			
		||||
            /* | 
				 | 
			
		||||
             * Removes all states and actions that are not part of the subsystem. | 
				 | 
			
		||||
             * A state is part of the subsystem iff it is selected in subsystemStates. | 
				 | 
			
		||||
             * An action is part of the subsystem iff  | 
				 | 
			
		||||
             *    * it is selected in subsystemActions AND | 
				 | 
			
		||||
             *    * it originates from a state that is part of the subsystem AND | 
				 | 
			
		||||
             *    * it does not contain a transition leading to a state outside of the subsystem. | 
				 | 
			
		||||
             * | 
				 | 
			
		||||
             * If this introduces a deadlock state (i.e., a state without an action) an exception is thrown. | 
				 | 
			
		||||
             *  | 
				 | 
			
		||||
             * @param originalModel The original model. | 
				 | 
			
		||||
             * @param subsystemStates The selected states. | 
				 | 
			
		||||
             * @param subsystemActions The selected actions | 
				 | 
			
		||||
             */ | 
				 | 
			
		||||
            static SubsystemBuilderReturnType transform(SparseModelType const& originalModel, storm::storage::BitVector const& subsystemStates, storm::storage::BitVector const& subsystemActions) { | 
				 | 
			
		||||
                STORM_LOG_DEBUG("Invoked subsystem builder on model with " << originalModel.getNumberOfStates() << " states."); | 
				 | 
			
		||||
                STORM_LOG_THROW(!(originalModel.getInitialStates() & subsystemStates).empty(), storm::exceptions::InvalidArgumentException, "The subsystem would not contain any initial states"); | 
				 | 
			
		||||
                SubsystemBuilderReturnType result; | 
				 | 
			
		||||
                 | 
				 | 
			
		||||
                uint_fast64_t subsystemStateCount = subsystemStates.getNumberOfSetBits(); | 
				 | 
			
		||||
                STORM_LOG_THROW(subsystemStateCount != 0, storm::exceptions::InvalidArgumentException, "Invoked SubsystemBuilder for an empty subsystem."); | 
				 | 
			
		||||
                if (subsystemStateCount == subsystemStates.size() && subsystemActions.full()) { | 
				 | 
			
		||||
                    result.model = std::make_shared<SparseModelType>(originalModel); | 
				 | 
			
		||||
                    result.newToOldStateIndexMapping = storm::utility::vector::buildVectorForRange(0, result.model->getNumberOfStates()); | 
				 | 
			
		||||
                    result.keptActions = storm::storage::BitVector(result.model->getTransitionMatrix().getRowCount(), true); | 
				 | 
			
		||||
                    return result; | 
				 | 
			
		||||
                } | 
				 | 
			
		||||
                 | 
				 | 
			
		||||
                result.newToOldStateIndexMapping.reserve(subsystemStateCount); | 
				 | 
			
		||||
                result.keptActions = storm::storage::BitVector(originalModel.getTransitionMatrix().getRowCount(), false); | 
				 | 
			
		||||
                for (auto subsysState : subsystemStates) { | 
				 | 
			
		||||
                    result.newToOldStateIndexMapping.push_back(subsysState); | 
				 | 
			
		||||
                    bool stateHasOneChoiceLeft = false; | 
				 | 
			
		||||
                    for (uint_fast64_t row = subsystemActions.getNextSetIndex(originalModel.getTransitionMatrix().getRowGroupIndices()[subsysState]); row < originalModel.getTransitionMatrix().getRowGroupIndices()[subsysState+1]; row = subsystemActions.getNextSetIndex(row+1)) { | 
				 | 
			
		||||
                        bool allRowEntriesStayInSubsys = true; | 
				 | 
			
		||||
                        for (auto const& entry : originalModel.getTransitionMatrix().getRow(row)) { | 
				 | 
			
		||||
                            if (!subsystemStates.get(entry.getColumn())) { | 
				 | 
			
		||||
                                allRowEntriesStayInSubsys = false; | 
				 | 
			
		||||
                                break; | 
				 | 
			
		||||
                            } | 
				 | 
			
		||||
                        } | 
				 | 
			
		||||
                        stateHasOneChoiceLeft |= allRowEntriesStayInSubsys; | 
				 | 
			
		||||
                        result.keptActions.set(row, allRowEntriesStayInSubsys); | 
				 | 
			
		||||
                    } | 
				 | 
			
		||||
                     STORM_LOG_THROW(stateHasOneChoiceLeft, storm::exceptions::InvalidArgumentException, "The subsystem would contain a deadlock state."); | 
				 | 
			
		||||
                } | 
				 | 
			
		||||
                 | 
				 | 
			
		||||
                // Transform the components of the model | 
				 | 
			
		||||
                storm::storage::sparse::ModelComponents<typename SparseModelType::ValueType, typename SparseModelType::RewardModelType> components; | 
				 | 
			
		||||
                components.transitionMatrix = originalModel.getTransitionMatrix().getSubmatrix(false, result.keptActions, subsystemStates); | 
				 | 
			
		||||
                components.stateLabeling = originalModel.getStateLabeling().getSubLabeling(subsystemStates); | 
				 | 
			
		||||
                for (auto const& rewardModel : originalModel.getRewardModels()){ | 
				 | 
			
		||||
                    components.rewardModels.insert(std::make_pair(rewardModel.first, transformRewardModel(rewardModel.second, subsystemStates, result.keptActions))); | 
				 | 
			
		||||
                } | 
				 | 
			
		||||
                if (originalModel.hasChoiceLabeling()) { | 
				 | 
			
		||||
                    components.choiceLabeling = originalModel.getChoiceLabeling().getSubLabeling(result.keptActions); | 
				 | 
			
		||||
                } | 
				 | 
			
		||||
                if (originalModel.hasStateValuations()) { | 
				 | 
			
		||||
                    components.stateValuations = originalModel.getStateValuations().selectStates(subsystemStateCount); | 
				 | 
			
		||||
                } | 
				 | 
			
		||||
                if (originalModel.hasChoiceOrigins()) { | 
				 | 
			
		||||
                    components.choiceOrigins = originalModel.getChoiceOrigins().selectChoices(result.keptActions); | 
				 | 
			
		||||
                } | 
				 | 
			
		||||
                 | 
				 | 
			
		||||
                transformModelSpecificComponents(originalModel, subsystemStates, components); | 
				 | 
			
		||||
                 | 
				 | 
			
		||||
                result.model = storm::utility::builder::buildModelFromComponents(originalModel.getType(), std::move(components)); | 
				 | 
			
		||||
                STORM_LOG_DEBUG("Subsystem Builder is done. Resulting model has " << result.model->getNumberOfStates() << " states."); | 
				 | 
			
		||||
                return result; | 
				 | 
			
		||||
            } | 
				 | 
			
		||||
             | 
				 | 
			
		||||
        private: | 
				 | 
			
		||||
            template<typename ValueType = typename SparseModelType::RewardModelType::ValueType, typename RewardModelType = typename SparseModelType::RewardModelType> | 
				 | 
			
		||||
            static RewardModelType transformRewardModel(RewardModelType const& originalRewardModel, storm::storage::BitVector const& subsystem, storm::storage::BitVector const& subsystemActions) { | 
				 | 
			
		||||
                boost::optional<std::vector<ValueType>> stateRewardVector; | 
				 | 
			
		||||
                boost::optional<std::vector<ValueType>> stateActionRewardVector; | 
				 | 
			
		||||
                boost::optional<storm::storage::SparseMatrix<ValueType>> transitionRewardMatrix; | 
				 | 
			
		||||
                if (originalRewardModel.hasStateRewards()){ | 
				 | 
			
		||||
                    stateRewardVector = storm::utility::vector::filterVector(originalRewardModel.getStateRewardVector(), subsystem); | 
				 | 
			
		||||
                } | 
				 | 
			
		||||
                if (originalRewardModel.hasStateActionRewards()){ | 
				 | 
			
		||||
                    stateActionRewardVector = storm::utility::vector::filterVector(originalRewardModel.getStateActionRewardVector(), subsystemActions); | 
				 | 
			
		||||
                } | 
				 | 
			
		||||
                if (originalRewardModel.hasTransitionRewards()){ | 
				 | 
			
		||||
                    transitionRewardMatrix = originalRewardModel.getTransitionRewardMatrix().getSubmatrix(false, subsystemActions, subsystem); | 
				 | 
			
		||||
                } | 
				 | 
			
		||||
                return RewardModelType(std::move(stateRewardVector), std::move(stateActionRewardVector), std::move(transitionRewardMatrix)); | 
				 | 
			
		||||
            } | 
				 | 
			
		||||
             | 
				 | 
			
		||||
            template<typename MT = SparseModelType> | 
				 | 
			
		||||
            static typename std::enable_if< | 
				 | 
			
		||||
            std::is_same<MT,storm::models::sparse::Dtmc<typename SparseModelType::ValueType>>::value || | 
				 | 
			
		||||
            std::is_same<MT,storm::models::sparse::Mdp<typename SparseModelType::ValueType>>::value, | 
				 | 
			
		||||
            MT>::type | 
				 | 
			
		||||
            transformModelSpecificComponents(MT const&, | 
				 | 
			
		||||
                                   storm::storage::BitVector const& /*subsystem*/, | 
				 | 
			
		||||
                                   storm::storage::sparse::ModelComponents<typename SparseModelType::ValueType, typename SparseModelType::RewardModelType>&) { | 
				 | 
			
		||||
                // Intentionally left empty | 
				 | 
			
		||||
            } | 
				 | 
			
		||||
             | 
				 | 
			
		||||
            template<typename MT = SparseModelType> | 
				 | 
			
		||||
            static typename std::enable_if< | 
				 | 
			
		||||
            std::is_same<MT,storm::models::sparse::Ctmc<typename SparseModelType::ValueType>>::value, | 
				 | 
			
		||||
            MT>::type | 
				 | 
			
		||||
            transformModelSpecificComponents(MT const& originalModel, | 
				 | 
			
		||||
                                   storm::storage::BitVector const& subsystem, | 
				 | 
			
		||||
                                   storm::storage::SparseMatrix<typename MT::ValueType>& matrix, | 
				 | 
			
		||||
                                   storm::storage::sparse::ModelComponents<typename SparseModelType::ValueType, typename SparseModelType::RewardModelType>& components) { | 
				 | 
			
		||||
                components.exitRates = storm::utility::vector::filterVector(originalModel.getExitRateVector(), subsystem); | 
				 | 
			
		||||
                components.rateTransitions = true; | 
				 | 
			
		||||
            } | 
				 | 
			
		||||
         | 
				 | 
			
		||||
            template<typename MT = SparseModelType> | 
				 | 
			
		||||
            static typename std::enable_if< | 
				 | 
			
		||||
            std::is_same<MT,storm::models::sparse::MarkovAutomaton<typename SparseModelType::ValueType>>::value, | 
				 | 
			
		||||
            MT>::type | 
				 | 
			
		||||
            transformModelSpecificComponents(MT const& originalModel, | 
				 | 
			
		||||
                                   storm::storage::BitVector const& subsystem, | 
				 | 
			
		||||
                                   storm::storage::SparseMatrix<typename MT::ValueType>& matrix, | 
				 | 
			
		||||
                                   storm::storage::sparse::ModelComponents<typename SparseModelType::ValueType, typename SparseModelType::RewardModelType>& components) { | 
				 | 
			
		||||
                components.markovianStates = originalModel.getMarkovianStates() % subsystem; | 
				 | 
			
		||||
                components.exitRates = storm::utility::vector::filterVector(originalModel.getExitRates(), subsystem); | 
				 | 
			
		||||
                components.rateTransitions = false; // Note that originalModel.getTransitionMatrix() contains probabilities | 
				 | 
			
		||||
            } | 
				 | 
			
		||||
             | 
				 | 
			
		||||
        }; | 
				 | 
			
		||||
 | 
				        template <typename ValueType, typename RewardModelType = storm::models::sparse::StandardRewardModel<ValueType>> | 
			
		||||
 | 
				        SubsystemBuilderReturnType<ValueType, RewardModelType> buildSubsystem(storm::models::sparse::Model<ValueType, RewardModelType> const& originalModel, storm::storage::BitVector const& subsystemStates, storm::storage::BitVector const& subsystemActions, bool keepUnreachableStates = true); | 
			
		||||
    } | 
				    } | 
			
		||||
} | 
				} | 
			
		||||
#endif // STORM_TRANSFORMER_SUBSYSTEMBUILDER_H | 
				 | 
			
		||||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue