Browse Source
moved the regionCheckResult, started to implement class for parameterLifting interface
tempestpy_adaptions
moved the regionCheckResult, started to implement class for parameterLifting interface
tempestpy_adaptions
TimQu
8 years ago
15 changed files with 583 additions and 365 deletions
-
187src/storm/modelchecker/parametric/ParameterLifting.cpp
-
64src/storm/modelchecker/parametric/ParameterLifting.h
-
22src/storm/modelchecker/parametric/RegionCheckResult.cpp
-
24src/storm/modelchecker/parametric/RegionCheckResult.h
-
4src/storm/modelchecker/parametric/SparseDtmcParameterLiftingModelChecker.cpp
-
4src/storm/modelchecker/parametric/SparseDtmcParameterLiftingModelChecker.h
-
4src/storm/modelchecker/parametric/SparseMdpParameterLiftingModelChecker.cpp
-
4src/storm/modelchecker/parametric/SparseMdpParameterLiftingModelChecker.h
-
2src/storm/modelchecker/parametric/SparseParameterLiftingModelChecker.cpp
-
6src/storm/modelchecker/parametric/SparseParameterLiftingModelChecker.h
-
34src/storm/modelchecker/region/RegionCheckResult.h
-
388src/storm/storage/ParameterRegion.cpp
-
193src/storm/storage/ParameterRegion.h
-
6src/storm/transformer/ParameterLifter.cpp
-
6src/storm/transformer/ParameterLifter.h
@ -0,0 +1,187 @@ |
|||
#include "storm/modelchecker/parametric/ParameterLifting.h"
|
|||
|
|||
#include "storm/adapters/CarlAdapter.h"
|
|||
|
|||
#include "storm/modelchecker/parametric/SparseDtmcParameterLiftingModelChecker.h"
|
|||
#include "storm/modelchecker/parametric/SparseDtmcInstantiationModelChecker.h"
|
|||
#include "storm/modelchecker/parametric/SparseMdpParameterLiftingModelChecker.h"
|
|||
#include "storm/modelchecker/parametric/SparseMdpInstantiationModelChecker.h"
|
|||
#include "storm/transformer/SparseParametricDtmcSimplifier.h"
|
|||
#include "storm/transformer/SparseParametricMdpSimplifier.h"
|
|||
#include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h"
|
|||
|
|||
#include "storm/models/sparse/StandardRewardModel.h"
|
|||
#include "storm/models/sparse/Dtmc.h"
|
|||
#include "storm/models/sparse/Mdp.h"
|
|||
|
|||
#include "storm/exceptions/NotSupportedException.h"
|
|||
#include "storm/exceptions/InvalidStateException.h"
|
|||
|
|||
namespace storm { |
|||
namespace modelchecker { |
|||
namespace parametric { |
|||
|
|||
|
|||
template <typename SparseModelType, typename ConstantType> |
|||
ParameterLifting<SparseModelType, ConstantType>::ParameterLifting(SparseModelType const& parametricModel) : parametricModel(parametricModel){ |
|||
STORM_LOG_THROW(parametricModel.getInitialStates().getNumberOfSetBits() == 1, storm::exceptions::NotSupportedException, "Parameter lifting requires models with only one initial state"); |
|||
} |
|||
|
|||
template <typename SparseModelType, typename ConstantType> |
|||
void ParameterLifting<SparseModelType, ConstantType>::specifyFormula(CheckTask<storm::logic::Formula, typename SparseModelType::ValueType> const& checkTask) { |
|||
STORM_LOG_THROW(checkTask.isBoundSet(), storm::exceptions::NotSupportedException, "Parameter lifting requires a bounded property."); |
|||
STORM_LOG_THROW(parameterLiftingChecker->canHandle(checkTask), storm::exceptions::NotSupportedException, "Parameter lifting is not supported for this property."); |
|||
|
|||
simplifyParametricModel(checkTask); |
|||
initializeUnderlyingCheckers(); |
|||
currentCheckTask = std::make_unique<storm::modelchecker::CheckTask<storm::logic::Formula, typename SparseModelType::ValueType>>(checkTask.substituteFormula(*currentFormula)); |
|||
|
|||
instantiationChecker->specifyFormula(*currentCheckTask); |
|||
parameterLiftingChecker->specifyFormula(*currentCheckTask); |
|||
} |
|||
|
|||
template <typename SparseModelType, typename ConstantType> |
|||
RegionCheckResult ParameterLifting<SparseModelType, ConstantType>::analyzeRegion(storm::storage::ParameterRegion<typename SparseModelType::ValueType> const& region, bool sampleVerticesOfRegion) const { |
|||
// First sample for one point to decide whether we should try to prove AllSat or AllViolated
|
|||
if(instantiationChecker->check(region.getCenterPoint())->asExplicitQualitativeCheckResult()[*getConsideredParametricModel().getInitialStates().begin()]) { |
|||
// try to prove AllSat
|
|||
if(parameterLiftingChecker->check(region, this->currentCheckTask->getOptimizationDirection())->asExplicitQualitativeCheckResult()[*getConsideredParametricModel().getInitialStates().begin()]) { |
|||
return RegionCheckResult::AllSat; |
|||
} else if (sampleVerticesOfRegion) { |
|||
// Check if there is a point in the region for which the property is violated
|
|||
auto vertices = region.getVerticesOfRegion(region.getVariables()); |
|||
for (auto const& v : vertices) { |
|||
if (!instantiationChecker->check(v)->asExplicitQualitativeCheckResult()[*getConsideredParametricModel().getInitialStates().begin()]) { |
|||
return RegionCheckResult::ExistsBoth; |
|||
} |
|||
} |
|||
} |
|||
// Reaching this point means that we only know that there is (at least) one point in the region for which the property is satisfied
|
|||
return RegionCheckResult::ExistsSat; |
|||
} else { |
|||
// try to prove AllViolated
|
|||
if(!parameterLiftingChecker->check(region, storm::solver::invert(this->currentCheckTask->getOptimizationDirection()))->asExplicitQualitativeCheckResult()[*getConsideredParametricModel().getInitialStates().begin()]) { |
|||
return RegionCheckResult::AllViolated; |
|||
} else if (sampleVerticesOfRegion) { |
|||
// Check if there is a point in the region for which the property is satisfied
|
|||
auto vertices = region.getVerticesOfRegion(region.getVariables()); |
|||
for (auto const& v : vertices) { |
|||
if (instantiationChecker->check(v)->asExplicitQualitativeCheckResult()[*getConsideredParametricModel().getInitialStates().begin()]) { |
|||
return RegionCheckResult::ExistsBoth; |
|||
} |
|||
} |
|||
} |
|||
// Reaching this point means that we only know that there is (at least) one point in the region for which the property is violated
|
|||
return RegionCheckResult::ExistsViolated; |
|||
} |
|||
} |
|||
|
|||
template <typename SparseModelType, typename ConstantType> |
|||
std::vector<std::pair<storm::storage::ParameterRegion<typename SparseModelType::ValueType>, RegionCheckResult>> ParameterLifting<SparseModelType, ConstantType>::performRegionRefinement(storm::storage::ParameterRegion<typename SparseModelType::ValueType> const& region, typename storm::storage::ParameterRegion<typename SparseModelType::ValueType>::CoefficientType const& threshold) const { |
|||
STORM_LOG_INFO("Applying refinement on region: " << region.toString(true) << " ."); |
|||
|
|||
auto areaOfParameterSpace = region.area(); |
|||
auto fractionOfUndiscoveredArea = storm::utility::one<typename storm::storage::ParameterRegion<typename SparseModelType::ValueType>::CoefficientType>(); |
|||
auto fractionOfAllSatArea = storm::utility::zero<typename storm::storage::ParameterRegion<typename SparseModelType::ValueType>::CoefficientType>(); |
|||
auto fractionOfAllViolatedArea = storm::utility::zero<typename storm::storage::ParameterRegion<typename SparseModelType::ValueType>::CoefficientType>(); |
|||
|
|||
std::vector<std::pair<storm::storage::ParameterRegion<typename SparseModelType::ValueType>, RegionCheckResult>> regions; |
|||
regions.emplace_back(region, RegionCheckResult::Unknown); |
|||
storm::storage::BitVector resultRegions(1, true); |
|||
uint_fast64_t indexOfCurrentRegion = 0; |
|||
|
|||
while (fractionOfUndiscoveredArea > threshold) { |
|||
STORM_LOG_THROW(indexOfCurrentRegion < regions.size(), storm::exceptions::InvalidStateException, "Threshold for undiscovered area not reached but no unprocessed regions left."); |
|||
auto & currentRegion = regions[indexOfCurrentRegion]; |
|||
RegionCheckResult res = analyzeRegion(currentRegion.first, currentRegion.second, false); |
|||
switch (res) { |
|||
case RegionCheckResult::AllSat: |
|||
fractionOfUndiscoveredArea -= currentRegion.area() / areaOfParameterSpace; |
|||
fractionOfAllSatArea += currentRegion.area() / areaOfParameterSpace; |
|||
break; |
|||
case RegionCheckResult::AllViolated: |
|||
fractionOfUndiscoveredArea -= currentRegion.area() / areaOfParameterSpace; |
|||
fractionOfAllViolatedArea += currentRegion.area() / areaOfParameterSpace; |
|||
break; |
|||
default: |
|||
uint_fast64_t oldNumOfRegions = regions.size(); |
|||
std::vector<storm::storage::ParameterRegion<typename SparseModelType::ValueType>> newRegions; |
|||
currentRegion.split(currentRegion.getCenterPoint(), regions); |
|||
resultRegions.grow(regions.size()); |
|||
resultRegions.set(resultRegions.begin() + oldNumOfRegions-1?, resultRegions.begin() + regions.size()-1? ); |
|||
resultRegions.set(indexOfCurrentRegion, false); |
|||
break; |
|||
} |
|||
++indexOfCurrentRegion; |
|||
} |
|||
std::cout << " done! " << std::endl << "Fraction of ALLSAT;ALLVIOLATED;UNDISCOVERED area:" << std::endl; |
|||
std::cout << "REFINEMENTRESULT;" <<storm::utility::convertNumber<double>(fractionOfAllSatArea) << ";" << storm::utility::convertNumber<double>(fractionOfAllViolatedArea) << ";" << storm::utility::convertNumber<double>(fractionOfUndiscoveredArea) << std::endl; |
|||
|
|||
() |
|||
return ; |
|||
} |
|||
|
|||
template <typename SparseModelType, typename ConstantType> |
|||
SparseParameterLiftingModelChecker<SparseModelType, ConstantType> const& ParameterLifting<SparseModelType, ConstantType>::getParameterLiftingChecker() const { |
|||
return *parameterLiftingChecker; |
|||
} |
|||
|
|||
template <typename SparseModelType, typename ConstantType> |
|||
SparseInstantiationModelChecker<SparseModelType, ConstantType> const& ParameterLifting<SparseModelType, ConstantType>::getInstantiationChecker() const { |
|||
return *instantiationChecker; |
|||
} |
|||
|
|||
template <typename SparseModelType, typename ConstantType> |
|||
SparseModelType const& ParameterLifting<SparseModelType, ConstantType>::getConsideredParametricModel() const { |
|||
if (simplifiedModel) { |
|||
return *simplifiedModel; |
|||
} else { |
|||
return parametricModel; |
|||
} |
|||
} |
|||
|
|||
template <> |
|||
void ParameterLifting<storm::models::sparse::Dtmc<storm::RationalFunction>, double>::initializeUnderlyingCheckers() { |
|||
parameterLiftingChecker = std::make_unique<SparseDtmcParameterLiftingModelChecker<storm::models::sparse::Dtmc<storm::RationalFunction>, double>>(getConsideredParametricModel()); |
|||
instantiationChecker = std::make_unique<SparseDtmcInstantiationModelChecker<storm::models::sparse::Dtmc<storm::RationalFunction>, double>>(getConsideredParametricModel()); |
|||
} |
|||
|
|||
template <> |
|||
void ParameterLifting<storm::models::sparse::Mdp<storm::RationalFunction>, double>::initializeUnderlyingCheckers() { |
|||
parameterLiftingChecker = std::make_unique<SparseMdpParameterLiftingModelChecker<storm::models::sparse::Mdp<storm::RationalFunction>, double>>(getConsideredParametricModel()); |
|||
instantiationChecker = std::make_unique<SparseMdpInstantiationModelChecker<storm::models::sparse::Mdp<storm::RationalFunction>, double>>(getConsideredParametricModel()); |
|||
} |
|||
|
|||
template <> |
|||
void ParameterLifting<storm::models::sparse::Dtmc<storm::RationalFunction>, double>::simplifyParametricModel(CheckTask<logic::Formula, storm::RationalFunction> const& checkTask) { |
|||
storm::transformer::SparseParametricDtmcSimplifier<storm::models::sparse::Dtmc<storm::RationalFunction>> simplifier(parametricModel); |
|||
if(simplifier.simplify(checkTask.getFormula())) { |
|||
simplifiedModel = simplifier.getSimplifiedModel(); |
|||
currentFormula = simplifier.getSimplifiedFormula(); |
|||
} else { |
|||
simplifiedModel = nullptr; |
|||
currentFormula = checkTask.getFormula().asSharedPointer(); |
|||
} |
|||
} |
|||
|
|||
template <> |
|||
void ParameterLifting<storm::models::sparse::Mdp<storm::RationalFunction>, double>::simplifyParametricModel(CheckTask<logic::Formula, storm::RationalFunction> const& checkTask) { |
|||
storm::transformer::SparseParametricMdpSimplifier<storm::models::sparse::Mdp<storm::RationalFunction>> simplifier(parametricModel); |
|||
if(simplifier.simplify(checkTask.getFormula())) { |
|||
simplifiedModel = simplifier.getSimplifiedModel(); |
|||
currentFormula = simplifier.getSimplifiedFormula(); |
|||
} else { |
|||
simplifiedModel = nullptr; |
|||
currentFormula = checkTask.getFormula().asSharedPointer(); |
|||
} |
|||
} |
|||
|
|||
|
|||
#ifdef STORM_HAVE_CARL
|
|||
template class ParameterLifting<storm::models::sparse::Dtmc<storm::RationalFunction>, double>; |
|||
template class ParameterLifting<storm::models::sparse::Mdp<storm::RationalFunction>, double>; |
|||
#endif
|
|||
} // namespace parametric
|
|||
} //namespace modelchecker
|
|||
} //namespace storm
|
|||
|
@ -0,0 +1,64 @@ |
|||
#pragma once |
|||
|
|||
#include <memory> |
|||
|
|||
#include "storm/modelchecker/parametric/RegionCheckResult.h" |
|||
#include "storm/modelchecker/parametric/SparseInstantiationModelChecker.h" |
|||
#include "storm/modelchecker/parametric/SparseParameterLiftingModelChecker.h" |
|||
#include "storm/storage/ParameterRegion.h" |
|||
|
|||
#include "storm/modelchecker/CheckTask.h" |
|||
|
|||
namespace storm { |
|||
namespace modelchecker{ |
|||
namespace parametric{ |
|||
|
|||
template<typename SparseModelType, typename ConstantType> |
|||
class ParameterLifting { |
|||
|
|||
public: |
|||
|
|||
ParameterLifting(SparseModelType const& parametricModel); |
|||
|
|||
~ParameterLifting() = default; |
|||
|
|||
void specifyFormula(CheckTask<storm::logic::Formula, typename SparseModelType::ValueType> const& checkTask); |
|||
|
|||
/*! |
|||
* Analyzes the given region by applying parameter lifting. |
|||
* We first check whether all points in the region violate/satisfy the property |
|||
* If this does not yield a conclusive result and if the given flag is true, we also sample the vertices of the region |
|||
*/ |
|||
RegionCheckResult analyzeRegion(storm::storage::ParameterRegion<typename SparseModelType::ValueType> const& region, bool sampleVerticesOfRegion) const; |
|||
|
|||
/*! |
|||
* Iteratively refines the region until parameter lifting yields a conclusive result (AllSat or AllViolated). |
|||
* The refinement stops as soon as the fraction of the area of the subregions with inconclusive result is less then the given threshold |
|||
*/ |
|||
std::vector<std::pair<storm::storage::ParameterRegion<typename SparseModelType::ValueType>, RegionCheckResult>> performRegionRefinement(storm::storage::ParameterRegion<typename SparseModelType::ValueType> const& region, typename storm::storage::ParameterRegion<typename SparseModelType::ValueType>::CoefficientType const& threshold) const; |
|||
|
|||
SparseParameterLiftingModelChecker<SparseModelType, ConstantType> const& getParameterLiftingChecker() const; |
|||
SparseInstantiationModelChecker<SparseModelType, ConstantType> const& getInstantiationChecker() const; |
|||
|
|||
private: |
|||
SparseModelType const& getConsideredParametricModel() const; |
|||
|
|||
void initializeUnderlyingCheckers(); |
|||
void simplifyParametricModel(CheckTask<storm::logic::Formula, typename SparseModelType::ValueType> const& checkTask); |
|||
|
|||
|
|||
SparseModelType const& parametricModel; |
|||
std::unique_ptr<CheckTask<storm::logic::Formula, typename SparseModelType::ValueType>> currentCheckTask; |
|||
std::shared_ptr<storm::logic::Formula const> currentFormula; |
|||
std::shared_ptr<SparseModelType> simplifiedModel; |
|||
|
|||
|
|||
std::unique_ptr<SparseParameterLiftingModelChecker<SparseModelType, ConstantType>> parameterLiftingChecker; |
|||
std::unique_ptr<SparseInstantiationModelChecker<SparseModelType, ConstantType>> instantiationChecker; |
|||
|
|||
|
|||
}; |
|||
|
|||
} //namespace parametric |
|||
} //namespace modelchecker |
|||
} //namespace storm |
@ -1,35 +1,29 @@ |
|||
/*
|
|||
* File: RegionCheckResult.cpp |
|||
* Author: tim |
|||
* |
|||
* Created on September 9, 2015, 1:56 PM |
|||
*/ |
|||
#include "storm/modelchecker/parametric/RegionCheckResult.h"
|
|||
|
|||
#include "RegionCheckResult.h"
|
|||
#include "storm/utility/macros.h"
|
|||
#include "storm/exceptions/NotImplementedException.h"
|
|||
|
|||
namespace storm { |
|||
namespace modelchecker { |
|||
namespace region { |
|||
namespace parametric { |
|||
std::ostream& operator<<(std::ostream& os, RegionCheckResult const& regionCheckResult) { |
|||
switch (regionCheckResult) { |
|||
case RegionCheckResult::UNKNOWN: |
|||
case RegionCheckResult::Unknown: |
|||
os << "Unknown"; |
|||
break; |
|||
case RegionCheckResult::EXISTSSAT: |
|||
case RegionCheckResult::ExistsSat: |
|||
os << "ExistsSat"; |
|||
break; |
|||
case RegionCheckResult::EXISTSVIOLATED: |
|||
case RegionCheckResult::ExistsViolated: |
|||
os << "ExistsViolated"; |
|||
break; |
|||
case RegionCheckResult::EXISTSBOTH: |
|||
case RegionCheckResult::ExistsBoth: |
|||
os << "ExistsBoth"; |
|||
break; |
|||
case RegionCheckResult::ALLSAT: |
|||
case RegionCheckResult::AllSat: |
|||
os << "AllSat"; |
|||
break; |
|||
case RegionCheckResult::ALLVIOLATED: |
|||
case RegionCheckResult::AllViolated: |
|||
os << "AllViolated"; |
|||
break; |
|||
default: |
@ -0,0 +1,24 @@ |
|||
#pragma once |
|||
|
|||
#include <ostream> |
|||
|
|||
namespace storm { |
|||
namespace modelchecker { |
|||
namespace parametric { |
|||
/*! |
|||
* The results for a single Parameter region |
|||
*/ |
|||
enum class RegionCheckResult { |
|||
Unknown, /*!< the result is unknown */ |
|||
ExistsSat, /*!< the formula is satisfied for at least one parameter evaluation that lies in the given region */ |
|||
ExistsViolated, /*!< the formula is violated for at least one parameter evaluation that lies in the given region */ |
|||
ExistsBoth, /*!< the formula is satisfied for some parameters but also violated for others */ |
|||
AllSat, /*!< the formula is satisfied for all parameters in the given region */ |
|||
AllViolated /*!< the formula is violated for all parameters in the given region */ |
|||
}; |
|||
|
|||
std::ostream& operator<<(std::ostream& os, RegionCheckResult const& regionCheckResult); |
|||
} |
|||
} |
|||
} |
|||
|
@ -1,34 +0,0 @@ |
|||
/* |
|||
* File: RegionCheckResult.h |
|||
* Author: tim |
|||
* |
|||
* Created on September 9, 2015, 1:56 PM |
|||
*/ |
|||
|
|||
#ifndef STORM_MODELCHECKER_REGION_REGIONCHECKRESULT_H |
|||
#define STORM_MODELCHECKER_REGION_REGIONCHECKRESULT_H |
|||
|
|||
#include <ostream> |
|||
|
|||
namespace storm { |
|||
namespace modelchecker { |
|||
namespace region { |
|||
/*! |
|||
* The possible results for a single Parameter region |
|||
*/ |
|||
enum class RegionCheckResult { |
|||
UNKNOWN, /*!< the result is unknown */ |
|||
EXISTSSAT, /*!< the formula is satisfied for at least one parameter evaluation that lies in the given region */ |
|||
EXISTSVIOLATED, /*!< the formula is violated for at least one parameter evaluation that lies in the given region */ |
|||
EXISTSBOTH, /*!< the formula is satisfied for some parameters but also violated for others */ |
|||
ALLSAT, /*!< the formula is satisfied for all parameters in the given region */ |
|||
ALLVIOLATED /*!< the formula is violated for all parameters in the given region */ |
|||
}; |
|||
|
|||
std::ostream& operator<<(std::ostream& os, RegionCheckResult const& regionCheckResult); |
|||
} |
|||
} |
|||
} |
|||
|
|||
#endif /* STORM_MODELCHECKER_REGION_REGIONCHECKRESULT_H */ |
|||
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue