13 changed files with 928 additions and 17 deletions
			
			
		- 
					5src/models/sparse/MarkovAutomaton.cpp
- 
					7src/models/sparse/MarkovAutomaton.h
- 
					29src/models/sparse/Model.h
- 
					2src/models/sparse/StochasticTwoPlayerGame.cpp
- 
					161src/utility/ModelInstantiator.cpp
- 
					158src/utility/ModelInstantiator.h
- 
					19src/utility/constants.cpp
- 
					3src/utility/constants.h
- 
					39src/utility/parametric.cpp
- 
					54src/utility/parametric.h
- 
					266test/functional/utility/ModelInstantiatorTest.cpp
- 
					146test/functional/utility/brp16_2.pm
- 
					56test/functional/utility/coin2_2.pm
| @ -0,0 +1,161 @@ | |||
| /* 
 | |||
|  * File:   ModelInstantiator.cpp | |||
|  * Author: Tim Quatmann | |||
|  *  | |||
|  * Created on February 23, 2016 | |||
|  */ | |||
| 
 | |||
| #include "src/utility/ModelInstantiator.h"
 | |||
| #include "src/models/sparse/StandardRewardModel.h"
 | |||
| 
 | |||
| namespace storm { | |||
|     namespace utility { | |||
|          | |||
|             template<typename ParametricSparseModelType, typename ConstantSparseModelType> | |||
|             ModelInstantiator<ParametricSparseModelType, ConstantSparseModelType>::ModelInstantiator(ParametricSparseModelType const& parametricModel){ | |||
|                 //Now pre-compute the information for the equation system.
 | |||
|                 initializeModelSpecificData(parametricModel); | |||
|                 initializeMatrixMapping(this->instantiatedModel->getTransitionMatrix(), this->functions, this->matrixMapping, parametricModel.getTransitionMatrix()); | |||
|                  | |||
|                 for(auto& rewModel : this->instantiatedModel->getRewardModels()) { | |||
|                     if(rewModel.second.hasStateRewards()){ | |||
|                         initializeVectorMapping(rewModel.second.getStateRewardVector(), this->functions, this->vectorMapping, parametricModel.getRewardModel(rewModel.first).getStateRewardVector()); | |||
|                     } | |||
|                     if(rewModel.second.hasStateActionRewards()){ | |||
|                         initializeVectorMapping(rewModel.second.getStateActionRewardVector(), this->functions, this->vectorMapping, parametricModel.getRewardModel(rewModel.first).getStateActionRewardVector()); | |||
|                     } | |||
|                     if(rewModel.second.hasTransitionRewards()){ | |||
|                         initializeMatrixMapping(rewModel.second.getTransitionRewardMatrix(), this->functions, this->matrixMapping, parametricModel.getRewardModel(rewModel.first).getTransitionRewardMatrix()); | |||
|                     } | |||
|                 } | |||
|             } | |||
|              | |||
|             template<typename ParametricSparseModelType, typename ConstantType> | |||
|             ModelInstantiator<ParametricSparseModelType, ConstantType>::~ModelInstantiator() { | |||
|                 //Intentionally left empty
 | |||
|             } | |||
|              | |||
|             template<typename ParametricSparseModelType, typename ConstantSparseModelType> | |||
|             storm::storage::SparseMatrix<typename ConstantSparseModelType::ValueType> ModelInstantiator<ParametricSparseModelType, ConstantSparseModelType>::buildDummyMatrix(storm::storage::SparseMatrix<ParametricType> const& parametricMatrix) const{ | |||
|                 storm::storage::SparseMatrixBuilder<ConstantType> matrixBuilder(parametricMatrix.getRowCount(), | |||
|                                                                                 parametricMatrix.getColumnCount(), | |||
|                                                                                 parametricMatrix.getEntryCount(), | |||
|                                                                                 true, // no force dimensions
 | |||
|                                                                                 true, //Custom row grouping
 | |||
|                                                                                 parametricMatrix.getRowGroupCount()); | |||
|                 for(std::size_t rowGroup = 0; rowGroup < parametricMatrix.getRowGroupCount(); ++rowGroup){ | |||
|                     matrixBuilder.newRowGroup(parametricMatrix.getRowGroupIndices()[rowGroup]); | |||
|                     for(std::size_t row = parametricMatrix.getRowGroupIndices()[rowGroup]; row < parametricMatrix.getRowGroupIndices()[rowGroup+1]; ++row){ | |||
|                         ConstantType dummyValue = storm::utility::one<ConstantType>(); | |||
|                         for(auto const& paramEntry : parametricMatrix.getRow(row)){ | |||
|                             matrixBuilder.addNextValue(row, paramEntry.getColumn(), dummyValue); | |||
|                             dummyValue = storm::utility::zero<ConstantType>(); | |||
|                         } | |||
|                     } | |||
|                 } | |||
|                 return matrixBuilder.build(); | |||
|             } | |||
|              | |||
|             template<typename ParametricSparseModelType, typename ConstantSparseModelType> | |||
|             std::unordered_map<std::string, typename ConstantSparseModelType::RewardModelType> ModelInstantiator<ParametricSparseModelType, ConstantSparseModelType>::buildDummyRewardModels(std::unordered_map<std::string, typename ParametricSparseModelType::RewardModelType> const& parametricRewardModel) const { | |||
|                 std::unordered_map<std::string, typename ConstantSparseModelType::RewardModelType> result; | |||
|                 for(auto const& paramRewardModel : parametricRewardModel){ | |||
|                     auto const& rewModel = paramRewardModel.second; | |||
|                     boost::optional<std::vector<ConstantType>> optionalStateRewardVector; | |||
|                     if(rewModel.hasStateRewards()) { | |||
|                         optionalStateRewardVector = std::vector<ConstantType>(rewModel.getStateRewardVector().size()); | |||
|                     } | |||
|                     boost::optional<std::vector<ConstantType>> optionalStateActionRewardVector; | |||
|                     if(rewModel.hasStateActionRewards()) { | |||
|                         optionalStateActionRewardVector = std::vector<ConstantType>(rewModel.getStateActionRewardVector().size()); | |||
|                     } | |||
|                     boost::optional<storm::storage::SparseMatrix<ConstantType>> optionalTransitionRewardMatrix; | |||
|                     if(rewModel.hasTransitionRewards()) { | |||
|                         optionalTransitionRewardMatrix = buildDummyMatrix(rewModel.getTransitionRewardMatrix()); | |||
|                     } | |||
|                     result.insert(std::make_pair(paramRewardModel.first,  | |||
|                                                  storm::models::sparse::StandardRewardModel<ConstantType>(std::move(optionalStateRewardVector), std::move(optionalStateActionRewardVector), std::move(optionalTransitionRewardMatrix)) | |||
|                                                 )); | |||
|                 } | |||
|                 return result; | |||
|             } | |||
|              | |||
|             template<typename ParametricSparseModelType, typename ConstantSparseModelType> | |||
|             void ModelInstantiator<ParametricSparseModelType, ConstantSparseModelType>::initializeMatrixMapping(storm::storage::SparseMatrix<ConstantType>& constantMatrix, | |||
|                                              std::unordered_map<ParametricType, ConstantType>& functions, | |||
|                                              std::vector<std::pair<typename storm::storage::SparseMatrix<ConstantType>::iterator, ConstantType*>>& mapping, | |||
|                                              storm::storage::SparseMatrix<ParametricType> const& parametricMatrix) const{ | |||
|                 ConstantType dummyValue = storm::utility::one<ConstantType>(); | |||
|                 auto constantEntryIt = constantMatrix.begin(); | |||
|                 auto parametricEntryIt = parametricMatrix.begin(); | |||
|                 while(parametricEntryIt != parametricMatrix.end()){ | |||
|                     STORM_LOG_ASSERT(parametricEntryIt->getColumn() == constantEntryIt->getColumn(), "Entries of parametric and constant matrix are not at the same position"); | |||
|                     if(storm::utility::isConstant(parametricEntryIt->getValue())){ | |||
|                         //Constant entries can be inserted directly
 | |||
|                         constantEntryIt->setValue(storm::utility::convertNumber<ConstantType>(storm::utility::parametric::getConstantPart(parametricEntryIt->getValue()))); | |||
|                     } else { | |||
|                         //insert the new function and store that the current constantMatrix entry needs to be set to the value of this function
 | |||
|                         auto functionsIt = functions.insert(std::make_pair(parametricEntryIt->getValue(), dummyValue)).first; | |||
|                         mapping.emplace_back(std::make_pair(constantEntryIt, &(functionsIt->second))); | |||
|                         //Note that references to elements of an unordered map remain valid after calling unordered_map::insert.
 | |||
|                     } | |||
|                     ++constantEntryIt; | |||
|                     ++parametricEntryIt; | |||
|                 } | |||
|                 STORM_LOG_ASSERT(constantEntryIt == constantMatrix.end(), "Parametric matrix seems to have more or less entries then the constant matrix"); | |||
|                 //TODO: is this necessary?
 | |||
|                 constantMatrix.updateNonzeroEntryCount(); | |||
|             } | |||
|              | |||
|             template<typename ParametricSparseModelType, typename ConstantSparseModelType> | |||
|             void ModelInstantiator<ParametricSparseModelType, ConstantSparseModelType>::initializeVectorMapping(std::vector<ConstantType>& constantVector, | |||
|                                              std::unordered_map<ParametricType, ConstantType>& functions, | |||
|                                              std::vector<std::pair<typename std::vector<ConstantType>::iterator, ConstantType*>>& mapping, | |||
|                                              std::vector<ParametricType> const& parametricVector) const{ | |||
|                 ConstantType dummyValue = storm::utility::one<ConstantType>(); | |||
|                 auto constantEntryIt = constantVector.begin(); | |||
|                 auto parametricEntryIt = parametricVector.begin(); | |||
|                 while(parametricEntryIt != parametricVector.end()){ | |||
|                     if(storm::utility::isConstant(storm::utility::simplify(*parametricEntryIt))){ | |||
|                         //Constant entries can be inserted directly
 | |||
|                         *constantEntryIt = storm::utility::convertNumber<ConstantType>(storm::utility::parametric::getConstantPart(*parametricEntryIt)); | |||
|                     } else { | |||
|                         //insert the new function and store that the current constantVector entry needs to be set to the value of this function
 | |||
|                         auto functionsIt = functions.insert(std::make_pair(*parametricEntryIt, dummyValue)).first; | |||
|                         mapping.emplace_back(std::make_pair(constantEntryIt, &(functionsIt->second))); | |||
|                         //Note that references to elements of an unordered map remain valid after calling unordered_map::insert.
 | |||
|                     } | |||
|                     ++constantEntryIt; | |||
|                     ++parametricEntryIt; | |||
|                 } | |||
|                 STORM_LOG_ASSERT(constantEntryIt == constantVector.end(), "Parametric vector seems to have more or less entries then the constant vector"); | |||
|             } | |||
|              | |||
|             template<typename ParametricSparseModelType, typename ConstantSparseModelType> | |||
|             ConstantSparseModelType const& ModelInstantiator<ParametricSparseModelType, ConstantSparseModelType>::instantiate(std::map<VariableType, CoefficientType>const& valuation){ | |||
|                 //Write results into the placeholders
 | |||
|                 for(auto& functionResult : this->functions){ | |||
|                     functionResult.second=storm::utility::convertNumber<ConstantType>( | |||
|                             storm::utility::parametric::evaluate(functionResult.first, valuation)); | |||
|                 } | |||
|                  | |||
|                 //Write the instantiated values to the matrices and vectors according to the stored mappings
 | |||
|                 for(auto& entryValuePair : this->matrixMapping){ | |||
|                     entryValuePair.first->setValue(*(entryValuePair.second)); | |||
|                 } | |||
|                 for(auto& entryValuePair : this->vectorMapping){ | |||
|                     *(entryValuePair.first)=*(entryValuePair.second); | |||
|                 } | |||
|                  | |||
|                 return *this->instantiatedModel; | |||
|             } | |||
|          | |||
| #ifdef STORM_HAVE_CARL
 | |||
|             template class ModelInstantiator<storm::models::sparse::Dtmc<storm::RationalFunction>, storm::models::sparse::Dtmc<double>>; | |||
|             template class ModelInstantiator<storm::models::sparse::Mdp<storm::RationalFunction>, storm::models::sparse::Mdp<double>>; | |||
|             template class ModelInstantiator<storm::models::sparse::Ctmc<storm::RationalFunction>, storm::models::sparse::Ctmc<double>>; | |||
|             template class ModelInstantiator<storm::models::sparse::MarkovAutomaton<storm::RationalFunction>, storm::models::sparse::MarkovAutomaton<double>>; | |||
|             template class ModelInstantiator<storm::models::sparse::StochasticTwoPlayerGame<storm::RationalFunction>, storm::models::sparse::StochasticTwoPlayerGame<double>>; | |||
| #endif
 | |||
|     } //namespace utility
 | |||
| } //namespace storm
 | |||
