2 changed files with 141 additions and 0 deletions
			
			
		@ -0,0 +1,100 @@ | 
			
		|||||
 | 
				#include "MemoryIncorporation.h"
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#include "storm/models/sparse/Mdp.h"
 | 
			
		||||
 | 
				#include "storm/models/sparse/MarkovAutomaton.h"
 | 
			
		||||
 | 
				#include "storm/models/sparse/StandardRewardModel.h"
 | 
			
		||||
 | 
				#include "storm/storage/memorystructure/MemoryStructureBuilder.h"
 | 
			
		||||
 | 
				#include "storm/storage/memorystructure/NondeterministicMemoryStructureBuilder.h"
 | 
			
		||||
 | 
				#include "storm/storage/memorystructure/SparseModelMemoryProduct.h"
 | 
			
		||||
 | 
				#include "storm/storage/memorystructure/SparseModelNondeterministicMemoryProduct.h"
 | 
			
		||||
 | 
				#include "storm/logic/Formulas.h"
 | 
			
		||||
 | 
				#include "storm/logic/FragmentSpecification.h"
 | 
			
		||||
 | 
				#include "storm/modelchecker/propositional/SparsePropositionalModelChecker.h"
 | 
			
		||||
 | 
				#include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h"
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#include "storm/utility/macros.h"
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#include "storm/exceptions/NotImplementedException.h"
 | 
			
		||||
 | 
				#include "storm/exceptions/NotSupportedException.h"
 | 
			
		||||
 | 
				namespace storm { | 
			
		||||
 | 
				    namespace transformer { | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				        template <class SparseModelType> | 
			
		||||
 | 
				        storm::storage::MemoryStructure getGoalMemory(SparseModelType const& model, storm::logic::Formula const& propositionalGoalStateFormula) { | 
			
		||||
 | 
				            STORM_LOG_THROW(propositionalGoalStateFormula.isInFragment(storm::logic::propositional()), storm::exceptions::NotSupportedException, "The  subformula " << propositionalGoalStateFormula << " should be propositional."); | 
			
		||||
 | 
				             | 
			
		||||
 | 
				            storm::modelchecker::SparsePropositionalModelChecker<SparseModelType> mc(model); | 
			
		||||
 | 
				            storm::storage::BitVector goalStates = mc.check(propositionalGoalStateFormula)->asExplicitQualitativeCheckResult().getTruthValuesVector(); | 
			
		||||
 | 
				         | 
			
		||||
 | 
				            // Check if the formula is already satisfied for all initial states. In such a case the trivial memory structure suffices.
 | 
			
		||||
 | 
				            if (model.getInitialStates().isSubsetOf(goalStates)) { | 
			
		||||
 | 
				                STORM_LOG_INFO("One objective is already satisfied for all initial states."); | 
			
		||||
 | 
				                return storm::storage::MemoryStructureBuilder<typename SparseModelType::ValueType, typename SparseModelType::RewardModelType>::buildTrivialMemoryStructure(model); | 
			
		||||
 | 
				            } | 
			
		||||
 | 
				             | 
			
		||||
 | 
				             | 
			
		||||
 | 
				            // Create a memory structure that stores whether a goal state has already been reached
 | 
			
		||||
 | 
				            storm::storage::MemoryStructureBuilder<typename SparseModelType::ValueType, typename SparseModelType::RewardModelType> builder(2, model); | 
			
		||||
 | 
				            builder.setTransition(0, 0, ~goalStates); | 
			
		||||
 | 
				            builder.setTransition(0, 1, goalStates); | 
			
		||||
 | 
				            builder.setTransition(1, 1, storm::storage::BitVector(model.getNumberOfStates(), true)); | 
			
		||||
 | 
				            for (auto const& initState : model.getInitialStates()) { | 
			
		||||
 | 
				                builder.setInitialMemoryState(initState, goalStates.get(initState) ? 1 : 0); | 
			
		||||
 | 
				            } | 
			
		||||
 | 
				            return builder.build(); | 
			
		||||
 | 
				        } | 
			
		||||
 | 
				         | 
			
		||||
 | 
				        template <class SparseModelType> | 
			
		||||
 | 
				        storm::storage::MemoryStructure getUntilFormulaMemory(SparseModelType const& model, storm::logic::Formula const& leftSubFormula, storm::logic::Formula const& rightSubFormula) { | 
			
		||||
 | 
				            auto notLeftOrRight = std::make_shared<storm::logic::BinaryBooleanStateFormula>(storm::logic::BinaryBooleanStateFormula::OperatorType::Or, | 
			
		||||
 | 
				                                        std::make_shared<storm::logic::UnaryBooleanStateFormula>(storm::logic::UnaryBooleanStateFormula::OperatorType::Not, leftSubFormula.asSharedPointer()), | 
			
		||||
 | 
				                                        rightSubFormula.asSharedPointer()); | 
			
		||||
 | 
				            return getGoalMemory<SparseModelType>(model, *notLeftOrRight); | 
			
		||||
 | 
				         | 
			
		||||
 | 
				        } | 
			
		||||
 | 
				         | 
			
		||||
 | 
				        template <class SparseModelType> | 
			
		||||
 | 
				        std::shared_ptr<SparseModelType> MemoryIncorporation<SparseModelType>::incorporateGoalMemory(SparseModelType const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) { | 
			
		||||
 | 
				            storm::storage::MemoryStructure memory = storm::storage::MemoryStructureBuilder<ValueType, RewardModelType>::buildTrivialMemoryStructure(model); | 
			
		||||
 | 
				             | 
			
		||||
 | 
				            for (auto const& subFormula : formulas) { | 
			
		||||
 | 
				                STORM_LOG_THROW(subFormula->isOperatorFormula(), storm::exceptions::NotSupportedException, "The given Formula " << *subFormula << " is not supported."); | 
			
		||||
 | 
				                auto const& subsubFormula = subFormula->asOperatorFormula().getSubformula(); | 
			
		||||
 | 
				                if (subsubFormula.isEventuallyFormula()) { | 
			
		||||
 | 
				                    memory = memory.product(getGoalMemory(model, subsubFormula.asEventuallyFormula().getSubformula())); | 
			
		||||
 | 
				                } else if (subsubFormula.isUntilFormula()) { | 
			
		||||
 | 
				                    memory = memory.product(getUntilFormulaMemory(model, subsubFormula.asUntilFormula().getLeftSubformula(), subsubFormula.asUntilFormula().getRightSubformula())); | 
			
		||||
 | 
				                } else if (subsubFormula.isBoundedUntilFormula()) { | 
			
		||||
 | 
				                    // For bounded formulas it is only reasonable to add the goal memory if it considers a single upper step/time bound.
 | 
			
		||||
 | 
				                    auto const& buf = subsubFormula.asBoundedUntilFormula(); | 
			
		||||
 | 
				                    if (!buf.isMultiDimensional() && !buf.getTimeBoundReference().isRewardBound() && (!buf.hasLowerBound() || (!buf.isLowerBoundStrict() && storm::utility::isZero(buf.template getLowerBound<storm::RationalNumber>())))) { | 
			
		||||
 | 
				                        memory = memory.product(getUntilFormulaMemory(model, buf.getLeftSubformula(), buf.getRightSubformula())); | 
			
		||||
 | 
				                    } | 
			
		||||
 | 
				                } else if (subsubFormula.isGloballyFormula()) { | 
			
		||||
 | 
				                    auto notPhi = std::make_shared<storm::logic::UnaryBooleanStateFormula>(storm::logic::UnaryBooleanStateFormula::OperatorType::Not, subsubFormula.asGloballyFormula().getSubformula().asSharedPointer()); | 
			
		||||
 | 
				                    memory = memory.product(getGoalMemory(model, *notPhi)); | 
			
		||||
 | 
				                } else { | 
			
		||||
 | 
				                    STORM_LOG_THROW(subsubFormula.isTotalRewardFormula() || subsubFormula.isCumulativeRewardFormula(), storm::exceptions::NotSupportedException, "The given Formula " << subsubFormula << " is not supported."); | 
			
		||||
 | 
				                } | 
			
		||||
 | 
				            } | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				            storm::storage::SparseModelMemoryProduct<ValueType> product = memory.product(model); | 
			
		||||
 | 
				            return std::dynamic_pointer_cast<SparseModelType>(product.build()); | 
			
		||||
 | 
				        } | 
			
		||||
 | 
				         | 
			
		||||
 | 
				        template <class SparseModelType> | 
			
		||||
 | 
				        std::shared_ptr<SparseModelType> MemoryIncorporation<SparseModelType>::incorporateFullMemory(SparseModelType const& model, uint64_t memoryStates) { | 
			
		||||
 | 
				            auto memory = storm::storage::NondeterministicMemoryStructureBuilder().build(storm::storage::NondeterministicMemoryStructurePattern::Full, memoryStates); | 
			
		||||
 | 
				            return storm::storage::SparseModelNondeterministicMemoryProduct<SparseModelType>(model, memory).build(); | 
			
		||||
 | 
				        } | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				        template class MemoryIncorporation<storm::models::sparse::Mdp<double>>; | 
			
		||||
 | 
				        template class MemoryIncorporation<storm::models::sparse::MarkovAutomaton<double>>; | 
			
		||||
 | 
				         | 
			
		||||
 | 
				        template class MemoryIncorporation<storm::models::sparse::Mdp<storm::RationalNumber>>; | 
			
		||||
 | 
				        template class MemoryIncorporation<storm::models::sparse::MarkovAutomaton<storm::RationalNumber>>; | 
			
		||||
 | 
				                 | 
			
		||||
 | 
				    } | 
			
		||||
 | 
				} | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				
 | 
			
		||||
@ -0,0 +1,41 @@ | 
			
		|||||
 | 
				#pragma once | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#include <memory> | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#include "storm/storage/memorystructure/MemoryStructure.h" | 
			
		||||
 | 
				#include "storm/logic/MultiObjectiveFormula.h" | 
			
		||||
 | 
				#include "storm/logic/Formula.h" | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				namespace storm { | 
			
		||||
 | 
				    namespace transformer { | 
			
		||||
 | 
				         | 
			
		||||
 | 
				        /*! | 
			
		||||
 | 
				         * Incorporates Memory into the state space of the given model, that is | 
			
		||||
 | 
				         * the resulting model is the crossproduct of of the given model plus | 
			
		||||
 | 
				         * some type of memory structure | 
			
		||||
 | 
				         */ | 
			
		||||
 | 
				        template <class SparseModelType> | 
			
		||||
 | 
				        class MemoryIncorporation { | 
			
		||||
 | 
				         | 
			
		||||
 | 
				        typedef typename SparseModelType::ValueType ValueType; | 
			
		||||
 | 
				        typedef typename SparseModelType::RewardModelType RewardModelType; | 
			
		||||
 | 
				         | 
			
		||||
 | 
				         | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				        public: | 
			
		||||
 | 
				             | 
			
		||||
 | 
				            /*! | 
			
		||||
 | 
				             * Incorporates memory that stores whether a 'goal' state has already been reached. | 
			
		||||
 | 
				             */ | 
			
		||||
 | 
				            static std::shared_ptr<SparseModelType> incorporateGoalMemory(SparseModelType const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas); | 
			
		||||
 | 
				             | 
			
		||||
 | 
				            /*! | 
			
		||||
 | 
				             * Incorporates a memory structure where the nondeterminism of the model decides which successor state to choose. | 
			
		||||
 | 
				             */ | 
			
		||||
 | 
				            static std::shared_ptr<SparseModelType> incorporateFullMemory(SparseModelType const& model, uint64_t memoryStates); | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				        }; | 
			
		||||
 | 
				    } | 
			
		||||
 | 
				} | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				
 | 
			
		||||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue