Browse Source

implemented some auxilarry functions for parameterregions

Former-commit-id: 590a0f216c
tempestpy_adaptions
TimQu 10 years ago
parent
commit
836b5cebc6
  1. 123
      src/modelchecker/reachability/SparseDtmcRegionModelChecker.cpp
  2. 44
      src/modelchecker/reachability/SparseDtmcRegionModelChecker.h
  3. 17
      src/utility/cli.h
  4. 142
      src/utility/regions.cpp
  5. 90
      src/utility/regions.h

123
src/modelchecker/reachability/SparseDtmcRegionModelChecker.cpp

@ -22,11 +22,74 @@
#include "src/exceptions/InvalidPropertyException.h" #include "src/exceptions/InvalidPropertyException.h"
#include "src/exceptions/InvalidStateException.h" #include "src/exceptions/InvalidStateException.h"
#include "exceptions/UnexpectedException.h"
#include "src/exceptions/UnexpectedException.h"
namespace storm { namespace storm {
namespace modelchecker { namespace modelchecker {
template<typename ParametricType, typename ConstantType>
SparseDtmcRegionModelChecker<ParametricType, ConstantType>::ParameterRegion::ParameterRegion(std::map<VariableType, BoundType> lowerBounds, std::map<VariableType, BoundType> upperBounds) : lowerBounds(lowerBounds), upperBounds(upperBounds) {
// Intentionally left empty.
//todo: check whether both mappings map the same variables
}
template<typename ParametricType, typename ConstantType>
std::set<typename SparseDtmcRegionModelChecker<ParametricType, ConstantType>::VariableType> SparseDtmcRegionModelChecker<ParametricType, ConstantType>::ParameterRegion::getVariables() const{
std::set<VariableType> result;
for(auto const& variableWithBound : lowerBounds) {
result.insert(variableWithBound.first);
}
return result;
}
template<typename ParametricType, typename ConstantType>
typename SparseDtmcRegionModelChecker<ParametricType, ConstantType>::BoundType const& SparseDtmcRegionModelChecker<ParametricType, ConstantType>::ParameterRegion::getLowerBound(VariableType const& variable) const{
auto const& result = lowerBounds.find(variable);
STORM_LOG_THROW(result!=lowerBounds.end(), storm::exceptions::IllegalArgumentException, "tried to find a lower bound of a variable that is not specified by this region");
return (*result).second;
}
template<typename ParametricType, typename ConstantType>
typename SparseDtmcRegionModelChecker<ParametricType, ConstantType>::BoundType const& SparseDtmcRegionModelChecker<ParametricType, ConstantType>::ParameterRegion::getUpperBound(VariableType const& variable) const{
auto const& result = upperBounds.find(variable);
STORM_LOG_THROW(result!=upperBounds.end(), storm::exceptions::IllegalArgumentException, "tried to find an upper bound of a variable that is not specified by this region");
return (*result).second;
}
template<typename ParametricType, typename ConstantType>
std::vector<std::map<typename SparseDtmcRegionModelChecker<ParametricType, ConstantType>::VariableType, typename SparseDtmcRegionModelChecker<ParametricType, ConstantType>::BoundType>> SparseDtmcRegionModelChecker<ParametricType, ConstantType>::ParameterRegion::getVerticesOfRegion(std::set<VariableType> const& consideredVariables) const{
std::size_t const numOfVariables=consideredVariables.size();
std::size_t const numOfVertices=std::pow(2,numOfVariables);
std::vector<std::map<VariableType, BoundType>> resultingVector(numOfVertices,std::map<VariableType, BoundType>());
if(numOfVertices==1){
//no variables are given, the returned vector will still contain an empty map
return resultingVector;
}
for(uint_fast64_t vertexId=0; vertexId<numOfVertices; ++vertexId){
//interprete vertexId as a bit sequence
//the consideredVariables.size() least significant bits of vertex will always represent the next vertex
//(00...0 = lower bounds for all variables, 11...1 = upper bounds for all variables)
std::size_t variableIndex=0;
for(auto const& variable : consideredVariables){
if( (vertexId>>variableIndex)%2==0 ){
resultingVector[vertexId].insert(std::pair<VariableType, BoundType>(variable, getLowerBound(variable)));
}
else{
resultingVector[vertexId].insert(std::pair<VariableType, BoundType>(variable, getUpperBound(variable)));
}
++variableIndex;
}
}
return resultingVector;
}
template<typename ParametricType, typename ConstantType> template<typename ParametricType, typename ConstantType>
SparseDtmcRegionModelChecker<ParametricType, ConstantType>::SparseDtmcRegionModelChecker(storm::models::sparse::Dtmc<ParametricType> const& model) : model(model), eliminationModelChecker(model) { SparseDtmcRegionModelChecker<ParametricType, ConstantType>::SparseDtmcRegionModelChecker(storm::models::sparse::Dtmc<ParametricType> const& model) : model(model), eliminationModelChecker(model) {
// Intentionally left empty. // Intentionally left empty.
@ -275,14 +338,14 @@ namespace storm {
} }
template<> template<>
void SparseDtmcRegionModelChecker<storm::RationalFunction, double>::restrictProbabilityVariables(storm::solver::Smt2SmtSolver& solver, std::vector<storm::RationalFunction::PolyType> const& stateProbVars, storm::storage::BitVector const& subsystem, FlexibleMatrix const& flexibleMatrix, std::vector<storm::RationalFunction> const& oneStepProbabilities, std::vector<ParameterRegion> const& regions, storm::logic::ComparisonType const& compType){
void SparseDtmcRegionModelChecker<storm::RationalFunction, double>::restrictProbabilityVariables(storm::solver::Smt2SmtSolver& solver, std::vector<storm::RationalFunction::PolyType> const& stateProbVars, storm::storage::BitVector const& subsystem, FlexibleMatrix const& flexibleMatrix, std::vector<storm::RationalFunction> const& oneStepProbabilities, ParameterRegion const& region, storm::logic::ComparisonType const& compType){
//We are going to build a new (non parametric) MDP which has an action for the lower bound and an action for the upper bound of every parameter //We are going to build a new (non parametric) MDP which has an action for the lower bound and an action for the upper bound of every parameter
//todo invent something better to obtain the substitutions. //todo invent something better to obtain the substitutions.
//this only works as long as there is only one parameter per state, //this only works as long as there is only one parameter per state,
// also: check whether the terms are linear/monotone(?) // also: check whether the terms are linear/monotone(?)
STORM_LOG_WARN("the probability restriction is experimental.. only works on linear terms with one parameter per state");
STORM_LOG_WARN("the probability restriction only works on linear terms which is not checked");
storm::storage::sparse::state_type const numOfStates=subsystem.getNumberOfSetBits() + 2; //subsystem + target state + sink state storm::storage::sparse::state_type const numOfStates=subsystem.getNumberOfSetBits() + 2; //subsystem + target state + sink state
storm::models::sparse::StateLabeling stateLabeling(numOfStates); storm::models::sparse::StateLabeling stateLabeling(numOfStates);
stateLabeling.addLabel("init", storm::storage::BitVector(numOfStates, true)); stateLabeling.addLabel("init", storm::storage::BitVector(numOfStates, true));
@ -293,19 +356,7 @@ namespace storm {
sinkLabel.set(numOfStates-1, true); sinkLabel.set(numOfStates-1, true);
stateLabeling.addLabel("sink", std::move(sinkLabel)); stateLabeling.addLabel("sink", std::move(sinkLabel));
std::map<storm::Variable, storm::RationalFunction::CoeffType> substitutionLB;
for(auto const& parRegion : regions){
substitutionLB.insert(std::pair<storm::Variable,storm::RationalFunction::CoeffType>(parRegion.variable, parRegion.lowerBound));
}
std::map<storm::Variable, storm::RationalFunction::CoeffType> substitutionUB;
for(auto const& parRegion : regions){
substitutionUB.insert(std::pair<storm::Variable,storm::RationalFunction::CoeffType>(parRegion.variable, parRegion.upperBound));
}
std::vector<std::map<storm::Variable, storm::RationalFunction::CoeffType>> substitutions;
substitutions.push_back(substitutionLB);
substitutions.push_back(substitutionUB);
std::pair<storm::storage::SparseMatrix<double>,std::vector<boost::container::flat_set<uint_fast64_t>>> instantiation = instantiateFlexibleMatrix(flexibleMatrix, substitutions, subsystem, true, oneStepProbabilities, true);
std::pair<storm::storage::SparseMatrix<double>,std::vector<boost::container::flat_set<uint_fast64_t>>> instantiation = instantiateFlexibleMatrix(flexibleMatrix, region.getVerticesOfRegion(region.getVariables()), subsystem, true, oneStepProbabilities, true);
boost::optional<std::vector<double>> noStateRewards; boost::optional<std::vector<double>> noStateRewards;
boost::optional<storm::storage::SparseMatrix<double>> noTransitionRewards; boost::optional<storm::storage::SparseMatrix<double>> noTransitionRewards;
storm::models::sparse::Mdp<double> mdp(instantiation.first, std::move(stateLabeling),noStateRewards,noTransitionRewards,instantiation.second); storm::models::sparse::Mdp<double> mdp(instantiation.first, std::move(stateLabeling),noStateRewards,noTransitionRewards,instantiation.second);
@ -341,22 +392,6 @@ namespace storm {
std::unique_ptr<CheckResult> resultPtr = modelChecker.computeEventuallyProbabilities(eventuallyFormula,false,opType); std::unique_ptr<CheckResult> resultPtr = modelChecker.computeEventuallyProbabilities(eventuallyFormula,false,opType);
std::vector<double> resultVector = resultPtr->asExplicitQuantitativeCheckResult<double>().getValueVector(); std::vector<double> resultVector = resultPtr->asExplicitQuantitativeCheckResult<double>().getValueVector();
//todo this is experimental..
if (true){
std::cout << "the matrix has " << mdp.getTransitionMatrix().getRowGroupCount() << "row groups, " << mdp.getTransitionMatrix().getRowCount() << " rows, and " << mdp.getTransitionMatrix().getColumnCount() << "columns" << std::endl;
boost::container::flat_set< uint_fast64_t> lbChoiceLabel;
lbChoiceLabel.insert(1);
lbChoiceLabel.insert(2);
storm::models::sparse::Dtmc<double> dtmc(mdp.restrictChoiceLabels(lbChoiceLabel).getTransitionMatrix(), std::move(stateLabeling));
//modelchecking on dtmc
storm::modelchecker::SparseDtmcPrctlModelChecker<double> dtmcModelChecker(dtmc);
std::unique_ptr<CheckResult> resultPtrDtmc = dtmcModelChecker.computeEventuallyProbabilities(eventuallyFormula);
std::vector<double> resultVectorDtmc = resultPtrDtmc->asExplicitQuantitativeCheckResult<double>().getValueVector();
std::cout << "dtmc result with lower bounds:" << resultVectorDtmc[0];
std::cout << "mdp result:" << resultVector[0];
}
//formulate constraints for the solver //formulate constraints for the solver
uint_fast64_t boundDenominator = 1.0/storm::settings::generalSettings().getPrecision(); //we need to approx. the obtained bounds as rational numbers uint_fast64_t boundDenominator = 1.0/storm::settings::generalSettings().getPrecision(); //we need to approx. the obtained bounds as rational numbers
storm::storage::sparse::state_type subsystemState=0; //the subsystem uses other state indices storm::storage::sparse::state_type subsystemState=0; //the subsystem uses other state indices
@ -371,12 +406,12 @@ namespace storm {
} }
template<typename ParametricType, typename ConstantType> template<typename ParametricType, typename ConstantType>
void SparseDtmcRegionModelChecker<ParametricType, ConstantType>::restrictProbabilityVariables(storm::solver::Smt2SmtSolver& solver, std::vector<storm::RationalFunction::PolyType> const& stateProbVars, storm::storage::BitVector const& subsystem, FlexibleMatrix const& flexibleMatrix, std::vector<storm::RationalFunction> const& oneStepProbabilities, std::vector<ParameterRegion> const& regions, storm::logic::ComparisonType const& compType){
void SparseDtmcRegionModelChecker<ParametricType, ConstantType>::restrictProbabilityVariables(storm::solver::Smt2SmtSolver& solver, std::vector<storm::RationalFunction::PolyType> const& stateProbVars, storm::storage::BitVector const& subsystem, FlexibleMatrix const& flexibleMatrix, std::vector<storm::RationalFunction> const& oneStepProbabilities, ParameterRegion const& region, storm::logic::ComparisonType const& compType){
STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException, "restricting Probability Variables is not supported for this type"); STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException, "restricting Probability Variables is not supported for this type");
} }
template<> template<>
bool SparseDtmcRegionModelChecker<storm::RationalFunction, double>::checkRegion(storm::logic::Formula const& formula, std::vector<SparseDtmcRegionModelChecker<storm::RationalFunction, double>::ParameterRegion> parameterRegions){
bool SparseDtmcRegionModelChecker<storm::RationalFunction, double>::checkRegion(storm::logic::Formula const& formula, std::vector<ParameterRegion> parameterRegions){
//Note: this is an 'experimental' implementation //Note: this is an 'experimental' implementation
std::chrono::high_resolution_clock::time_point timeStart = std::chrono::high_resolution_clock::now(); std::chrono::high_resolution_clock::time_point timeStart = std::chrono::high_resolution_clock::now();
@ -481,20 +516,22 @@ namespace storm {
//the bounds for the parameters //the bounds for the parameters
solver.push(); solver.push();
for(auto param : parameterRegions){
storm::RawPolynomial lB(param.variable);
lB -= param.lowerBound;
//STORM_LOG_THROW(parameterRegions.size()==1, storm::exceptions::NotImplementedException, "multiple regions not yet implemented");
ParameterRegion region=parameterRegions[0];
for(auto variable : region.getVariables()){
storm::RawPolynomial lB(variable);
lB -= region.getLowerBound(variable);
solver.add(carl::Constraint<storm::RawPolynomial>(lB,storm::CompareRelation::GEQ)); solver.add(carl::Constraint<storm::RawPolynomial>(lB,storm::CompareRelation::GEQ));
storm::RawPolynomial uB(param.variable);
uB -= param.upperBound;
storm::RawPolynomial uB(variable);
uB -= region.getUpperBound(variable);
solver.add(carl::Constraint<storm::RawPolynomial>(uB,storm::CompareRelation::LEQ)); solver.add(carl::Constraint<storm::RawPolynomial>(uB,storm::CompareRelation::LEQ));
} }
std::chrono::high_resolution_clock::time_point timeSmtFormulationEnd = std::chrono::high_resolution_clock::now(); std::chrono::high_resolution_clock::time_point timeSmtFormulationEnd = std::chrono::high_resolution_clock::now();
// find further restriction on probabilities // find further restriction on probabilities
restrictProbabilityVariables(solver,stateProbVars,subsystem,flexibleMatrix,oneStepProbabilities, parameterRegions, storm::logic::ComparisonType::Less); //probOpForm.getComparisonType());
restrictProbabilityVariables(solver,stateProbVars,subsystem,flexibleMatrix,oneStepProbabilities, parameterRegions, storm::logic::ComparisonType::Greater);
restrictProbabilityVariables(solver,stateProbVars,subsystem,flexibleMatrix,oneStepProbabilities, parameterRegions[0], storm::logic::ComparisonType::Less); //probOpForm.getComparisonType());
restrictProbabilityVariables(solver,stateProbVars,subsystem,flexibleMatrix,oneStepProbabilities, parameterRegions[0], storm::logic::ComparisonType::Greater);
std::chrono::high_resolution_clock::time_point timeRestrictingEnd = std::chrono::high_resolution_clock::now(); std::chrono::high_resolution_clock::time_point timeRestrictingEnd = std::chrono::high_resolution_clock::now();
@ -544,7 +581,7 @@ namespace storm {
} }
template<typename ParametricType, typename ConstantType> template<typename ParametricType, typename ConstantType>
bool SparseDtmcRegionModelChecker<ParametricType, ConstantType>::checkRegion(storm::logic::Formula const& formula, std::vector<SparseDtmcRegionModelChecker<ParametricType, ConstantType>::ParameterRegion> parameterRegions){
bool SparseDtmcRegionModelChecker<ParametricType, ConstantType>::checkRegion(storm::logic::Formula const& formula, std::vector<ParameterRegion> parameterRegions){
STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException, "Region check is not supported for this type"); STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException, "Region check is not supported for this type");
} }
@ -553,5 +590,7 @@ namespace storm {
#ifdef STORM_HAVE_CARL #ifdef STORM_HAVE_CARL
template class SparseDtmcRegionModelChecker<storm::RationalFunction, double>; template class SparseDtmcRegionModelChecker<storm::RationalFunction, double>;
#endif #endif
//note: for other template instantiations, add a rule for the typedefs of VariableType and BoundType
} // namespace modelchecker } // namespace modelchecker
} // namespace storm } // namespace storm

44
src/modelchecker/reachability/SparseDtmcRegionModelChecker.h

@ -1,14 +1,13 @@
#ifndef STORM_MODELCHECKER_REACHABILITY_SPARSEDTMCREGIONMODELCHECKER_H_ #ifndef STORM_MODELCHECKER_REACHABILITY_SPARSEDTMCREGIONMODELCHECKER_H_
#define STORM_MODELCHECKER_REACHABILITY_SPARSEDTMCREGIONMODELCHECKER_H_ #define STORM_MODELCHECKER_REACHABILITY_SPARSEDTMCREGIONMODELCHECKER_H_
//TODO remove useless includes
#include <type_traits>
#include "src/storage/sparse/StateType.h" #include "src/storage/sparse/StateType.h"
#include "src/models/sparse/Dtmc.h" #include "src/models/sparse/Dtmc.h"
#include "src/models/sparse/Mdp.h" #include "src/models/sparse/Mdp.h"
//#include "src/modelchecker/AbstractModelChecker.h"
#include "src/utility/constants.h" #include "src/utility/constants.h"
//#include "src/solver/SmtSolver.h"
#include "utility/regions.h"
#include "src/solver/Smt2SmtSolver.h" #include "src/solver/Smt2SmtSolver.h"
#include "SparseDtmcEliminationModelChecker.h" #include "SparseDtmcEliminationModelChecker.h"
@ -18,24 +17,45 @@ namespace storm {
template<typename ParametricType, typename ConstantType> template<typename ParametricType, typename ConstantType>
class SparseDtmcRegionModelChecker { class SparseDtmcRegionModelChecker {
public: public:
explicit SparseDtmcRegionModelChecker(storm::models::sparse::Dtmc<ParametricType> const& model);
virtual bool canHandle(storm::logic::Formula const& formula) const;
//The type of variables and bounds depends on the template arguments
typedef typename std::conditional<(std::is_same<ParametricType,storm::RationalFunction>::value), storm::Variable,std::nullptr_t>::type VariableType;
typedef typename std::conditional<(std::is_same<ParametricType,storm::RationalFunction>::value), storm::RationalFunction::CoeffType,std::nullptr_t>::type BoundType;
class ParameterRegion{
public:
ParameterRegion(std::map<VariableType, BoundType> lowerBounds, std::map<VariableType, BoundType> upperBounds);
std::set<VariableType> getVariables() const;
BoundType const& getLowerBound(VariableType const& variable) const;
BoundType const& getUpperBound(VariableType const& variable) const;
/*
* Returns a vector of all possible combinations of lower and upper bounds of the given variables.
* The first entry of the returned vector will map every variable to its lower bound
* The second entry will map every variable to its lower bound, except the first one (i.e. *consVariables.begin())
* ...
* The last entry will map every variable to its upper bound
*/
std::vector<std::map<VariableType, BoundType>> getVerticesOfRegion(std::set<VariableType> const& consideredVariables) const;
private:
std::map<VariableType, BoundType> const lowerBounds;
std::map<VariableType, BoundType> const upperBounds;
#ifdef STORM_HAVE_CARL
struct ParameterRegion{
storm::Variable variable;
storm::RationalFunction::CoeffType lowerBound;
storm::RationalFunction::CoeffType upperBound;
}; };
explicit SparseDtmcRegionModelChecker(storm::models::sparse::Dtmc<ParametricType> const& model);
virtual bool canHandle(storm::logic::Formula const& formula) const;
/*! /*!
* Checks whether the given formula holds for all possible parameters that satisfy the given parameter regions * Checks whether the given formula holds for all possible parameters that satisfy the given parameter regions
* ParameterRegions should contain all parameters (not mentioned parameters are assumed to be arbitrary reals) * ParameterRegions should contain all parameters (not mentioned parameters are assumed to be arbitrary reals)
*/ */
bool checkRegion(storm::logic::Formula const& formula, std::vector<ParameterRegion> parameterRegions); bool checkRegion(storm::logic::Formula const& formula, std::vector<ParameterRegion> parameterRegions);
#endif
private: private:
typedef typename storm::modelchecker::SparseDtmcEliminationModelChecker<ParametricType>::FlexibleSparseMatrix FlexibleMatrix; typedef typename storm::modelchecker::SparseDtmcEliminationModelChecker<ParametricType>::FlexibleSparseMatrix FlexibleMatrix;
@ -67,7 +87,7 @@ namespace storm {
void formulateModelWithSMT(storm::solver::Smt2SmtSolver& solver, std::vector<storm::RationalFunction::PolyType>& stateProbVars, storm::storage::BitVector const& subsystem, FlexibleMatrix const& flexibleMatrix, std::vector<storm::RationalFunction> const& oneStepProbabilities); void formulateModelWithSMT(storm::solver::Smt2SmtSolver& solver, std::vector<storm::RationalFunction::PolyType>& stateProbVars, storm::storage::BitVector const& subsystem, FlexibleMatrix const& flexibleMatrix, std::vector<storm::RationalFunction> const& oneStepProbabilities);
void restrictProbabilityVariables(storm::solver::Smt2SmtSolver& solver, std::vector<storm::RationalFunction::PolyType> const& stateProbVars, storm::storage::BitVector const& subsystem, FlexibleMatrix const& flexibleMatrix, std::vector<storm::RationalFunction> const& oneStepProbabilities, std::vector<ParameterRegion> const& regions, storm::logic::ComparisonType const& compTypeOfProperty);
void restrictProbabilityVariables(storm::solver::Smt2SmtSolver& solver, std::vector<storm::RationalFunction::PolyType> const& stateProbVars, storm::storage::BitVector const& subsystem, FlexibleMatrix const& flexibleMatrix, std::vector<storm::RationalFunction> const& oneStepProbabilities, ParameterRegion const& region, storm::logic::ComparisonType const& compTypeOfProperty);
#endif #endif

17
src/utility/cli.h

@ -7,6 +7,7 @@
#include <cstdio> #include <cstdio>
#include <sstream> #include <sstream>
#include <memory> #include <memory>
#include <map>
#include "storm-config.h" #include "storm-config.h"
// Includes for the linked libraries and versions header. // Includes for the linked libraries and versions header.
@ -66,6 +67,7 @@ log4cplus::Logger printer;
#include "src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h" #include "src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h"
#include "src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h" #include "src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h"
#include "src/modelchecker/reachability/SparseDtmcRegionModelChecker.h" #include "src/modelchecker/reachability/SparseDtmcRegionModelChecker.h"
#include "src/utility/regions.h"
#include "src/modelchecker/prctl/SparseMdpPrctlModelChecker.h" #include "src/modelchecker/prctl/SparseMdpPrctlModelChecker.h"
#include "src/modelchecker/csl/SparseCtmcCslModelChecker.h" #include "src/modelchecker/csl/SparseCtmcCslModelChecker.h"
#include "src/modelchecker/prctl/HybridDtmcPrctlModelChecker.h" #include "src/modelchecker/prctl/HybridDtmcPrctlModelChecker.h"
@ -476,19 +478,8 @@ namespace storm {
if(settings.isParametricRegionSet()){ if(settings.isParametricRegionSet()){
std::cout << std::endl; std::cout << std::endl;
//experimental implementation! check some hardcoded region //experimental implementation! check some hardcoded region
std::vector<storm::modelchecker::SparseDtmcRegionModelChecker<storm::RationalFunction, double>::ParameterRegion> regions;
storm::RationalFunction::CoeffType zeroPointOne(1);
zeroPointOne = zeroPointOne/10;
storm::modelchecker::SparseDtmcRegionModelChecker<storm::RationalFunction, double>::ParameterRegion param1;
param1.lowerBound= zeroPointOne*zeroPointOne*78;
param1.upperBound= zeroPointOne*zeroPointOne*82;
param1.variable=carl::VariablePool::getInstance().findVariableWithName("pL");
regions.push_back(param1);
storm::modelchecker::SparseDtmcRegionModelChecker<storm::RationalFunction, double>::ParameterRegion param2;
param2.lowerBound= zeroPointOne*zeroPointOne*78;
param2.upperBound= zeroPointOne*zeroPointOne*82;;
param2.variable=carl::VariablePool::getInstance().findVariableWithName("pK");
regions.push_back(param2);
std::vector<storm::modelchecker::SparseDtmcRegionModelChecker<storm::RationalFunction,double>::ParameterRegion> regions=storm::utility::regions::RegionParser<storm::RationalFunction, double>::parseMultipleRegions("0.78<=pL<=0.82,0.78<=pK<=0.82; 0.3<=pL<=0.5,0.1<=pK<=0.7;0.6<=pL<=0.7,0.8<=pK<=0.9");
storm::modelchecker::SparseDtmcRegionModelChecker<storm::RationalFunction, double> modelchecker(*dtmc); storm::modelchecker::SparseDtmcRegionModelChecker<storm::RationalFunction, double> modelchecker(*dtmc);
bool result = modelchecker.checkRegion(*formula.get(), regions); bool result = modelchecker.checkRegion(*formula.get(), regions);

142
src/utility/regions.cpp

@ -0,0 +1,142 @@
/*
* File: Regions.cpp
* Author: Tim Quatmann
*
* Created on May 13, 2015, 12:54 PM
*/
#include <string>
#include "src/utility/regions.h"
#include "src/exceptions/NotImplementedException.h"
#include "src/exceptions/InvalidArgumentException.h"
#include "adapters/CarlAdapter.h"
namespace storm {
namespace utility{
namespace regions {
template<typename ParametricType, typename ConstantType>
void RegionParser<ParametricType, ConstantType>::parseParameterBounds(
std::map<VariableType, BoundType>& lowerBounds,
std::map<VariableType, BoundType>& upperBounds,
std::string const& parameterBoundsString,
double const precision){
double actualPrecision = (precision==0.0 ? storm::settings::generalSettings().getPrecision() : precision);
std::string::size_type positionOfFirstRelation = parameterBoundsString.find("<=");
STORM_LOG_THROW(positionOfFirstRelation!=std::string::npos, storm::exceptions::InvalidArgumentException, "When parsing the region" << parameterBoundsString << " I could not find a '<=' after the first number");
std::string::size_type positionOfSecondRelation = parameterBoundsString.find("<=", positionOfFirstRelation+2);
STORM_LOG_THROW(positionOfSecondRelation!=std::string::npos, storm::exceptions::InvalidArgumentException, "When parsing the region" << parameterBoundsString << " I could not find a '<=' after the parameter");
std::string parameter=parameterBoundsString.substr(positionOfFirstRelation+2,positionOfSecondRelation-(positionOfFirstRelation+2));
//removes all whitespaces from the parameter string:
parameter.erase(std::remove_if(parameter.begin(), parameter.end(), isspace), parameter.end());
STORM_LOG_THROW(parameter.length()>0, storm::exceptions::InvalidArgumentException, "When parsing the region" << parameterBoundsString << " I could not find a parameter");
double lowerBound, upperBound;
try{
lowerBound=std::stod(parameterBoundsString.substr(0,positionOfFirstRelation));
upperBound=std::stod(parameterBoundsString.substr(positionOfSecondRelation+2));
}
catch (std::exception const& exception) {
STORM_LOG_ERROR("Failed to parse the region: " << parameterBoundsString << ". The correct format for regions is lowerBound<=parameter<=upperbound");
throw exception;
}
VariableType var = getVariableFromString<VariableType>(parameter);
BoundType lb = convertNumber<double, BoundType>(lowerBound, true, actualPrecision);
BoundType ub = convertNumber<double, BoundType>(upperBound, false, actualPrecision);
lowerBounds.emplace(std::make_pair(var, lb));
upperBounds.emplace(std::make_pair(var, ub));
std::cout << "parsed bounds " << parameterBoundsString << ": lb=" << lowerBound << " ub=" << upperBound << " param='" << parameter << "' precision=" << actualPrecision << std::endl;
}
template<typename ParametricType, typename ConstantType>
typename RegionParser<ParametricType, ConstantType>::ParameterRegion RegionParser<ParametricType, ConstantType>::parseRegion(std::string const& regionString, double precision){
double actualPrecision = (precision==0.0 ? storm::settings::generalSettings().getPrecision() : precision);
std::map<VariableType, BoundType> lowerBounds;
std::map<VariableType, BoundType> upperBounds;
std::vector<std::string> parameterBounds;
boost::split(parameterBounds, regionString, boost::is_any_of(","));
for(auto const& parameterBound : parameterBounds){
std::cout << "parsing a parameter bound" << std::endl;
RegionParser<ParametricType, ConstantType>::parseParameterBounds(lowerBounds, upperBounds, parameterBound, actualPrecision);
std::cout << "created a parameter bound. lower bound has size" << lowerBounds.size() << std::endl;
std::cout << "parsing a param bound is done" << std::endl;
}
return ParameterRegion(lowerBounds, upperBounds);
}
template<typename ParametricType, typename ConstantType>
std::vector<typename RegionParser<ParametricType, ConstantType>::ParameterRegion> RegionParser<ParametricType, ConstantType>::parseMultipleRegions(std::string const& regionsString, double precision){
double actualPrecision = (precision==0.0 ? storm::settings::generalSettings().getPrecision() : precision);
std::vector<ParameterRegion> result;
std::vector<std::string> regionsStrVec;
boost::split(regionsStrVec, regionsString, boost::is_any_of(";"));
for(auto const& regionStr : regionsStrVec){
std::cout << "parsing a region" << std::endl;
result.emplace_back(RegionParser<ParametricType, ConstantType>::parseRegion(regionStr, actualPrecision));
std::cout << "parsing a region is done" << std::endl;
}
return result;
}
template<>
storm::RationalFunction::CoeffType convertNumber<double, storm::RationalFunction::CoeffType>(double const& number, bool const& roundDown, double const& precision){
double actualPrecision = (precision==0.0 ? storm::settings::generalSettings().getPrecision() : precision);
uint_fast64_t denominator = 1.0/actualPrecision;
uint_fast64_t numerator;
if(roundDown){
numerator= number*denominator; //this will always round down if necessary
} else{
numerator = number*denominator*10; //*10 to look whether we have to round up
if(numerator%10>0){
numerator+=10;
}
numerator/=10;
}
storm::RationalFunction::CoeffType result=numerator;
result = result/denominator;
return result;
}
template<>
storm::RationalFunction convertNumber<double, storm::RationalFunction>(double const& number, bool const& roundDown, double const& precision){
return storm::RationalFunction(convertNumber<double, storm::RationalFunction::CoeffType>(number, roundDown, precision));
}
template<>
double convertNumber<cln::cl_RA, double>(cln::cl_RA const& number, bool const& roundDown, double const& precision){
return cln::double_approx(number);
}
template<typename SourceType, typename TargetType>
TargetType convertNumber(SourceType const& number, bool const& roundDown, double const& precision){
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "number conversion between the given types not implemented");
}
template<>
storm::Variable getVariableFromString<storm::Variable>(std::string variableString){
storm::Variable const& var = carl::VariablePool::getInstance().findVariableWithName(variableString);
STORM_LOG_THROW(var!=carl::Variable::NO_VARIABLE, storm::exceptions::InvalidArgumentException, "Variable '" + variableString + "' could not be found.");
return var;
}
template<typename VariableType>
VariableType getVariableFromString(std::string variableString){
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Variable from String not implemented for this Type");
}
//explicit instantiations
#ifdef STORM_HAVE_CARL
template class RegionParser<storm::RationalFunction, double>;
template storm::RationalFunction convertNumber<double, storm::RationalFunction>(double const& number, bool const& roundDown, double const& precision);
template storm::RationalFunction::CoeffType convertNumber<double, storm::RationalFunction::CoeffType>(double const& number, bool const& roundDown, double const& precision);
template double convertNumber<cln::cl_RA, double>(storm::RationalFunction::CoeffType const& number, bool const& roundDown, double const& precision);
template storm::Variable getVariableFromString<storm::Variable>(std::string variableString);
#endif
}
}
}

90
src/utility/regions.h

@ -0,0 +1,90 @@
/*
* File: Regions.h
* Author: Tim Quatmann
*
* Created on May 13, 2015, 12:54 PM
*/
#include "src/modelchecker/reachability/SparseDtmcRegionModelChecker.h" //to get the ParameterRegion type
#ifndef STORM_UTILITY_REGIONS_H
#define STORM_UTILITY_REGIONS_H
// Forward-declare region modelchecker class.
namespace storm {
namespace modelchecker{
template<typename ParametricType, typename ConstantType>
class SparseDtmcRegionModelChecker;
}
}
namespace storm {
namespace utility{
namespace regions {
template<typename ParametricType, typename ConstantType>
class RegionParser{
public:
typedef typename storm::modelchecker::SparseDtmcRegionModelChecker<ParametricType,ConstantType>::ParameterRegion ParameterRegion;
typedef typename storm::modelchecker::SparseDtmcRegionModelChecker<ParametricType,ConstantType>::VariableType VariableType;
typedef typename storm::modelchecker::SparseDtmcRegionModelChecker<ParametricType,ConstantType>::BoundType BoundType;
/*
* Can be used to parse a single parameter with its bounds from a string of the form "0.3<=p<=0.5".
* The numbers are parsed as doubles and then converted to SparseDtmcRegionModelChecker::Boundtype.
* According to the given precision, the lower bound may be rounded down and the upper bound may be rounded up.
* If no precision is given, the one from the settings is used.
* The results will be inserted in the given maps
*
*/
static void parseParameterBounds(
std::map<VariableType, BoundType>& lowerBounds,
std::map<VariableType, BoundType>& upperBounds,
std::string const& parameterBoundsString,
double const precision=0.0
);
/*
* Can be used to parse a single region from a string of the form "0.3<=p<=0.5,0.4<=q<=0.7".
* The numbers are parsed as doubles and then converted to SparseDtmcRegionModelChecker::Boundtype.
* According to the given precision, the lower bound may be rounded down and the upper bound may be rounded up.
* If no precision is given, the one from the settings is used.
*
*/
static ParameterRegion parseRegion(
std::string const& regionString,
double precision=0.0);
/*
* Can be used to parse a vector of region from a string of the form "0.3<=p<=0.5,0.4<=q<=0.7;0.1<=p<=0.3,0.2<=q<=0.4".
* The numbers are parsed as doubles and then converted to SparseDtmcRegionModelChecker::Boundtype.
* According to the given precision, the lower bound may be rounded down and the upper bound may be rounded up.
* If no precision is given, the one from the settings is used.
*
*/
static std::vector<ParameterRegion> parseMultipleRegions(
std::string const& regionsString,
double precision=0.0);
};
/*
* Converts a number from one type to a number from the other.
* If no exact conversion is possible, the number is rounded up or down, using the given precision or the one from the settings.
*/
template<typename SourceType, typename TargetType>
TargetType convertNumber(SourceType const& number, bool const& roundDown=true, double const& precision=0.0);
/*
* retrieves the variable object from the given string
* Throws an exception if variable not found
*/
template<typename VariableType>
VariableType getVariableFromString(std::string variableString);
}
}
}
#endif /* STORM_UTILITY_REGIONS_H */
Loading…
Cancel
Save