| @ -0,0 +1,158 @@ | |||
| /*  | |||
|  * File:   ModelInstantiator.h | |||
|  * Author: Tim Quatmann | |||
|  * | |||
|  * Created on February 23, 2016 | |||
|  */ | |||
| 
 | |||
| #ifndef STORM_UTILITY_MODELINSTANTIATOR_H | |||
| #define	STORM_UTILITY_MODELINSTANTIATOR_H | |||
| 
 | |||
| #include <unordered_map> | |||
| #include <memory> | |||
| #include <type_traits> | |||
| 
 | |||
| #include "src/models/sparse/Dtmc.h" | |||
| #include "src/models/sparse/Mdp.h" | |||
| #include "src/models/sparse/Ctmc.h" | |||
| #include "src/models/sparse/MarkovAutomaton.h" | |||
| #include "src/models/sparse/StochasticTwoPlayerGame.h" | |||
| #include "src/utility/parametric.h" | |||
| #include "src/utility/constants.h" | |||
| 
 | |||
| namespace storm { | |||
|     namespace utility{ | |||
|          | |||
|          | |||
|         /*! | |||
|          * This class allows efficient instantiation of the given parametric model. | |||
|          * The key to efficiency is to evaluate every distinct transition- (or reward-) function only once | |||
|          * instead of evaluating the same function for each occurrence in the model.  | |||
|          */ | |||
|         template<typename ParametricSparseModelType, typename ConstantSparseModelType> | |||
|             class ModelInstantiator { | |||
|             public: | |||
|                 typedef typename ParametricSparseModelType::ValueType ParametricType; | |||
|                 typedef typename storm::utility::parametric::VariableType<ParametricType>::type VariableType; | |||
|                 typedef typename storm::utility::parametric::CoefficientType<ParametricType>::type CoefficientType; | |||
|                 typedef typename ConstantSparseModelType::ValueType ConstantType; | |||
|                  | |||
|                 /*! | |||
|                  * Constructs a ModelInstantiator | |||
|                  * @param parametricModel The model that is to be instantiated | |||
|                  */ | |||
|                 ModelInstantiator(ParametricSparseModelType const& parametricModel); | |||
|                  | |||
|                 /*! | |||
|                  * Destructs the ModelInstantiator | |||
|                  */ | |||
|                 virtual ~ModelInstantiator(); | |||
| 
 | |||
|                 /*! | |||
|                  * Evaluates the occurring parametric functions and retrieves the instantiated model | |||
|                  * @param valuation Maps each occurring variables to the value with which it should be substituted | |||
|                  * @return The instantiated model | |||
|                  */ | |||
|                 ConstantSparseModelType const& instantiate(std::map<VariableType, CoefficientType>const& valuation); | |||
|                  | |||
| 
 | |||
|             private: | |||
|                 /*! | |||
|                  * Initializes the instantiatedModel with dummy data by considering the model-specific ingredients. | |||
|                  * Also initializes other model-specific data, e.g., the exitRate vector of a markov automaton | |||
|                  */ | |||
|                 template<typename PMT = ParametricSparseModelType> | |||
|                 typename std::enable_if< | |||
|                             std::is_same<PMT,storm::models::sparse::Dtmc<typename ParametricSparseModelType::ValueType>>::value || | |||
|                             std::is_same<PMT,storm::models::sparse::Mdp<typename ParametricSparseModelType::ValueType>>::value || | |||
|                             std::is_same<PMT,storm::models::sparse::Ctmc<typename ParametricSparseModelType::ValueType>>::value | |||
|                 >::type | |||
|                 initializeModelSpecificData(PMT const& parametricModel) { | |||
|                     auto stateLabelingCopy = parametricModel.getStateLabeling(); | |||
|                     auto choiceLabelingCopy = parametricModel.getOptionalChoiceLabeling(); | |||
|                     this->instantiatedModel = std::make_shared<ConstantSparseModelType>(buildDummyMatrix(parametricModel.getTransitionMatrix()), std::move(stateLabelingCopy), buildDummyRewardModels(parametricModel.getRewardModels()), std::move(choiceLabelingCopy)); | |||
|                 } | |||
|                  | |||
|                 template<typename PMT = ParametricSparseModelType> | |||
|                 typename std::enable_if< | |||
|                             std::is_same<PMT,storm::models::sparse::MarkovAutomaton<typename ParametricSparseModelType::ValueType>>::value | |||
|                 >::type | |||
|                 initializeModelSpecificData(PMT const& parametricModel) { | |||
|                     auto stateLabelingCopy = parametricModel.getStateLabeling(); | |||
|                     auto markovianStatesCopy = parametricModel.getMarkovianStates(); | |||
|                     auto choiceLabelingCopy = parametricModel.getOptionalChoiceLabeling(); | |||
|                     std::vector<ConstantType> exitRates(parametricModel.getExitRates().size(), storm::utility::one<ConstantType>()); | |||
|                     this->instantiatedModel = std::make_shared<ConstantSparseModelType>(buildDummyMatrix(parametricModel.getTransitionMatrix()), std::move(stateLabelingCopy), std::move(markovianStatesCopy), std::move(exitRates), buildDummyRewardModels(parametricModel.getRewardModels()), std::move(choiceLabelingCopy)); | |||
|                      | |||
|                     initializeVectorMapping(this->instantiatedModel->getExitRates(), this->functions, this->vectorMapping, parametricModel.getExitRates()); | |||
|                 } | |||
|                  | |||
|                 template<typename PMT = ParametricSparseModelType> | |||
|                 typename std::enable_if< | |||
|                             std::is_same<PMT,storm::models::sparse::StochasticTwoPlayerGame<typename ParametricSparseModelType::ValueType>>::value | |||
|                 >::type | |||
|                 initializeModelSpecificData(PMT const& parametricModel) { | |||
|                     auto player1MatrixCopy = parametricModel.getPlayer1Matrix(); | |||
|                     auto stateLabelingCopy = parametricModel.getStateLabeling(); | |||
|                     boost::optional<std::vector<typename storm::models::sparse::LabelSet>> player1ChoiceLabeling, player2ChoiceLabeling; | |||
|                     if(parametricModel.hasPlayer1ChoiceLabeling()) player1ChoiceLabeling = parametricModel.getPlayer1ChoiceLabeling(); | |||
|                     if(parametricModel.hasPlayer2ChoiceLabeling()) player2ChoiceLabeling = parametricModel.getPlayer2ChoiceLabeling(); | |||
|                     this->instantiatedModel = std::make_shared<ConstantSparseModelType>(std::move(player1MatrixCopy), buildDummyMatrix(parametricModel.getTransitionMatrix()), std::move(stateLabelingCopy), buildDummyRewardModels(parametricModel.getRewardModels()), std::move(player1ChoiceLabeling), std::move(player2ChoiceLabeling)); | |||
|                 } | |||
|                  | |||
|                 /*! | |||
|                  * Creates a matrix that has entries at the same position as the given matrix. | |||
|                  * The returned matrix is a stochastic matrix, i.e., the rows sum up to one. | |||
|                  */ | |||
|                 storm::storage::SparseMatrix<ConstantType> buildDummyMatrix(storm::storage::SparseMatrix<ParametricType> const& parametricMatrix) const; | |||
|                  | |||
|                 /*! | |||
|                  * Creates a copy of the given reward models with the same names and with state(action)rewards / transitionrewards having the same entry-count and entry-positions. | |||
|                  */ | |||
|                 std::unordered_map<std::string, typename ConstantSparseModelType::RewardModelType> buildDummyRewardModels(std::unordered_map<std::string, typename ParametricSparseModelType::RewardModelType> const& parametricRewardModel) const; | |||
|                  | |||
|                 /*! | |||
|                  * Connects the occurring functions with the corresponding matrix entries | |||
|                  *  | |||
|                  * @note constantMatrix and parametricMatrix should have entries at the same positions | |||
|                  *  | |||
|                  * @param constantMatrix The matrix to which the evaluation results are written | |||
|                  * @param functions Occurring functions are inserted in this map | |||
|                  * @param mapping The connections of functions to matrix entries are push_backed  into this | |||
|                  * @param parametricMatrix the source matrix with the functions to consider. | |||
|                  */ | |||
|                 void initializeMatrixMapping(storm::storage::SparseMatrix<ConstantType>& constantMatrix, | |||
|                                              std::unordered_map<ParametricType, ConstantType>& functions, | |||
|                                              std::vector<std::pair<typename storm::storage::SparseMatrix<ConstantType>::iterator, ConstantType*>>& mapping, | |||
|                                              storm::storage::SparseMatrix<ParametricType> const& parametricMatrix) const; | |||
|                  | |||
|                 /*! | |||
|                  * Connects the occurring functions with the corresponding vector entries | |||
|                  *  | |||
|                  * @note constantVector and parametricVector should have the same size | |||
|                  *  | |||
|                  * @param constantVector The vector to which the evaluation results are written | |||
|                  * @param functions Occurring functions with their placeholders are inserted in this map | |||
|                  * @param mapping The connections of functions to vector entries are push_backed  into this | |||
|                  * @param parametricVector the source vector with the functions to consider. | |||
|                  */ | |||
|                 void initializeVectorMapping(std::vector<ConstantType>& constantVector, | |||
|                                              std::unordered_map<ParametricType, ConstantType>& functions, | |||
|                                              std::vector<std::pair<typename std::vector<ConstantType>::iterator, ConstantType*>>& mapping, | |||
|                                              std::vector<ParametricType> const& parametricVector) const; | |||
|                  | |||
|                 /// The resulting model | |||
|                 std::shared_ptr<ConstantSparseModelType> instantiatedModel; | |||
|                 /// the occurring functions together with the corresponding placeholders for their evaluated result | |||
|                 std::unordered_map<ParametricType, ConstantType> functions;  | |||
|                 /// Connection of matrix entries with placeholders | |||
|                 std::vector<std::pair<typename storm::storage::SparseMatrix<ConstantType>::iterator, ConstantType*>> matrixMapping;  | |||
|                 /// Connection of Vector entries with placeholders | |||
|                 std::vector<std::pair<typename std::vector<ConstantType>::iterator, ConstantType*>> vectorMapping;  | |||
|                  | |||
|                  | |||
|             }; | |||
|     }//Namespace utility | |||
| } //namespace storm | |||
| #endif	/* STORM_UTILITY_MODELINSTANTIATOR_H */ | |||
| 
 | |||
| @ -0,0 +1,39 @@ | |||
| /* 
 | |||
|  * File:   parametric.cpp | |||
|  * Author: Tim Quatmann | |||
|  *  | |||
|  * Created by Tim Quatmann on 08/03/16. | |||
|  */ | |||
| 
 | |||
| #include <string>
 | |||
| 
 | |||
| #include "src/utility/parametric.h"
 | |||
| #include "src/utility/constants.h"
 | |||
| #include "src/utility/macros.h"
 | |||
| #include "src/settings/SettingsManager.h"
 | |||
| #include "src/exceptions/IllegalArgumentException.h"
 | |||
| #include "src/exceptions/NotImplementedException.h"
 | |||
| 
 | |||
| #ifdef STORM_HAVE_CARL
 | |||
| #include<carl/numbers/numbers.h>
 | |||
| #include<carl/core/VariablePool.h>
 | |||
| #endif
 | |||
| 
 | |||
| namespace storm { | |||
|     namespace utility{ | |||
|         namespace parametric { | |||
|              | |||
| #ifdef STORM_HAVE_CARL
 | |||
|             template<> | |||
|             typename CoefficientType<storm::RationalFunction>::type evaluate<storm::RationalFunction>(storm::RationalFunction const& function, std::map<typename VariableType<storm::RationalFunction>::type, typename CoefficientType<storm::RationalFunction>::type> const& valuation){ | |||
|                 return function.evaluate(valuation); | |||
|             } | |||
|              | |||
|             template<> | |||
|             typename CoefficientType<storm::RationalFunction>::type getConstantPart<storm::RationalFunction>(storm::RationalFunction const& function){ | |||
|                 return function.constantPart(); | |||
|             } | |||
| #endif
 | |||
|         } | |||
|     } | |||
| } | |||
| @ -0,0 +1,54 @@ | |||
| // | |||
| //  parametric.h | |||
| // | |||
| //  Created by Tim Quatmann on 08/03/16. | |||
| // | |||
| // | |||
| 
 | |||
| #ifndef STORM_UTILITY_PARAMETRIC_H | |||
| #define STORM_UTILITY_PARAMETRIC_H | |||
| 
 | |||
| #include "src/adapters/CarlAdapter.h" | |||
| 
 | |||
| 
 | |||
| namespace storm { | |||
|     namespace utility { | |||
|         namespace parametric { | |||
|              | |||
|             /*! | |||
|              * Access the type of variables from a given function type | |||
|              */ | |||
|             template<typename FunctionType> | |||
|             struct VariableType { typedef void type; }; | |||
|             /*! | |||
|              * Acess the type of coefficients from a given function type | |||
|              */ | |||
|             template<typename FunctionType> | |||
|             struct CoefficientType { typedef void type; }; | |||
|              | |||
| #ifdef STORM_HAVE_CARL | |||
|             template<> | |||
|             struct VariableType<storm::RationalFunction> { typedef storm::Variable type; }; | |||
|             template<> | |||
|             struct CoefficientType<storm::RationalFunction> { typedef storm::RationalNumber type; }; | |||
| #endif | |||
|              | |||
|             /*! | |||
|              * Evaluates the given function wrt. the given valuation | |||
|              */ | |||
|             template<typename FunctionType> | |||
|             typename CoefficientType<FunctionType>::type evaluate(FunctionType const& function, std::map<typename VariableType<FunctionType>::type, typename CoefficientType<FunctionType>::type> const& valuation); | |||
|              | |||
|             /*! | |||
|              * Retrieves the constant part of the given function. | |||
|              */ | |||
|             template<typename FunctionType> | |||
|             typename CoefficientType<FunctionType>::type getConstantPart(FunctionType const& function); | |||
| 
 | |||
|         } | |||
|          | |||
|     } | |||
| } | |||
| 
 | |||
| 
 | |||
| #endif /* STORM_UTILITY_PARAMETRIC_H */ | |||
| @ -0,0 +1,266 @@ | |||
| #include "gtest/gtest.h"
 | |||
| #include "storm-config.h"
 | |||
| 
 | |||
| #ifdef STORM_HAVE_CARL
 | |||
| 
 | |||
| #include "src/adapters/CarlAdapter.h"
 | |||
| #include<carl/numbers/numbers.h>
 | |||
| #include<carl/core/VariablePool.h>
 | |||
| 
 | |||
| 
 | |||
| #include "src/settings/SettingsManager.h"
 | |||
| #include "src/settings/modules/GeneralSettings.h"
 | |||
| 
 | |||
| #include "utility/storm.h"
 | |||
| #include "utility/ModelInstantiator.h"
 | |||
| #include "src/models/sparse/Model.h"
 | |||
| #include "src/models/sparse/Dtmc.h"
 | |||
| #include "src/models/sparse/Mdp.h"
 | |||
| 
 | |||
| TEST(ModelInstantiatorTest, Brp_Prob) { | |||
|     carl::VariablePool::getInstance().clear(); | |||
|      | |||
|     std::string const& programFile = STORM_CPP_TESTS_BASE_PATH "/functional/utility/brp16_2.pm"; | |||
|     std::string const& formulaAsString = "P=? [F s=5 ]"; | |||
|     std::string const& constantsAsString = ""; //e.g. pL=0.9,TOACK=0.5
 | |||
|      | |||
|     // Program and formula
 | |||
|     storm::prism::Program program = storm::parseProgram(programFile); | |||
|     program.checkValidity(); | |||
|     std::vector<std::shared_ptr<storm::logic::Formula>> formulas = storm::parseFormulasForProgram(formulaAsString, program); | |||
|     ASSERT_TRUE(formulas.size()==1); | |||
|     // Parametric model
 | |||
|     typename storm::builder::ExplicitPrismModelBuilder<storm::RationalFunction>::Options options = storm::builder::ExplicitPrismModelBuilder<storm::RationalFunction>::Options(*formulas[0]); | |||
|     options.addConstantDefinitionsFromString(program, constantsAsString);  | |||
|     options.preserveFormula(*formulas[0]); | |||
|     std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> dtmc = storm::builder::ExplicitPrismModelBuilder<storm::RationalFunction>().translateProgram(program, options)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>(); | |||
|      | |||
|     storm::utility::ModelInstantiator<storm::models::sparse::Dtmc<storm::RationalFunction>, storm::models::sparse::Dtmc<double>> modelInstantiator(*dtmc); | |||
|     EXPECT_FALSE(dtmc->hasRewardModel()); | |||
|      | |||
|     { | |||
|         std::map<storm::Variable, storm::RationalNumber> valuation; | |||
|         storm::Variable const& pL = carl::VariablePool::getInstance().findVariableWithName("pL"); | |||
|         ASSERT_NE(pL, carl::Variable::NO_VARIABLE); | |||
|         storm::Variable const& pK = carl::VariablePool::getInstance().findVariableWithName("pK"); | |||
|         ASSERT_NE(pK, carl::Variable::NO_VARIABLE); | |||
|         valuation.insert(std::make_pair(pL,carl::rationalize<storm::RationalNumber>(0.8))); | |||
|         valuation.insert(std::make_pair(pK,carl::rationalize<storm::RationalNumber>(0.9))); | |||
| 
 | |||
|         storm::models::sparse::Dtmc<double> const& instantiated(modelInstantiator.instantiate(valuation)); | |||
| 
 | |||
|         ASSERT_EQ(dtmc->getTransitionMatrix().getRowGroupIndices(), instantiated.getTransitionMatrix().getRowGroupIndices()); | |||
|         for(std::size_t rowGroup = 0; rowGroup < dtmc->getTransitionMatrix().getRowGroupCount(); ++rowGroup){ | |||
|             for(std::size_t row = dtmc->getTransitionMatrix().getRowGroupIndices()[rowGroup]; row < dtmc->getTransitionMatrix().getRowGroupIndices()[rowGroup+1]; ++row){ | |||
|                 auto instantiatedEntry = instantiated.getTransitionMatrix().getRow(row).begin(); | |||
|                 for(auto const& paramEntry : dtmc->getTransitionMatrix().getRow(row)){ | |||
|                     EXPECT_EQ(paramEntry.getColumn(), instantiatedEntry->getColumn()); | |||
|                     double evaluatedValue = carl::toDouble(paramEntry.getValue().evaluate(valuation)); | |||
|                     EXPECT_EQ(evaluatedValue, instantiatedEntry->getValue()); | |||
|                     ++instantiatedEntry; | |||
|                 } | |||
|                 EXPECT_EQ(instantiated.getTransitionMatrix().getRow(row).end(),instantiatedEntry); | |||
|             } | |||
|         } | |||
|         EXPECT_EQ(dtmc->getStateLabeling(), instantiated.getStateLabeling()); | |||
|         EXPECT_EQ(dtmc->getOptionalChoiceLabeling(), instantiated.getOptionalChoiceLabeling()); | |||
| 
 | |||
|         storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> modelchecker(instantiated); | |||
|         std::unique_ptr<storm::modelchecker::CheckResult> chkResult = modelchecker.check(*formulas[0]); | |||
|         storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeChkResult = chkResult->asExplicitQuantitativeCheckResult<double>(); | |||
|         EXPECT_NEAR(0.2989278941, quantitativeChkResult[*instantiated.getInitialStates().begin()], storm::settings::generalSettings().getPrecision()); | |||
|     } | |||
|      | |||
|     { | |||
|         std::map<storm::Variable, storm::RationalNumber> valuation; | |||
|         storm::Variable const& pL = carl::VariablePool::getInstance().findVariableWithName("pL"); | |||
|         ASSERT_NE(pL, carl::Variable::NO_VARIABLE); | |||
|         storm::Variable const& pK = carl::VariablePool::getInstance().findVariableWithName("pK"); | |||
|         ASSERT_NE(pK, carl::Variable::NO_VARIABLE); | |||
|         valuation.insert(std::make_pair(pL,carl::rationalize<storm::RationalNumber>(1))); | |||
|         valuation.insert(std::make_pair(pK,carl::rationalize<storm::RationalNumber>(1))); | |||
| 
 | |||
|         storm::models::sparse::Dtmc<double> const& instantiated(modelInstantiator.instantiate(valuation)); | |||
| 
 | |||
|         ASSERT_EQ(dtmc->getTransitionMatrix().getRowGroupIndices(), instantiated.getTransitionMatrix().getRowGroupIndices()); | |||
|         for(std::size_t rowGroup = 0; rowGroup < dtmc->getTransitionMatrix().getRowGroupCount(); ++rowGroup){ | |||
|             for(std::size_t row = dtmc->getTransitionMatrix().getRowGroupIndices()[rowGroup]; row < dtmc->getTransitionMatrix().getRowGroupIndices()[rowGroup+1]; ++row){ | |||
|                 auto instantiatedEntry = instantiated.getTransitionMatrix().getRow(row).begin(); | |||
|                 for(auto const& paramEntry : dtmc->getTransitionMatrix().getRow(row)){ | |||
|                     EXPECT_EQ(paramEntry.getColumn(), instantiatedEntry->getColumn()); | |||
|                     double evaluatedValue = carl::toDouble(paramEntry.getValue().evaluate(valuation)); | |||
|                     EXPECT_EQ(evaluatedValue, instantiatedEntry->getValue()); | |||
|                     ++instantiatedEntry; | |||
|                 } | |||
|                 EXPECT_EQ(instantiated.getTransitionMatrix().getRow(row).end(),instantiatedEntry); | |||
|             } | |||
|         } | |||
|         EXPECT_EQ(dtmc->getStateLabeling(), instantiated.getStateLabeling()); | |||
|         EXPECT_EQ(dtmc->getOptionalChoiceLabeling(), instantiated.getOptionalChoiceLabeling()); | |||
| 
 | |||
|         storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> modelchecker(instantiated); | |||
|         std::unique_ptr<storm::modelchecker::CheckResult> chkResult = modelchecker.check(*formulas[0]); | |||
|         storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeChkResult = chkResult->asExplicitQuantitativeCheckResult<double>(); | |||
|         EXPECT_EQ(0.0 , quantitativeChkResult[*instantiated.getInitialStates().begin()]); | |||
|     } | |||
|      | |||
|     { | |||
|         std::map<storm::Variable, storm::RationalNumber> valuation; | |||
|         storm::Variable const& pL = carl::VariablePool::getInstance().findVariableWithName("pL"); | |||
|         ASSERT_NE(pL, carl::Variable::NO_VARIABLE); | |||
|         storm::Variable const& pK = carl::VariablePool::getInstance().findVariableWithName("pK"); | |||
|         ASSERT_NE(pK, carl::Variable::NO_VARIABLE); | |||
|         valuation.insert(std::make_pair(pL,carl::rationalize<storm::RationalNumber>(1))); | |||
|         valuation.insert(std::make_pair(pK,carl::rationalize<storm::RationalNumber>(0.9))); | |||
| 
 | |||
|         storm::models::sparse::Dtmc<double> const& instantiated(modelInstantiator.instantiate(valuation)); | |||
| 
 | |||
|         ASSERT_EQ(dtmc->getTransitionMatrix().getRowGroupIndices(), instantiated.getTransitionMatrix().getRowGroupIndices()); | |||
|         for(std::size_t rowGroup = 0; rowGroup < dtmc->getTransitionMatrix().getRowGroupCount(); ++rowGroup){ | |||
|             for(std::size_t row = dtmc->getTransitionMatrix().getRowGroupIndices()[rowGroup]; row < dtmc->getTransitionMatrix().getRowGroupIndices()[rowGroup+1]; ++row){ | |||
|                 auto instantiatedEntry = instantiated.getTransitionMatrix().getRow(row).begin(); | |||
|                 for(auto const& paramEntry : dtmc->getTransitionMatrix().getRow(row)){ | |||
|                     EXPECT_EQ(paramEntry.getColumn(), instantiatedEntry->getColumn()); | |||
|                     double evaluatedValue = carl::toDouble(paramEntry.getValue().evaluate(valuation)); | |||
|                     EXPECT_EQ(evaluatedValue, instantiatedEntry->getValue()); | |||
|                     ++instantiatedEntry; | |||
|                 } | |||
|                 EXPECT_EQ(instantiated.getTransitionMatrix().getRow(row).end(),instantiatedEntry); | |||
|             } | |||
|         } | |||
|         EXPECT_EQ(dtmc->getStateLabeling(), instantiated.getStateLabeling()); | |||
|         EXPECT_EQ(dtmc->getOptionalChoiceLabeling(), instantiated.getOptionalChoiceLabeling()); | |||
| 
 | |||
|         storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> modelchecker(instantiated); | |||
|         std::unique_ptr<storm::modelchecker::CheckResult> chkResult = modelchecker.check(*formulas[0]); | |||
|         storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeChkResult = chkResult->asExplicitQuantitativeCheckResult<double>(); | |||
|         EXPECT_NEAR(0.01588055832, quantitativeChkResult[*instantiated.getInitialStates().begin()], storm::settings::generalSettings().getPrecision()); | |||
|     } | |||
| } | |||
| 
 | |||
| TEST(ModelInstantiatorTest, Brp_Rew) { | |||
|     carl::VariablePool::getInstance().clear(); | |||
|      | |||
|     std::string const& programFile = STORM_CPP_TESTS_BASE_PATH "/functional/utility/brp16_2.pm"; | |||
|     std::string const& formulaAsString = "R=? [F ((s=5) | (s=0&srep=3)) ]"; | |||
|     std::string const& constantsAsString = ""; //e.g. pL=0.9,TOACK=0.5
 | |||
|      | |||
|     // Program and formula
 | |||
|     storm::prism::Program program = storm::parseProgram(programFile); | |||
|     program.checkValidity(); | |||
|     std::vector<std::shared_ptr<storm::logic::Formula>> formulas = storm::parseFormulasForProgram(formulaAsString, program); | |||
|     ASSERT_TRUE(formulas.size()==1); | |||
|     // Parametric model
 | |||
|     typename storm::builder::ExplicitPrismModelBuilder<storm::RationalFunction>::Options options = storm::builder::ExplicitPrismModelBuilder<storm::RationalFunction>::Options(*formulas[0]); | |||
|     options.addConstantDefinitionsFromString(program, constantsAsString);  | |||
|     options.preserveFormula(*formulas[0]); | |||
|     std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> dtmc = storm::builder::ExplicitPrismModelBuilder<storm::RationalFunction>().translateProgram(program, options)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>(); | |||
| 
 | |||
|     storm::utility::ModelInstantiator<storm::models::sparse::Dtmc<storm::RationalFunction>, storm::models::sparse::Dtmc<double>> modelInstantiator(*dtmc); | |||
|      | |||
|     { | |||
|         std::map<storm::Variable, storm::RationalNumber> valuation; | |||
|         storm::Variable const& pL = carl::VariablePool::getInstance().findVariableWithName("pL"); | |||
|         ASSERT_NE(pL, carl::Variable::NO_VARIABLE); | |||
|         storm::Variable const& pK = carl::VariablePool::getInstance().findVariableWithName("pK"); | |||
|         ASSERT_NE(pK, carl::Variable::NO_VARIABLE); | |||
|         storm::Variable const& TOMsg = carl::VariablePool::getInstance().findVariableWithName("TOMsg"); | |||
|         ASSERT_NE(pK, carl::Variable::NO_VARIABLE); | |||
|         storm::Variable const& TOAck = carl::VariablePool::getInstance().findVariableWithName("TOAck"); | |||
|         ASSERT_NE(pK, carl::Variable::NO_VARIABLE); | |||
|         valuation.insert(std::make_pair(pL,carl::rationalize<storm::RationalNumber>(0.9))); | |||
|         valuation.insert(std::make_pair(pK,carl::rationalize<storm::RationalNumber>(0.3))); | |||
|         valuation.insert(std::make_pair(TOMsg,carl::rationalize<storm::RationalNumber>(0.3))); | |||
|         valuation.insert(std::make_pair(TOAck,carl::rationalize<storm::RationalNumber>(0.5))); | |||
| 
 | |||
|         storm::models::sparse::Dtmc<double> const& instantiated(modelInstantiator.instantiate(valuation)); | |||
| 
 | |||
|         ASSERT_EQ(dtmc->getTransitionMatrix().getRowGroupIndices(), instantiated.getTransitionMatrix().getRowGroupIndices()); | |||
|         for(std::size_t rowGroup = 0; rowGroup < dtmc->getTransitionMatrix().getRowGroupCount(); ++rowGroup){ | |||
|             for(std::size_t row = dtmc->getTransitionMatrix().getRowGroupIndices()[rowGroup]; row < dtmc->getTransitionMatrix().getRowGroupIndices()[rowGroup+1]; ++row){ | |||
|                 auto instantiatedEntry = instantiated.getTransitionMatrix().getRow(row).begin(); | |||
|                 for(auto const& paramEntry : dtmc->getTransitionMatrix().getRow(row)){ | |||
|                     EXPECT_EQ(paramEntry.getColumn(), instantiatedEntry->getColumn()); | |||
|                     double evaluatedValue = carl::toDouble(paramEntry.getValue().evaluate(valuation)); | |||
|                     EXPECT_EQ(evaluatedValue, instantiatedEntry->getValue()); | |||
|                     ++instantiatedEntry; | |||
|                 } | |||
|                 EXPECT_EQ(instantiated.getTransitionMatrix().getRow(row).end(),instantiatedEntry); | |||
|             } | |||
|         } | |||
|         ASSERT_TRUE(instantiated.hasUniqueRewardModel()); | |||
|         EXPECT_FALSE(instantiated.getUniqueRewardModel()->second.hasStateRewards()); | |||
|         EXPECT_FALSE(instantiated.getUniqueRewardModel()->second.hasTransitionRewards()); | |||
|         EXPECT_TRUE(instantiated.getUniqueRewardModel()->second.hasStateActionRewards()); | |||
|         ASSERT_TRUE(dtmc->getUniqueRewardModel()->second.hasStateActionRewards()); | |||
|         std::size_t stateActionEntries = dtmc->getUniqueRewardModel()->second.getStateActionRewardVector().size(); | |||
|         ASSERT_EQ(stateActionEntries, instantiated.getUniqueRewardModel()->second.getStateActionRewardVector().size()); | |||
|         for(std::size_t i =0; i<stateActionEntries; ++i){ | |||
|             double evaluatedValue = carl::toDouble(dtmc->getUniqueRewardModel()->second.getStateActionRewardVector()[i].evaluate(valuation)); | |||
|             EXPECT_EQ(evaluatedValue, instantiated.getUniqueRewardModel()->second.getStateActionRewardVector()[i]); | |||
|         } | |||
|         EXPECT_EQ(dtmc->getStateLabeling(), instantiated.getStateLabeling()); | |||
|         EXPECT_EQ(dtmc->getOptionalChoiceLabeling(), instantiated.getOptionalChoiceLabeling()); | |||
| 
 | |||
|         storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> modelchecker(instantiated); | |||
|         std::unique_ptr<storm::modelchecker::CheckResult> chkResult = modelchecker.check(*formulas[0]); | |||
|         storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeChkResult = chkResult->asExplicitQuantitativeCheckResult<double>(); | |||
|         EXPECT_NEAR(1.308324495, quantitativeChkResult[*instantiated.getInitialStates().begin()], storm::settings::generalSettings().getPrecision()); | |||
|     } | |||
|      | |||
| } | |||
|      | |||
| 
 | |||
| TEST(ModelInstantiatorTest, consensus) { | |||
|     carl::VariablePool::getInstance().clear(); | |||
|      | |||
|     std::string const& programFile = STORM_CPP_TESTS_BASE_PATH "/functional/utility/coin2_2.pm"; | |||
|     std::string const& formulaAsString = "Pmin=? [F \"finished\"&\"all_coins_equal_1\" ]"; | |||
|     std::string const& constantsAsString = ""; //e.g. pL=0.9,TOACK=0.5
 | |||
|      | |||
|     // Program and formula
 | |||
|     storm::prism::Program program = storm::parseProgram(programFile); | |||
|     program.checkValidity(); | |||
|     std::vector<std::shared_ptr<storm::logic::Formula>> formulas = storm::parseFormulasForProgram(formulaAsString, program); | |||
|     ASSERT_TRUE(formulas.size()==1); | |||
|     // Parametric model
 | |||
|     typename storm::builder::ExplicitPrismModelBuilder<storm::RationalFunction>::Options options = storm::builder::ExplicitPrismModelBuilder<storm::RationalFunction>::Options(*formulas[0]); | |||
|     options.addConstantDefinitionsFromString(program, constantsAsString);  | |||
|     options.preserveFormula(*formulas[0]); | |||
|     std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> mdp = storm::builder::ExplicitPrismModelBuilder<storm::RationalFunction>().translateProgram(program, options)->as<storm::models::sparse::Mdp<storm::RationalFunction>>(); | |||
| 
 | |||
|     storm::utility::ModelInstantiator<storm::models::sparse::Mdp<storm::RationalFunction>, storm::models::sparse::Mdp<double>> modelInstantiator(*mdp); | |||
|      | |||
|     std::map<storm::Variable, storm::RationalNumber> valuation; | |||
|     storm::Variable const& p1 = carl::VariablePool::getInstance().findVariableWithName("p1"); | |||
|     ASSERT_NE(p1, carl::Variable::NO_VARIABLE); | |||
|     storm::Variable const& p2 = carl::VariablePool::getInstance().findVariableWithName("p2"); | |||
|     ASSERT_NE(p2, carl::Variable::NO_VARIABLE); | |||
|     valuation.insert(std::make_pair(p1,carl::rationalize<storm::RationalNumber>(0.51))); | |||
|     valuation.insert(std::make_pair(p2,carl::rationalize<storm::RationalNumber>(0.49))); | |||
|     storm::models::sparse::Mdp<double> const& instantiated(modelInstantiator.instantiate(valuation)); | |||
| 
 | |||
|     ASSERT_EQ(mdp->getTransitionMatrix().getRowGroupIndices(), instantiated.getTransitionMatrix().getRowGroupIndices()); | |||
|     for(std::size_t rowGroup = 0; rowGroup < mdp->getTransitionMatrix().getRowGroupCount(); ++rowGroup){ | |||
|         for(std::size_t row = mdp->getTransitionMatrix().getRowGroupIndices()[rowGroup]; row < mdp->getTransitionMatrix().getRowGroupIndices()[rowGroup+1]; ++row){ | |||
|             auto instantiatedEntry = instantiated.getTransitionMatrix().getRow(row).begin(); | |||
|             for(auto const& paramEntry : mdp->getTransitionMatrix().getRow(row)){ | |||
|                 EXPECT_EQ(paramEntry.getColumn(), instantiatedEntry->getColumn()); | |||
|                 double evaluatedValue = carl::toDouble(paramEntry.getValue().evaluate(valuation)); | |||
|                 EXPECT_EQ(evaluatedValue, instantiatedEntry->getValue()); | |||
|                 ++instantiatedEntry; | |||
|             } | |||
|             EXPECT_EQ(instantiated.getTransitionMatrix().getRow(row).end(),instantiatedEntry); | |||
|         } | |||
|     } | |||
|     EXPECT_EQ(mdp->getStateLabeling(), instantiated.getStateLabeling()); | |||
|     EXPECT_EQ(mdp->getOptionalChoiceLabeling(), instantiated.getOptionalChoiceLabeling()); | |||
| 
 | |||
|     storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> modelchecker(instantiated); | |||
|     std::unique_ptr<storm::modelchecker::CheckResult> chkResult = modelchecker.check(*formulas[0]); | |||
|     storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeChkResult = chkResult->asExplicitQuantitativeCheckResult<double>(); | |||
|     EXPECT_NEAR(0.3526577219, quantitativeChkResult[*instantiated.getInitialStates().begin()], storm::settings::generalSettings().getPrecision()); | |||
|      | |||
| } | |||
| 
 | |||
| #endif
 | |||
| @ -0,0 +1,146 @@ | |||
| // bounded retransmission protocol [D'AJJL01] | |||
| // gxn/dxp 23/05/2001 | |||
| 
 | |||
| dtmc | |||
| 
 | |||
| // number of chunks | |||
| const int N = 16; | |||
| // maximum number of retransmissions | |||
| const int MAX = 2; | |||
| 
 | |||
| // reliability of channels | |||
| const double pL; | |||
| const double pK; | |||
| 
 | |||
| // timeouts | |||
| const double TOMsg; | |||
| const double TOAck; | |||
| 
 | |||
| module sender | |||
| 
 | |||
|     s : [0..6]; | |||
|     // 0 idle | |||
|     // 1 next_frame  | |||
|     // 2 wait_ack | |||
|     // 3 retransmit | |||
|     // 4 success | |||
|     // 5 error | |||
|     // 6 wait sync | |||
|     srep : [0..3]; | |||
|     // 0 bottom | |||
|     // 1 not ok (nok) | |||
|     // 2 do not know (dk) | |||
|     // 3 ok (ok) | |||
|     nrtr : [0..MAX]; | |||
|     i : [0..N]; | |||
|     bs : bool; | |||
|     s_ab : bool; | |||
|     fs : bool; | |||
|     ls : bool; | |||
|      | |||
|     // idle | |||
|     [NewFile] (s=0) -> (s'=1) & (i'=1) & (srep'=0); | |||
|     // next_frame | |||
|     [aF] (s=1) -> (s'=2) & (fs'=(i=1)) & (ls'=(i=N)) & (bs'=s_ab) & (nrtr'=0); | |||
|     // wait_ack | |||
|     [aB] (s=2) -> (s'=4) & (s_ab'=!s_ab); | |||
|     [TO_Msg] (s=2) -> (s'=3); | |||
|     [TO_Ack] (s=2) -> (s'=3); | |||
|     // retransmit | |||
|     [aF] (s=3) & (nrtr<MAX) -> (s'=2) & (fs'=(i=1)) & (ls'=(i=N)) & (bs'=s_ab) & (nrtr'=nrtr+1); | |||
|     [] (s=3) & (nrtr=MAX) & (i<N) -> (s'=5) & (srep'=1); | |||
|     [] (s=3) & (nrtr=MAX) & (i=N) -> (s'=5) & (srep'=2); | |||
|     // success | |||
|     [] (s=4) & (i<N) -> (s'=1) & (i'=i+1); | |||
|     [] (s=4) & (i=N) -> (s'=0) & (srep'=3); | |||
|     // error | |||
|     [SyncWait] (s=5) -> (s'=6);  | |||
|     // wait sync | |||
|     [SyncWait] (s=6) -> (s'=0) & (s_ab'=false);  | |||
|      | |||
| endmodule | |||
| 
 | |||
| module receiver | |||
| 
 | |||
|     r : [0..5]; | |||
|     // 0 new_file | |||
|     // 1 fst_safe | |||
|     // 2 frame_received | |||
|     // 3 frame_reported | |||
|     // 4 idle | |||
|     // 5 resync | |||
|     rrep : [0..4]; | |||
|     // 0 bottom | |||
|     // 1 fst | |||
|     // 2 inc | |||
|     // 3 ok | |||
|     // 4 nok | |||
|     fr : bool; | |||
|     lr : bool; | |||
|     br : bool; | |||
|     r_ab : bool; | |||
|     recv : bool; | |||
|      | |||
|      | |||
|     // new_file | |||
|     [SyncWait] (r=0) -> (r'=0); | |||
|     [aG] (r=0) -> (r'=1) & (fr'=fs) & (lr'=ls) & (br'=bs) & (recv'=T); | |||
|     // fst_safe_frame | |||
|     [] (r=1) -> (r'=2) & (r_ab'=br); | |||
|     // frame_received | |||
|     [] (r=2) & (r_ab=br) & (fr=true) & (lr=false)  -> (r'=3) & (rrep'=1); | |||
|     [] (r=2) & (r_ab=br) & (fr=false) & (lr=false) -> (r'=3) & (rrep'=2); | |||
|     [] (r=2) & (r_ab=br) & (fr=false) & (lr=true)  -> (r'=3) & (rrep'=3); | |||
|     [aA] (r=2) & !(r_ab=br) -> (r'=4);   | |||
|     // frame_reported | |||
|     [aA] (r=3) -> (r'=4) & (r_ab'=!r_ab); | |||
|     // idle | |||
|     [aG] (r=4) -> (r'=2) & (fr'=fs) & (lr'=ls) & (br'=bs) & (recv'=T); | |||
|     [SyncWait] (r=4) & (ls=true) -> (r'=5); | |||
|     [SyncWait] (r=4) & (ls=false) -> (r'=5) & (rrep'=4); | |||
|     // resync | |||
|     [SyncWait] (r=5) -> (r'=0) & (rrep'=0); | |||
|      | |||
| endmodule | |||
| 
 | |||
| // prevents more than one file being sent | |||
| module tester  | |||
| 
 | |||
|     T : bool; | |||
|      | |||
|     [NewFile] (T=false) -> (T'=true); | |||
|      | |||
| endmodule | |||
| 
 | |||
| module  channelK | |||
| 
 | |||
|     k : [0..2]; | |||
|      | |||
|     // idle | |||
|     [aF] (k=0) -> pK : (k'=1) + 1-pK : (k'=2); | |||
|     // sending | |||
|     [aG] (k=1) -> (k'=0); | |||
|     // lost | |||
|     [TO_Msg] (k=2) -> (k'=0); | |||
|      | |||
| endmodule | |||
| 
 | |||
| module  channelL | |||
| 
 | |||
|     l : [0..2]; | |||
|      | |||
|     // idle | |||
|     [aA] (l=0) -> pL : (l'=1) + 1-pL : (l'=2); | |||
|     // sending | |||
|     [aB] (l=1) -> (l'=0); | |||
|     // lost | |||
|     [TO_Ack] (l=2) -> (l'=0); | |||
|      | |||
| endmodule | |||
| 
 | |||
| rewards | |||
| 	[TO_Msg] true : TOMsg; | |||
| 	[TO_Ack] true : TOAck; | |||
| endrewards | |||
| 
 | |||
| 
 | |||
| @ -0,0 +1,56 @@ | |||
| //Randomised Consensus Protocol | |||
| 
 | |||
| mdp | |||
| const double p1; // in [0.2 , 0.8] | |||
| const double p2; // in [0.2 , 0.8] | |||
| 
 | |||
| 
 | |||
| const int N=2; | |||
| const int K=2; | |||
| const int range = 2*(K+1)*N; | |||
| const int counter_init = (K+1)*N; | |||
| const int left = N; | |||
| const int right = 2*(K+1)*N - N; | |||
| 
 | |||
| // shared coin | |||
| global counter : [0..range] init counter_init; | |||
| 
 | |||
| module process1 | |||
| 	 | |||
| 	// program counter | |||
| 	pc1 : [0..3]; | |||
| 	// 0 - flip | |||
| 	// 1 - write  | |||
| 	// 2 - check | |||
| 	// 3 - finished | |||
| 	 | |||
| 	// local coin | |||
| 	coin1 : [0..1];	 | |||
| 
 | |||
| 	// flip coin | |||
| 	[] (pc1=0)  -> p1 : (coin1'=0) & (pc1'=1) + 1 - p1 : (coin1'=1) & (pc1'=1); | |||
| 	// write tails -1  (reset coin to add regularity) | |||
| 	[] (pc1=1) & (coin1=0) & (counter>0) -> (counter'=counter-1) & (pc1'=2) & (coin1'=0); | |||
| 	// write heads +1 (reset coin to add regularity) | |||
| 	[] (pc1=1) & (coin1=1) & (counter<range) -> (counter'=counter+1) & (pc1'=2) & (coin1'=0); | |||
| 	// check | |||
| 	// decide tails | |||
| 	[] (pc1=2) & (counter<=left) -> (pc1'=3) & (coin1'=0); | |||
| 	// decide heads | |||
| 	[] (pc1=2) & (counter>=right) -> (pc1'=3) & (coin1'=1); | |||
| 	// flip again | |||
| 	[] (pc1=2) & (counter>left) & (counter<right) -> (pc1'=0); | |||
| 	// loop (all loop together when done) | |||
| 	[done] (pc1=3) -> (pc1'=3); | |||
| 
 | |||
| endmodule | |||
| 
 | |||
| module process2 = process1[pc1=pc2,coin1=coin2,p1=p2] endmodule | |||
| label "finished" = pc1=3 &pc2=3 ; | |||
| label "all_coins_equal_1" = coin1=1 &coin2=1 ; | |||
| rewards "steps" | |||
| 	true : 1; | |||
| endrewards | |||
| 
 | |||
| 
 | |||
| 
 | |||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue