@ -6,6 +6,7 @@
# include "storm/modelchecker/results/CheckResult.h"
# include "storm/modelchecker/results/CheckResult.h"
# include "storm/modelchecker/results/SymbolicQualitativeCheckResult.h"
# include "storm/modelchecker/results/SymbolicQualitativeCheckResult.h"
# include "storm/modelchecker/results/QuantitativeCheckResult.h"
# include "storm/modelchecker/results/SymbolicQuantitativeCheckResult.h"
# include "storm/modelchecker/results/SymbolicQuantitativeCheckResult.h"
# include "storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h"
# include "storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h"
# include "storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h"
# include "storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h"
@ -15,6 +16,8 @@
# include "storm/storage/dd/Bdd.h"
# include "storm/storage/dd/Bdd.h"
# include "storm/storage/dd/BisimulationDecomposition.h"
# include "storm/storage/dd/BisimulationDecomposition.h"
# include "storm/abstraction/QualitativeMdpResultMinMax.h"
# include "storm/settings/SettingsManager.h"
# include "storm/settings/SettingsManager.h"
# include "storm/settings/modules/AbstractionSettings.h"
# include "storm/settings/modules/AbstractionSettings.h"
@ -41,28 +44,28 @@ namespace storm {
template < typename ModelType >
template < typename ModelType >
std : : unique_ptr < CheckResult > PartialBisimulationMdpModelChecker < ModelType > : : computeUntilProbabilities ( CheckTask < storm : : logic : : UntilFormula > const & checkTask ) {
std : : unique_ptr < CheckResult > PartialBisimulationMdpModelChecker < ModelType > : : computeUntilProbabilities ( CheckTask < storm : : logic : : UntilFormula > const & checkTask ) {
return computeValuesAbstractionRefinement ( false , checkTask . substituteFormula < storm : : logic : : Formula > ( checkTask . getFormula ( ) ) ) ;
return computeValuesAbstractionRefinement ( checkTask . substituteFormula < storm : : logic : : Formula > ( checkTask . getFormula ( ) ) ) ;
}
}
template < typename ModelType >
template < typename ModelType >
std : : unique_ptr < CheckResult > PartialBisimulationMdpModelChecker < ModelType > : : computeReachabilityProbabilities ( CheckTask < storm : : logic : : EventuallyFormula > const & checkTask ) {
std : : unique_ptr < CheckResult > PartialBisimulationMdpModelChecker < ModelType > : : computeReachabilityProbabilities ( CheckTask < storm : : logic : : EventuallyFormula > const & checkTask ) {
return computeValuesAbstractionRefinement ( false , checkTask . substituteFormula < storm : : logic : : Formula > ( checkTask . getFormula ( ) ) ) ;
return computeValuesAbstractionRefinement ( checkTask . substituteFormula < storm : : logic : : Formula > ( checkTask . getFormula ( ) ) ) ;
}
}
template < typename ModelType >
template < typename ModelType >
std : : unique_ptr < CheckResult > PartialBisimulationMdpModelChecker < ModelType > : : computeReachabilityRewards ( storm : : logic : : RewardMeasureType rewardMeasureType , CheckTask < storm : : logic : : EventuallyFormula , ValueType > const & checkTask ) {
std : : unique_ptr < CheckResult > PartialBisimulationMdpModelChecker < ModelType > : : computeReachabilityRewards ( storm : : logic : : RewardMeasureType rewardMeasureType , CheckTask < storm : : logic : : EventuallyFormula , ValueType > const & checkTask ) {
STORM_LOG_THROW ( rewardMeasureType = = storm : : logic : : RewardMeasureType : : Expectation , storm : : exceptions : : InvalidPropertyException , " Can only compute reward expectations. " ) ;
STORM_LOG_THROW ( rewardMeasureType = = storm : : logic : : RewardMeasureType : : Expectation , storm : : exceptions : : InvalidPropertyException , " Can only compute reward expectations. " ) ;
return computeValuesAbstractionRefinement ( true , checkTask . template substituteFormula < storm : : logic : : Formula > ( checkTask . getFormula ( ) ) ) ;
return computeValuesAbstractionRefinement ( checkTask . template substituteFormula < storm : : logic : : Formula > ( checkTask . getFormula ( ) ) ) ;
}
}
template < typename ModelType >
template < typename ModelType >
std : : unique_ptr < CheckResult > PartialBisimulationMdpModelChecker < ModelType > : : computeValuesAbstractionRefinement ( bool rewards , CheckTask < storm : : logic : : Formula > const & checkTask ) {
std : : unique_ptr < CheckResult > PartialBisimulationMdpModelChecker < ModelType > : : computeValuesAbstractionRefinement ( CheckTask < storm : : logic : : Formula > const & checkTask ) {
STORM_LOG_THROW ( checkTask . isOnlyInitialStatesRelevantSet ( ) , storm : : exceptions : : InvalidPropertyException , " The game-based abstraction refinement model checker can only compute the result for the initial states. " ) ;
STORM_LOG_THROW ( checkTask . isOnlyInitialStatesRelevantSet ( ) , storm : : exceptions : : InvalidPropertyException , " The game-based abstraction refinement model checker can only compute the result for the initial states. " ) ;
// Create the appropriate preservation information.
// Create the appropriate preservation information.
storm : : dd : : bisimulation : : PreservationInformation < DdType , ValueType > preservationInformation ( model , { checkTask . getFormula ( ) . asSharedPointer ( ) } ) ;
storm : : dd : : bisimulation : : PreservationInformation < DdType , ValueType > preservationInformation ( model , { checkTask . getFormula ( ) . asSharedPointer ( ) } ) ;
if ( rewards ) {
if ( checkTask . getFo rmula ( ) . isEventuallyFormula ( ) & & checkTask . getFormula ( ) . asEventuallyFormula ( ) . getContext ( ) = = storm : : logic : : FormulaContext : : R eward) {
if ( ! checkTask . isRewardModelSet ( ) | | model . hasUniqueRewardModel ( ) ) {
if ( ! checkTask . isRewardModelSet ( ) | | model . hasUniqueRewardModel ( ) ) {
preservationInformation . addRewardModel ( model . getUniqueRewardModelName ( ) ) ;
preservationInformation . addRewardModel ( model . getUniqueRewardModelName ( ) ) ;
} else if ( checkTask . isRewardModelSet ( ) ) {
} else if ( checkTask . isRewardModelSet ( ) ) {
@ -85,10 +88,21 @@ namespace storm {
if ( fullQuotient ) {
if ( fullQuotient ) {
STORM_LOG_TRACE ( " Reached final quotient. " ) ;
STORM_LOG_TRACE ( " Reached final quotient. " ) ;
quotient - > printModelInformationToStream ( std : : cout ) ;
quotient - > printModelInformationToStream ( std : : cout ) ;
result = computeResultFullQuotient ( * quotient , rewards , checkTask ) ;
result = computeResultFullQuotient ( * quotient , checkTask ) ;
} else {
} else {
// Obtain lower and upper bounds from the partial quotient.
// Obtain lower and upper bounds from the partial quotient.
std : : pair < std : : unique_ptr < CheckResult > , std : : unique_ptr < CheckResult > > bounds = computeBoundsPartialQuotient ( * quotient , rewards , checkTask ) ;
std : : pair < std : : unique_ptr < CheckResult > , std : : unique_ptr < CheckResult > > bounds = computeBoundsPartialQuotient ( * quotient , checkTask ) ;
// If either of the two bounds does not exist, the answer can be derived from the existing bounds.
if ( bounds . first = = nullptr | | bounds . second = = nullptr ) {
STORM_LOG_ASSERT ( bounds . first | | bounds . second , " Expected at least one bound. " ) ;
quotient - > printModelInformationToStream ( std : : cout ) ;
if ( bounds . first ) {
return std : : move ( bounds . first ) ;
} else {
return std : : move ( bounds . second ) ;
}
}
// Check whether the bounds are sufficiently close.
// Check whether the bounds are sufficiently close.
bool converged = checkBoundsSufficientlyClose ( bounds ) ;
bool converged = checkBoundsSufficientlyClose ( bounds ) ;
@ -153,46 +167,150 @@ namespace storm {
return std : : make_unique < storm : : modelchecker : : SymbolicQuantitativeCheckResult < DdType , ValueType > > ( lowerBounds . getReachableStates ( ) , lowerBounds . getStates ( ) , ( lowerBounds . getValueVector ( ) + upperBounds . getValueVector ( ) ) / lowerBounds . getValueVector ( ) . getDdManager ( ) . getConstant ( storm : : utility : : convertNumber < ValueType > ( std : : string ( " 2.0 " ) ) ) ) ;
return std : : make_unique < storm : : modelchecker : : SymbolicQuantitativeCheckResult < DdType , ValueType > > ( lowerBounds . getReachableStates ( ) , lowerBounds . getStates ( ) , ( lowerBounds . getValueVector ( ) + upperBounds . getValueVector ( ) ) / lowerBounds . getValueVector ( ) . getDdManager ( ) . getConstant ( storm : : utility : : convertNumber < ValueType > ( std : : string ( " 2.0 " ) ) ) ) ;
}
}
static int i = 0 ;
template < typename ModelType >
typename PartialBisimulationMdpModelChecker < ModelType > : : ValueType PartialBisimulationMdpModelChecker < ModelType > : : getExtremalBound ( storm : : OptimizationDirection dir , QuantitativeCheckResult < ValueType > const & result ) {
if ( dir = = storm : : OptimizationDirection : : Minimize ) {
return result . getMin ( ) ;
} else {
return result . getMax ( ) ;
}
}
template < typename ModelType >
template < typename ModelType >
std : : pair < std : : unique_ptr < CheckResult > , std : : unique_ptr < CheckResult > > PartialBisimulationMdpModelChecker < ModelType > : : computeBoundsPartialQuotient ( storm : : models : : symbolic : : Mdp < DdType , ValueType > const & quotient , bool rewards , CheckTask < storm : : logic : : Formula > const & checkTask ) {
bool PartialBisimulationMdpModelChecker < ModelType > : : boundsSufficient ( storm : : models : : Model < ValueType > const & quotient , bool lowerBounds , QuantitativeCheckResult < ValueType > const & result , storm : : logic : : ComparisonType comparisonType , ValueType const & threshold ) {
if ( lowerBounds ) {
if ( storm : : logic : : isLowerBound ( comparisonType ) ) {
ValueType minimalLowerBound = getExtremalBound ( storm : : OptimizationDirection : : Minimize , result ) ;
return ( storm : : logic : : isStrict ( comparisonType ) & & minimalLowerBound > threshold ) | | ( ! storm : : logic : : isStrict ( comparisonType ) & & minimalLowerBound > = threshold ) ;
} else {
ValueType maximalLowerBound = getExtremalBound ( storm : : OptimizationDirection : : Maximize , result ) ;
return ( storm : : logic : : isStrict ( comparisonType ) & & maximalLowerBound > = threshold ) | | ( ! storm : : logic : : isStrict ( comparisonType ) & & maximalLowerBound > threshold ) ;
}
} else {
if ( storm : : logic : : isLowerBound ( comparisonType ) ) {
ValueType minimalUpperBound = getExtremalBound ( storm : : OptimizationDirection : : Minimize , result ) ;
return ( storm : : logic : : isStrict ( comparisonType ) & & minimalUpperBound < = threshold ) | | ( ! storm : : logic : : isStrict ( comparisonType ) & & minimalUpperBound < threshold ) ;
} else {
ValueType maximalUpperBound = getExtremalBound ( storm : : OptimizationDirection : : Maximize , result ) ;
return ( storm : : logic : : isStrict ( comparisonType ) & & maximalUpperBound < threshold ) | | ( ! storm : : logic : : isStrict ( comparisonType ) & & maximalUpperBound < = threshold ) ;
}
}
}
std : : pair < std : : unique_ptr < CheckResult > , std : : unique_ptr < CheckResult > > result ;
template < typename ModelType >
std : : unique_ptr < CheckResult > PartialBisimulationMdpModelChecker < ModelType > : : computeBoundsPartialQuotient ( SymbolicMdpPrctlModelChecker < storm : : models : : symbolic : : Mdp < DdType , ValueType > > & checker , storm : : models : : symbolic : : Mdp < DdType , ValueType > const & quotient , storm : : OptimizationDirection const & dir , CheckTask < storm : : logic : : Formula > & checkTask ) {
CheckTask < storm : : logic : : Formula > newCheckTask ( checkTask ) ;
SymbolicMdpPrctlModelChecker < storm : : models : : symbolic : : Mdp < DdType , ValueType > > checker ( quotient ) ;
bool rewards = checkTask . getFormula ( ) . isEventuallyFormula ( ) & & checkTask . getFormula ( ) . asEventuallyFormula ( ) . getContext ( ) = = storm : : logic : : FormulaContext : : Reward ;
newCheckTask . setOptimizationDirection ( storm : : OptimizationDirection : : Minimize ) ;
std : : unique_ptr < CheckResult > result ;
checkTask . setOptimizationDirection ( dir ) ;
if ( rewards ) {
if ( rewards ) {
result . first = checker . computeRewards ( storm : : logic : : RewardMeasureType : : Expectation , newCheckTask ) ;
result = checker . computeRewards ( storm : : logic : : RewardMeasureType : : Expectation , c heckTask ) ;
} else {
} else {
result . first = checker . computeProbabilities ( newCheckTask ) ;
result = checker . computeProbabilities ( checkTask ) ;
}
STORM_LOG_ASSERT ( result , " Expected result. " ) ;
result - > filter ( storm : : modelchecker : : SymbolicQualitativeCheckResult < DdType > ( quotient . getReachableStates ( ) , quotient . getInitialStates ( ) ) ) ;
return result ;
}
}
STORM_LOG_ASSERT ( result . first , " Expected result. " ) ;
result . first - > asSymbolicQuantitativeCheckResult < DdType , ValueType > ( ) . getValueVector ( ) . exportToDot ( " lower_values " + std : : to_string ( i ) + " .dot " ) ;
result . first - > filter ( storm : : modelchecker : : SymbolicQualitativeCheckResult < DdType > ( quotient . getReachableStates ( ) , quotient . getInitialStates ( ) ) ) ;
newCheckTask . setOptimizationDirection ( storm : : OptimizationDirection : : Maximize ) ;
if ( rewards ) {
result . second = checker . computeRewards ( storm : : logic : : RewardMeasureType : : Expectation , newCheckTask ) ;
template < typename ModelType >
std : : pair < storm : : dd : : Bdd < PartialBisimulationMdpModelChecker < ModelType > : : DdType > , storm : : dd : : Bdd < PartialBisimulationMdpModelChecker < ModelType > : : DdType > > PartialBisimulationMdpModelChecker < ModelType > : : getConstraintAndTargetStates ( storm : : models : : symbolic : : Mdp < DdType , ValueType > const & quotient , CheckTask < storm : : logic : : Formula > const & checkTask ) {
std : : pair < storm : : dd : : Bdd < DdType > , storm : : dd : : Bdd < DdType > > result ;
SymbolicPropositionalModelChecker < storm : : models : : symbolic : : Mdp < DdType , ValueType > > checker ( quotient ) ;
if ( checkTask . getFormula ( ) . isUntilFormula ( ) ) {
std : : unique_ptr < CheckResult > subresult = checker . check ( checkTask . getFormula ( ) . asUntilFormula ( ) . getLeftSubformula ( ) ) ;
result . first = subresult - > asSymbolicQualitativeCheckResult < DdType > ( ) . getTruthValuesVector ( ) ;
subresult = checker . check ( checkTask . getFormula ( ) . asUntilFormula ( ) . getRightSubformula ( ) ) ;
result . second = subresult - > asSymbolicQualitativeCheckResult < DdType > ( ) . getTruthValuesVector ( ) ;
} else if ( checkTask . getFormula ( ) . isEventuallyFormula ( ) ) {
storm : : logic : : EventuallyFormula const & eventuallyFormula = checkTask . getFormula ( ) . asEventuallyFormula ( ) ;
result . first = quotient . getReachableStates ( ) ;
std : : unique_ptr < CheckResult > subresult = checker . check ( eventuallyFormula . getSubformula ( ) ) ;
result . second = subresult - > asSymbolicQualitativeCheckResult < DdType > ( ) . getTruthValuesVector ( ) ;
} else {
STORM_LOG_THROW ( false , storm : : exceptions : : NotSupportedException , " The given formula is not supported by this model checker. " ) ;
}
return result ;
}
template < typename ModelType >
std : : pair < std : : unique_ptr < CheckResult > , std : : unique_ptr < CheckResult > > PartialBisimulationMdpModelChecker < ModelType > : : computeBoundsPartialQuotient ( storm : : models : : symbolic : : Mdp < DdType , ValueType > const & quotient , CheckTask < storm : : logic : : Formula > const & checkTask ) {
std : : pair < std : : unique_ptr < CheckResult > , std : : unique_ptr < CheckResult > > result ;
// We go through two phases. In phase (1) we are solving the qualitative part and in phase (2) the quantitative part.
// Preparation: determine the constraint states and the target states of the reachability objective.
bool isRewardFormula = checkTask . getFormula ( ) . isEventuallyFormula ( ) & & checkTask . getFormula ( ) . asEventuallyFormula ( ) . getContext ( ) = = storm : : logic : : FormulaContext : : Reward ;
std : : pair < storm : : dd : : Bdd < DdType > , storm : : dd : : Bdd < DdType > > constraintTargetStates = getConstraintAndTargetStates ( quotient , checkTask ) ;
// Phase (1): solve qualitatively.
storm : : abstraction : : QualitativeMdpResultMinMax < DdType > qualitativeResults ;
storm : : dd : : Bdd < DdType > transitionMatrixBdd = quotient . getTransitionMatrix ( ) . notZero ( ) ;
if ( isRewardFormula ) {
qualitativeResults . min . second = storm : : utility : : graph : : performProb1E ( quotient , transitionMatrixBdd , constraintTargetStates . first , constraintTargetStates . second , storm : : utility : : graph : : performProbGreater0E ( quotient , transitionMatrixBdd , constraintTargetStates . first , constraintTargetStates . second ) ) ;
qualitativeResults . max . second = storm : : utility : : graph : : performProb1A ( quotient , transitionMatrixBdd , constraintTargetStates . first , storm : : utility : : graph : : performProbGreater0A ( quotient , transitionMatrixBdd , constraintTargetStates . first , constraintTargetStates . second ) ) ;
} else {
} else {
result . second = checker . computeProbabilities ( newCheckTask ) ;
qualitativeResults . min = storm : : utility : : graph : : performProb01Min ( quotient , transitionMatrixBdd , constraintTargetStates . first , constraintTargetStates . second ) ;
qualitativeResults . max = storm : : utility : : graph : : performProb01Max ( quotient , transitionMatrixBdd , constraintTargetStates . first , constraintTargetStates . second ) ;
}
}
STORM_LOG_ASSERT ( result . second , " Expected result. " ) ;
result . first - > asSymbolicQuantitativeCheckResult < DdType , ValueType > ( ) . getValueVector ( ) . exportToDot ( " upper_values " + std : : to_string ( i + + ) + " .dot " ) ;
result . second - > filter ( storm : : modelchecker : : SymbolicQualitativeCheckResult < DdType > ( quotient . getReachableStates ( ) , quotient . getInitialStates ( ) ) ) ;
// CheckTask<storm::logic::Formula> newCheckTask(checkTask);
//
// if (!checkTask.isBoundSet() || storm::logic::isLowerBound(checkTask.getBoundComparisonType())) {
// // Check whether we can answer the query (lower bound above bound).
// result.first = computeBoundsPartialQuotient(checker, quotient, rewards, storm::OptimizationDirection::Minimize, newCheckTask);
// if (checkTask.isBoundSet()) {
// bool sufficient = boundsSufficient(quotient, true, result.first->asQuantitativeCheckResult<ValueType>(), checkTask.getBoundComparisonType(), checkTask.getBoundThreshold());
// if (sufficient) {
// return result;
// }
// }
//
// // Check whether we can answer the query (upper bound below bound).
// result.second = computeBoundsPartialQuotient(checker, quotient, rewards, storm::OptimizationDirection::Maximize, newCheckTask);
// if (checkTask.isBoundSet()) {
// bool sufficient = boundsSufficient(quotient, false, result.second->asQuantitativeCheckResult<ValueType>(), checkTask.getBoundComparisonType(), checkTask.getBoundThreshold());
// if (sufficient) {
// result.first = nullptr;
// return result;
// }
// }
// } else {
// // Check whether we can answer the query (upper bound below bound).
// result.second = computeBoundsPartialQuotient(checker, quotient, rewards, storm::OptimizationDirection::Maximize, newCheckTask);
// if (checkTask.isBoundSet()) {
// bool sufficient = boundsSufficient(quotient, false, result.second->asQuantitativeCheckResult<ValueType>(), checkTask.getBoundComparisonType(), checkTask.getBoundThreshold());
// if (sufficient) {
// return result;
// }
// }
//
// // Check whether we can answer the query (lower bound above bound).
// result.first = computeBoundsPartialQuotient(checker, quotient, rewards, storm::OptimizationDirection::Minimize, newCheckTask);
// if (checkTask.isBoundSet()) {
// bool sufficient = boundsSufficient(quotient, true, result.first->asQuantitativeCheckResult<ValueType>(), checkTask.getBoundComparisonType(), checkTask.getBoundThreshold());
// if (sufficient) {
// result.second = nullptr;
// return result;
// }
// }
// }
return result ;
return result ;
}
}
template < typename ModelType >
template < typename ModelType >
std : : pair < std : : unique_ptr < CheckResult > , std : : unique_ptr < CheckResult > > PartialBisimulationMdpModelChecker < ModelType > : : computeBoundsPartialQuotient ( storm : : models : : symbolic : : StochasticTwoPlayerGame < DdType , ValueType > const & quotient , bool rewards , CheckTask < storm : : logic : : Formula > const & checkTask ) {
std : : pair < std : : unique_ptr < CheckResult > , std : : unique_ptr < CheckResult > > PartialBisimulationMdpModelChecker < ModelType > : : computeBoundsPartialQuotient ( storm : : models : : symbolic : : StochasticTwoPlayerGame < DdType , ValueType > const & quotient , CheckTask < storm : : logic : : Formula > const & checkTask ) {
STORM_LOG_THROW ( false , storm : : exceptions : : NotImplementedException , " Currently not implemented. " ) ;
STORM_LOG_THROW ( false , storm : : exceptions : : NotImplementedException , " Currently not implemented. " ) ;
}
}
template < typename ModelType >
template < typename ModelType >
std : : pair < std : : unique_ptr < CheckResult > , std : : unique_ptr < CheckResult > > PartialBisimulationMdpModelChecker < ModelType > : : computeBoundsPartialQuotient ( storm : : models : : Model < ValueType > const & quotient , bool rewards , CheckTask < storm : : logic : : Formula > const & checkTask ) {
std : : pair < std : : unique_ptr < CheckResult > , std : : unique_ptr < CheckResult > > PartialBisimulationMdpModelChecker < ModelType > : : computeBoundsPartialQuotient ( storm : : models : : Model < ValueType > const & quotient , CheckTask < storm : : logic : : Formula > const & checkTask ) {
// Sanity checks.
// Sanity checks.
STORM_LOG_THROW ( quotient . isSymbolicModel ( ) , storm : : exceptions : : NotSupportedException , " Expecting symbolic quotient. " ) ;
STORM_LOG_THROW ( quotient . isSymbolicModel ( ) , storm : : exceptions : : NotSupportedException , " Expecting symbolic quotient. " ) ;
@ -200,14 +318,16 @@ namespace storm {
STORM_LOG_THROW ( modelType = = storm : : models : : ModelType : : Mdp | | modelType = = storm : : models : : ModelType : : S2pg , storm : : exceptions : : NotSupportedException , " Only MDPs and stochastic games are supported as partial quotients. " ) ;
STORM_LOG_THROW ( modelType = = storm : : models : : ModelType : : Mdp | | modelType = = storm : : models : : ModelType : : S2pg , storm : : exceptions : : NotSupportedException , " Only MDPs and stochastic games are supported as partial quotients. " ) ;
if ( modelType = = storm : : models : : ModelType : : Mdp ) {
if ( modelType = = storm : : models : : ModelType : : Mdp ) {
return computeBoundsPartialQuotient ( * quotient . template as < storm : : models : : symbolic : : Mdp < DdType , ValueType > > ( ) , rewards , checkTask ) ;
return computeBoundsPartialQuotient ( static_cast < storm : : models : : symbolic : : Mdp < DdType , ValueType > const & > ( quotient ) , checkTask ) ;
} else {
} else {
return computeBoundsPartialQuotient ( * quotient . template as < storm : : models : : symbolic : : StochasticTwoPlayerGame < DdType , ValueType > > ( ) , rewards , checkTask ) ;
return computeBoundsPartialQuotient ( static_cast < storm : : models : : symbolic : : StochasticTwoPlayerGame < DdType , ValueType > const & > ( quotient ) , checkTask ) ;
}
}
}
}
template < typename ModelType >
template < typename ModelType >
std : : unique_ptr < CheckResult > PartialBisimulationMdpModelChecker < ModelType > : : computeResultFullQuotient ( storm : : models : : symbolic : : Dtmc < DdType , ValueType > const & quotient , bool rewards , CheckTask < storm : : logic : : Formula > const & checkTask ) {
std : : unique_ptr < CheckResult > PartialBisimulationMdpModelChecker < ModelType > : : computeResultFullQuotient ( storm : : models : : symbolic : : Dtmc < DdType , ValueType > const & quotient , CheckTask < storm : : logic : : Formula > const & checkTask ) {
bool rewards = checkTask . getFormula ( ) . isEventuallyFormula ( ) & & checkTask . getFormula ( ) . asEventuallyFormula ( ) . getContext ( ) = = storm : : logic : : FormulaContext : : Reward ;
SymbolicDtmcPrctlModelChecker < storm : : models : : symbolic : : Dtmc < DdType , ValueType > > checker ( quotient ) ;
SymbolicDtmcPrctlModelChecker < storm : : models : : symbolic : : Dtmc < DdType , ValueType > > checker ( quotient ) ;
std : : unique_ptr < CheckResult > result ;
std : : unique_ptr < CheckResult > result ;
if ( rewards ) {
if ( rewards ) {
@ -220,7 +340,9 @@ namespace storm {
}
}
template < typename ModelType >
template < typename ModelType >
std : : unique_ptr < CheckResult > PartialBisimulationMdpModelChecker < ModelType > : : computeResultFullQuotient ( storm : : models : : symbolic : : Mdp < DdType , ValueType > const & quotient , bool rewards , CheckTask < storm : : logic : : Formula > const & checkTask ) {
std : : unique_ptr < CheckResult > PartialBisimulationMdpModelChecker < ModelType > : : computeResultFullQuotient ( storm : : models : : symbolic : : Mdp < DdType , ValueType > const & quotient , CheckTask < storm : : logic : : Formula > const & checkTask ) {
bool rewards = checkTask . getFormula ( ) . isEventuallyFormula ( ) & & checkTask . getFormula ( ) . asEventuallyFormula ( ) . getContext ( ) = = storm : : logic : : FormulaContext : : Reward ;
SymbolicMdpPrctlModelChecker < storm : : models : : symbolic : : Mdp < DdType , ValueType > > checker ( quotient ) ;
SymbolicMdpPrctlModelChecker < storm : : models : : symbolic : : Mdp < DdType , ValueType > > checker ( quotient ) ;
std : : unique_ptr < CheckResult > result ;
std : : unique_ptr < CheckResult > result ;
if ( rewards ) {
if ( rewards ) {
@ -233,7 +355,7 @@ namespace storm {
}
}
template < typename ModelType >
template < typename ModelType >
std : : unique_ptr < CheckResult > PartialBisimulationMdpModelChecker < ModelType > : : computeResultFullQuotient ( storm : : models : : Model < ValueType > const & quotient , bool rewards , CheckTask < storm : : logic : : Formula > const & checkTask ) {
std : : unique_ptr < CheckResult > PartialBisimulationMdpModelChecker < ModelType > : : computeResultFullQuotient ( storm : : models : : Model < ValueType > const & quotient , CheckTask < storm : : logic : : Formula > const & checkTask ) {
// Sanity checks.
// Sanity checks.
STORM_LOG_THROW ( quotient . isSymbolicModel ( ) , storm : : exceptions : : NotSupportedException , " Expecting symbolic quotient. " ) ;
STORM_LOG_THROW ( quotient . isSymbolicModel ( ) , storm : : exceptions : : NotSupportedException , " Expecting symbolic quotient. " ) ;
@ -241,9 +363,9 @@ namespace storm {
STORM_LOG_THROW ( modelType = = storm : : models : : ModelType : : Dtmc | | modelType = = storm : : models : : ModelType : : Mdp , storm : : exceptions : : NotSupportedException , " Only DTMCs and MDPs supported as full quotients. " ) ;
STORM_LOG_THROW ( modelType = = storm : : models : : ModelType : : Dtmc | | modelType = = storm : : models : : ModelType : : Mdp , storm : : exceptions : : NotSupportedException , " Only DTMCs and MDPs supported as full quotients. " ) ;
if ( modelType = = storm : : models : : ModelType : : Dtmc ) {
if ( modelType = = storm : : models : : ModelType : : Dtmc ) {
return computeResultFullQuotient ( * quotient . template as < storm : : models : : symbolic : : Dtmc < DdType , ValueType > > ( ) , rewards , checkTask ) ;
return computeResultFullQuotient ( static_cast < storm : : models : : symbolic : : Dtmc < DdType , ValueType > const & > ( quotient ) , checkTask ) ;
} else {
} else {
return computeResultFullQuotient ( * quotient . template as < storm : : models : : symbolic : : Mdp < DdType , ValueType > > ( ) , rewards , checkTask ) ;
return computeResultFullQuotient ( static_cast < storm : : models : : symbolic : : Mdp < DdType , ValueType > const & > ( quotient ) , checkTask ) ;
}
}
}
}