@ -4,12 +4,6 @@
# 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/utility/vector.h"
@ -29,14 +23,28 @@ namespace storm {
namespace modelchecker {
namespace parametric {
ParameterLiftingSettings : : ParameterLiftingSettings ( ) {
// todo: get this form settings
this - > applyExactValidation = false ;
}
template < typename SparseModelType , typename ConstantType >
ParameterLifting < SparseModelType , ConstantType > : : ParameterLifting ( SparseModelType const & parametricModel ) : parametricModel ( parametricModel ) {
ParameterLifting < SparseModelType , ConstantType > : : ParameterLifting ( SparseModelType const & parametricModel ) : parametricModel ( parametricModel ) {
initializationStopwatch . start ( ) ;
STORM_LOG_THROW ( parametricModel . getInitialStates ( ) . getNumberOfSetBits ( ) = = 1 , storm : : exceptions : : NotSupportedException , " Parameter lifting requires models with only one initial state " ) ;
initializationStopwatch . stop ( ) ;
}
template < typename SparseModelType , typename ConstantType >
ParameterLiftingSettings const & ParameterLifting < SparseModelType , ConstantType > : : getSettings ( ) const {
return settings ;
}
template < typename SparseModelType , typename ConstantType >
void ParameterLifting < SparseModelType , ConstantType > : : setSettings ( ParameterLiftingSettings const & newSettings ) {
settings = newSettings ;
}
template < typename SparseModelType , typename ConstantType >
void ParameterLifting < SparseModelType , ConstantType > : : specifyFormula ( CheckTask < storm : : logic : : Formula , typename SparseModelType : : ValueType > const & checkTask ) {
initializationStopwatch . start ( ) ;
@ -47,15 +55,20 @@ namespace storm {
initializeUnderlyingCheckers ( ) ;
currentCheckTask = std : : make_unique < storm : : modelchecker : : CheckTask < storm : : logic : : Formula , typename SparseModelType : : ValueType > > ( checkTask . substituteFormula ( * currentFormula ) ) ;
STORM_LOG_THROW ( parameterLiftingChecker - > canHandle ( * currentCheckTask ) , storm : : exceptions : : NotSupportedException , " Parameter lifting is not supported for this property. " ) ;
instantiationChecker - > specifyFormula ( * currentCheckTask ) ;
STORM_LOG_THROW ( parameterLiftingChecker - > canHandle ( * currentCheckTask ) & &
( ! exactParameterLiftingChecker | | exactParameterLiftingChecker - > canHandle ( * currentCheckTask ) ) ,
storm : : exceptions : : NotSupportedException , " Parameter lifting is not supported for this property. " ) ;
if ( exactParameterLiftingChecker ) {
exactParameterLiftingChecker - > specifyFormula ( * currentCheckTask ) ;
}
parameterLiftingChecker - > specifyFormula ( * currentCheckTask ) ;
instantiationChecker - > specifyFormula ( * currentCheckTask ) ;
initializationStopwatch . stop ( ) ;
}
template < typename SparseModelType , typename ConstantType >
RegionCheckResult ParameterLifting < SparseModelType , ConstantType > : : analyzeRegion ( storm : : storage : : ParameterRegion < typename SparseModelType : : ValueType > const & region , RegionCheckResult const & initialResult , bool sampleVerticesOfRegion ) const {
RegionCheckResult result = initialResult ;
RegionCheckResult ParameterLifting < SparseModelType , ConstantType > : : analyzeRegion ( storm : : storage : : ParameterRegion < typename SparseModelType : : ValueType > const & region , RegionCheckResult const & initialResult , bool sampleVerticesOfRegion ) {
RegionCheckResult result = initialResult ;
// Check if we need to check the formula on one point to decide whether to show AllSat or AllViolated
instantiationCheckerStopwatch . start ( ) ;
@ -102,15 +115,48 @@ namespace storm {
parameterLiftingCheckerStopwatch . stop ( ) ;
return result ;
}
template < typename SparseModelType , typename ConstantType >
RegionCheckResult ParameterLifting < SparseModelType , ConstantType > : : analyzeRegionExactValidation ( storm : : storage : : ParameterRegion < typename SparseModelType : : ValueType > const & region , RegionCheckResult const & initialResult ) {
RegionCheckResult numericResult = analyzeRegion ( region , initialResult , false ) ;
parameterLiftingCheckerStopwatch . start ( ) ;
if ( numericResult = = RegionCheckResult : : AllSat | | numericResult = = RegionCheckResult : : AllViolated ) {
applyHintsToExactChecker ( ) ;
}
if ( numericResult = = RegionCheckResult : : AllSat ) {
if ( ! exactParameterLiftingChecker - > check ( region , this - > currentCheckTask - > getOptimizationDirection ( ) ) - > asExplicitQualitativeCheckResult ( ) [ * getConsideredParametricModel ( ) . getInitialStates ( ) . begin ( ) ] ) {
// Numerical result is wrong; Check whether the region is AllViolated!
if ( ! exactParameterLiftingChecker - > check ( region , storm : : solver : : invert ( this - > currentCheckTask - > getOptimizationDirection ( ) ) ) - > asExplicitQualitativeCheckResult ( ) [ * getConsideredParametricModel ( ) . getInitialStates ( ) . begin ( ) ] ) {
parameterLiftingCheckerStopwatch . stop ( ) ;
return RegionCheckResult : : AllViolated ;
} else {
return RegionCheckResult : : Unknown ;
}
}
} else if ( numericResult = = RegionCheckResult : : AllViolated ) {
if ( exactParameterLiftingChecker - > check ( region , storm : : solver : : invert ( this - > currentCheckTask - > getOptimizationDirection ( ) ) ) - > asExplicitQualitativeCheckResult ( ) [ * getConsideredParametricModel ( ) . getInitialStates ( ) . begin ( ) ] ) {
// Numerical result is wrong; Check whether the region is AllSat!
if ( exactParameterLiftingChecker - > check ( region , this - > currentCheckTask - > getOptimizationDirection ( ) ) - > asExplicitQualitativeCheckResult ( ) [ * getConsideredParametricModel ( ) . getInitialStates ( ) . begin ( ) ] ) {
parameterLiftingCheckerStopwatch . stop ( ) ;
return RegionCheckResult : : AllSat ;
} else {
return RegionCheckResult : : Unknown ;
}
}
}
parameterLiftingCheckerStopwatch . stop ( ) ;
return numericResult ;
}
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 {
std : : vector < std : : pair < storm : : storage : : ParameterRegion < typename SparseModelType : : ValueType > , RegionCheckResult > > ParameterLifting < SparseModelType , ConstantType > : : performRegionRefinement ( storm : : storage : : ParameterRegion < typename SparseModelType : : ValueType > const & region , CoefficientType const & threshold ) {
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 > ( ) ;
auto fractionOfUndiscoveredArea = storm : : utility : : one < CoefficientType > ( ) ;
auto fractionOfAllSatArea = storm : : utility : : zero < CoefficientType > ( ) ;
auto fractionOfAllViolatedArea = storm : : utility : : zero < CoefficientType > ( ) ;
std : : vector < std : : pair < storm : : storage : : ParameterRegion < typename SparseModelType : : ValueType > , RegionCheckResult > > regions ;
regions . emplace_back ( region , RegionCheckResult : : Unknown ) ;
@ -122,7 +168,11 @@ namespace storm {
STORM_LOG_INFO ( " Analyzing region # " < < indexOfCurrentRegion < < " ( " < < storm : : utility : : convertNumber < double > ( fractionOfUndiscoveredArea ) * 100 < < " % still unknown) " ) ;
auto const & currentRegion = regions [ indexOfCurrentRegion ] . first ;
auto & res = regions [ indexOfCurrentRegion ] . second ;
res = analyzeRegion ( currentRegion , res , false ) ;
if ( settings . applyExactValidation ) {
res = analyzeRegionExactValidation ( currentRegion , res ) ;
} else {
res = analyzeRegion ( currentRegion , res , false ) ;
}
switch ( res ) {
case RegionCheckResult : : AllSat :
fractionOfUndiscoveredArea - = currentRegion . area ( ) / areaOfParameterSpace ;
@ -160,16 +210,6 @@ namespace storm {
return storm : : utility : : vector : : filterVector ( regions , resultRegions ) ;
}
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 ) {
@ -178,48 +218,10 @@ namespace storm {
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 ( ) ;
}
}
template < typename SparseModelType , typename ConstantType >
std : : string ParameterLifting < SparseModelType , ConstantType > : : visualizeResult ( std : : vector < std : : pair < storm : : storage : : ParameterRegion < typename SparseModelType : : ValueType > , RegionCheckResult > > const & result , storm : : storage : : ParameterRegion < typename SparseModelType : : ValueType > const & parameterSpace , typename storm : : storage : : ParameterRegion < typename SparseModelType : : ValueType > : : VariableType const & x , typename storm : : storage : : ParameterRegion < typename SparseModelType : : ValueType > : : VariableType const & y ) {
typedef typename storm : : storage : : ParameterRegion < typename SparseModelType : : ValueType > : : CoefficientType ValueType ;
std : : stringstream stream ;
uint_fast64_t const sizeX = 128 ;
@ -229,21 +231,21 @@ namespace storm {
stream < < " \t x-axis: " < < x < < " \t y-axis: " < < y < < " \t S=safe, [ ]=unsafe, -=ambiguous " < < std : : endl ;
for ( uint_fast64_t i = 0 ; i < sizeX + 2 ; + + i ) stream < < " # " ; stream < < std : : endl ;
Value Type deltaX = ( parameterSpace . getUpperBoundary ( x ) - parameterSpace . getLowerBoundary ( x ) ) / storm : : utility : : convertNumber < Value Type> ( sizeX ) ;
Value Type deltaY = ( parameterSpace . getUpperBoundary ( y ) - parameterSpace . getLowerBoundary ( y ) ) / storm : : utility : : convertNumber < Value Type> ( sizeY ) ;
Value Type printedRegionArea = deltaX * deltaY ;
for ( Value Type yUpper = parameterSpace . getUpperBoundary ( y ) ; yUpper ! = parameterSpace . getLowerBoundary ( y ) ; yUpper - = deltaY ) {
Value Type yLower = yUpper - deltaY ;
Coefficient Type deltaX = ( parameterSpace . getUpperBoundary ( x ) - parameterSpace . getLowerBoundary ( x ) ) / storm : : utility : : convertNumber < Coefficient Type> ( sizeX ) ;
Coefficient Type deltaY = ( parameterSpace . getUpperBoundary ( y ) - parameterSpace . getLowerBoundary ( y ) ) / storm : : utility : : convertNumber < Coefficient Type> ( sizeY ) ;
Coefficient Type printedRegionArea = deltaX * deltaY ;
for ( Coefficient Type yUpper = parameterSpace . getUpperBoundary ( y ) ; yUpper ! = parameterSpace . getLowerBoundary ( y ) ; yUpper - = deltaY ) {
Coefficient Type yLower = yUpper - deltaY ;
stream < < " # " ;
for ( Value Type xLower = parameterSpace . getLowerBoundary ( x ) ; xLower ! = parameterSpace . getUpperBoundary ( x ) ; xLower + = deltaX ) {
Value Type xUpper = xLower + deltaX ;
for ( Coefficient Type xLower = parameterSpace . getLowerBoundary ( x ) ; xLower ! = parameterSpace . getUpperBoundary ( x ) ; xLower + = deltaX ) {
Coefficient Type xUpper = xLower + deltaX ;
bool currRegionSafe = false ;
bool currRegionUnSafe = false ;
bool currRegionComplete = false ;
Value Type coveredArea = storm : : utility : : zero < Value Type> ( ) ;
Coefficient Type coveredArea = storm : : utility : : zero < Coefficient Type> ( ) ;
for ( auto const & r : result ) {
Value Type instersectionArea = std : : max ( storm : : utility : : zero < Value Type> ( ) , std : : min ( yUpper , r . first . getUpperBoundary ( y ) ) - std : : max ( yLower , r . first . getLowerBoundary ( y ) ) ) ;
instersectionArea * = std : : max ( storm : : utility : : zero < Value Type> ( ) , std : : min ( xUpper , r . first . getUpperBoundary ( x ) ) - std : : max ( xLower , r . first . getLowerBoundary ( x ) ) ) ;
Coefficient Type instersectionArea = std : : max ( storm : : utility : : zero < Coefficient Type> ( ) , std : : min ( yUpper , r . first . getUpperBoundary ( y ) ) - std : : max ( yLower , r . first . getLowerBoundary ( y ) ) ) ;
instersectionArea * = std : : max ( storm : : utility : : zero < Coefficient Type> ( ) , std : : min ( xUpper , r . first . getUpperBoundary ( x ) ) - std : : max ( xLower , r . first . getLowerBoundary ( x ) ) ) ;
if ( ! storm : : utility : : isZero ( instersectionArea ) ) {
currRegionSafe = currRegionSafe | | r . second = = RegionCheckResult : : AllSat ;
currRegionUnSafe = currRegionUnSafe | | r . second = = RegionCheckResult : : AllViolated ;
@ -272,8 +274,10 @@ namespace storm {
}
# ifdef STORM_HAVE_CARL
template class ParameterLifting < storm : : models : : sparse : : Dtmc < storm : : RationalFunction > , double > ;
template class ParameterLifting < storm : : models : : sparse : : Mdp < storm : : RationalFunction > , double > ;
template class ParameterLifting < storm : : models : : sparse : : Dtmc < storm : : RationalFunction > , double > ;
template class ParameterLifting < storm : : models : : sparse : : Mdp < storm : : RationalFunction > , double > ;
template class ParameterLifting < storm : : models : : sparse : : Dtmc < storm : : RationalFunction > , storm : : RationalNumber > ;
template class ParameterLifting < storm : : models : : sparse : : Mdp < storm : : RationalFunction > , storm : : RationalNumber > ;
# endif
} // namespace parametric
} //namespace modelchecker
xxxxxxxxxx