Browse Source
Merge branch 'future' into variance_properties
Merge branch 'future' into variance_properties
Former-commit-id: 13fe1e8531
tempestpy_adaptions
dehnert
9 years ago
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