@ -18,10 +18,17 @@
# include "storm/modelchecker/helper/utility/SetInformationFromCheckTask.h"
# include "storm/logic/FragmentSpecification.h"
# include "storm/logic/ExtractMaximalStateFormulasVisitor.h"
# include "storm/automata/AcceptanceCondition.h"
# include "storm/automata/DeterministicAutomaton.h"
# include "storm/automata/LTL2DeterministicAutomaton.h"
# include "storm/models/sparse/StandardRewardModel.h"
# include "storm/settings/SettingsManager.h"
# include "storm/settings/modules/GeneralSettings.h"
# include "storm/settings/modules/DebugSettings.h"
# include "storm/exceptions/InvalidStateException.h"
@ -33,11 +40,11 @@ namespace storm {
SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : SparseDtmcPrctlModelChecker ( SparseDtmcModelType const & model ) : SparsePropositionalModelChecker < SparseDtmcModelType > ( model ) {
// Intentionally left empty.
}
template < typename SparseDtmcModelType >
bool SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : canHandleStatic ( CheckTask < storm : : logic : : Formula , ValueType > const & checkTask , bool * requiresSingleInitialState ) {
storm : : logic : : Formula const & formula = checkTask . getFormula ( ) ;
if ( formula . isInFragment ( storm : : logic : : prctl ( ) . setLongRunAverageRewardFormulasAllowed ( true ) . setLongRunAverageProbabilitiesAllowed ( true ) . setConditionalProbabilityFormulasAllowed ( true ) . setConditionalRewardFormulasAllowed ( true ) . setTotalRewardFormulasAllowed ( true ) . setOnlyEventuallyFormuluasInConditionalFormulasAllowed ( true ) . setRewardBoundedUntilFormulasAllowed ( true ) . setRewardBoundedCumulativeRewardFormulasAllowed ( true ) . setMultiDimensionalBoundedUntilFormulasAllowed ( true ) . setMultiDimensionalCumulativeRewardFormulasAllowed ( true ) . setTimeOperatorsAllowed ( true ) . setReachbilityTimeFormulasAllowed ( true ) . setRewardAccumulationAllowed ( true ) ) ) {
if ( formula . isInFragment ( storm : : logic : : prctlstar ( ) . setLongRunAverageRewardFormulasAllowed ( true ) . setLongRunAverageProbabilitiesAllowed ( true ) . setConditionalProbabilityFormulasAllowed ( true ) . setConditionalRewardFormulasAllowed ( true ) . setTotalRewardFormulasAllowed ( true ) . setOnlyEventuallyFormuluasInConditionalFormulasAllowed ( true ) . setRewardBoundedUntilFormulasAllowed ( true ) . setRewardBoundedCumulativeRewardFormulasAllowed ( true ) . setMultiDimensionalBoundedUntilFormulasAllowed ( true ) . setMultiDimensionalCumulativeRewardFormulasAllowed ( true ) . setTimeOperatorsAllowed ( true ) . setReachbilityTimeFormulasAllowed ( true ) . setRewardAccumulationAllowed ( true ) . setHOAPathFormulas Allowed ( true ) ) ) {
return true ;
} else if ( checkTask . isOnlyInitialStatesRelevantSet ( ) & & formula . isInFragment ( storm : : logic : : quantiles ( ) ) ) {
if ( requiresSingleInitialState ) {
@ -47,7 +54,7 @@ namespace storm {
}
return false ;
}
template < typename SparseDtmcModelType >
bool SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : canHandle ( CheckTask < storm : : logic : : Formula , ValueType > const & checkTask ) const {
bool requiresSingleInitialState = false ;
@ -57,7 +64,7 @@ namespace storm {
return false ;
}
}
template < typename SparseDtmcModelType >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : computeBoundedUntilProbabilities ( Environment const & env , CheckTask < storm : : logic : : BoundedUntilFormula , ValueType > const & checkTask ) {
storm : : logic : : BoundedUntilFormula const & pathFormula = checkTask . getFormula ( ) ;
@ -84,7 +91,7 @@ namespace storm {
return result ;
}
}
template < typename SparseDtmcModelType >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : computeNextProbabilities ( Environment const & env , CheckTask < storm : : logic : : NextFormula , ValueType > const & checkTask ) {
storm : : logic : : NextFormula const & pathFormula = checkTask . getFormula ( ) ;
@ -93,7 +100,7 @@ namespace storm {
std : : vector < ValueType > numericResult = storm : : modelchecker : : helper : : SparseDtmcPrctlHelper < ValueType > : : computeNextProbabilities ( env , this - > getModel ( ) . getTransitionMatrix ( ) , subResult . getTruthValuesVector ( ) ) ;
return std : : unique_ptr < CheckResult > ( new ExplicitQuantitativeCheckResult < ValueType > ( std : : move ( numericResult ) ) ) ;
}
template < typename SparseDtmcModelType >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : computeUntilProbabilities ( Environment const & env , CheckTask < storm : : logic : : UntilFormula , ValueType > const & checkTask ) {
storm : : logic : : UntilFormula const & pathFormula = checkTask . getFormula ( ) ;
@ -104,7 +111,7 @@ namespace storm {
std : : vector < ValueType > numericResult = storm : : modelchecker : : helper : : SparseDtmcPrctlHelper < ValueType > : : computeUntilProbabilities ( env , storm : : solver : : SolveGoal < ValueType > ( this - > getModel ( ) , checkTask ) , this - > getModel ( ) . getTransitionMatrix ( ) , this - > getModel ( ) . getBackwardTransitions ( ) , leftResult . getTruthValuesVector ( ) , rightResult . getTruthValuesVector ( ) , checkTask . isQualitativeSet ( ) , checkTask . getHint ( ) ) ;
return std : : unique_ptr < CheckResult > ( new ExplicitQuantitativeCheckResult < ValueType > ( std : : move ( numericResult ) ) ) ;
}
template < typename SparseDtmcModelType >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : computeGloballyProbabilities ( Environment const & env , CheckTask < storm : : logic : : GloballyFormula , ValueType > const & checkTask ) {
storm : : logic : : GloballyFormula const & pathFormula = checkTask . getFormula ( ) ;
@ -113,7 +120,77 @@ namespace storm {
std : : vector < ValueType > numericResult = storm : : modelchecker : : helper : : SparseDtmcPrctlHelper < ValueType > : : computeGloballyProbabilities ( env , storm : : solver : : SolveGoal < ValueType > ( this - > getModel ( ) , checkTask ) , this - > getModel ( ) . getTransitionMatrix ( ) , this - > getModel ( ) . getBackwardTransitions ( ) , subResult . getTruthValuesVector ( ) , checkTask . isQualitativeSet ( ) ) ;
return std : : unique_ptr < CheckResult > ( new ExplicitQuantitativeCheckResult < ValueType > ( std : : move ( numericResult ) ) ) ;
}
template < typename SparseDtmcModelType >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : computeHOAPathProbabilities ( Environment const & env , CheckTask < storm : : logic : : HOAPathFormula , ValueType > const & checkTask ) {
storm : : logic : : HOAPathFormula const & pathFormula = checkTask . getFormula ( ) ;
STORM_LOG_INFO ( " Obtaining HOA automaton... " ) ;
storm : : automata : : DeterministicAutomaton : : ptr da = pathFormula . readAutomaton ( ) ;
const storm : : automata : : APSet & apSet = da - > getAPSet ( ) ;
STORM_LOG_INFO ( " Deterministic automaton from HOA file has "
< < da - > getNumberOfStates ( ) < < " states, "
< < da - > getAPSet ( ) . size ( ) < < " atomic propositions and "
< < * da - > getAcceptance ( ) - > getAcceptanceExpression ( ) < < " as acceptance condition. " ) ;
std : : map < std : : string , storm : : storage : : BitVector > apSets ;
for ( std : : string const & ap : apSet . getAPs ( ) ) {
std : : shared_ptr < storm : : logic : : Formula const > expression = pathFormula . getAPMapping ( ) . at ( ap ) ;
STORM_LOG_INFO ( " Computing satisfaction set for atomic proposition \" " < < ap < < " \" <=> " < < * expression < < " ... " ) ;
std : : unique_ptr < CheckResult > resultPointer = this - > check ( * expression ) ;
ExplicitQualitativeCheckResult const & result = resultPointer - > asExplicitQualitativeCheckResult ( ) ;
storm : : storage : : BitVector bitVector = result . getTruthValuesVector ( ) ;
STORM_LOG_INFO ( " Atomic proposition \" " < < ap < < " \" is satisfied by " < < bitVector . getNumberOfSetBits ( ) < < " states. " ) ;
apSets [ ap ] = std : : move ( bitVector ) ;
}
const SparseDtmcModelType & dtmc = this - > getModel ( ) ;
storm : : solver : : SolveGoal < ValueType > goal ( dtmc , checkTask ) ;
std : : vector < ValueType > numericResult = storm : : modelchecker : : helper : : SparseDtmcPrctlHelper < ValueType > : : computeDAProductProbabilities ( env , dtmc , std : : move ( goal ) , * da , apSets , checkTask . isQualitativeSet ( ) ) ;
return std : : unique_ptr < CheckResult > ( new ExplicitQuantitativeCheckResult < ValueType > ( std : : move ( numericResult ) ) ) ;
}
template < typename SparseDtmcModelType >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : computeLTLProbabilities ( Environment const & env , CheckTask < storm : : logic : : PathFormula , ValueType > const & checkTask ) {
storm : : logic : : PathFormula const & pathFormula = checkTask . getFormula ( ) ;
std : : vector < storm : : logic : : ExtractMaximalStateFormulasVisitor : : LabelFormulaPair > extracted ;
std : : shared_ptr < storm : : logic : : Formula > ltlFormula = storm : : logic : : ExtractMaximalStateFormulasVisitor : : extract ( pathFormula , extracted ) ;
STORM_LOG_INFO ( " Extracting maximal state formulas and computing satisfaction sets for path formula: " < < pathFormula ) ;
std : : map < std : : string , storm : : storage : : BitVector > apSets ;
for ( auto & p : extracted ) {
STORM_LOG_INFO ( " Computing satisfaction set for atomic proposition \" " < < p . first < < " \" <=> " < < * p . second < < " ... " ) ;
std : : unique_ptr < CheckResult > subResultPointer = this - > check ( env , * p . second ) ;
ExplicitQualitativeCheckResult const & subResult = subResultPointer - > asExplicitQualitativeCheckResult ( ) ;
auto sat = subResult . getTruthValuesVector ( ) ;
STORM_LOG_INFO ( " Atomic proposition \" " < < p . first < < " \" is satisfied by " < < sat . getNumberOfSetBits ( ) < < " states. " ) ;
apSets [ p . first ] = std : : move ( sat ) ;
}
STORM_LOG_INFO ( " Resulting LTL path formula: " < < * ltlFormula ) ;
STORM_LOG_INFO ( " in prefix format: " < < ltlFormula - > toPrefixString ( ) ) ;
std : : shared_ptr < storm : : automata : : DeterministicAutomaton > da = storm : : automata : : LTL2DeterministicAutomaton : : ltl2da ( * ltlFormula ) ;
STORM_LOG_INFO ( " Deterministic automaton for LTL formula has "
< < da - > getNumberOfStates ( ) < < " states, "
< < da - > getAPSet ( ) . size ( ) < < " atomic propositions and "
< < * da - > getAcceptance ( ) - > getAcceptanceExpression ( ) < < " as acceptance condition. " ) ;
const SparseDtmcModelType & dtmc = this - > getModel ( ) ;
storm : : solver : : SolveGoal < ValueType > goal ( dtmc , checkTask ) ;
std : : vector < ValueType > numericResult = storm : : modelchecker : : helper : : SparseDtmcPrctlHelper < ValueType > : : computeDAProductProbabilities ( env , dtmc , std : : move ( goal ) , * da , apSets , checkTask . isQualitativeSet ( ) ) ;
return std : : unique_ptr < CheckResult > ( new ExplicitQuantitativeCheckResult < ValueType > ( std : : move ( numericResult ) ) ) ;
}
template < typename SparseDtmcModelType >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : computeCumulativeRewards ( Environment const & env , storm : : logic : : RewardMeasureType , CheckTask < storm : : logic : : CumulativeRewardFormula , ValueType > const & checkTask ) {
storm : : logic : : CumulativeRewardFormula const & rewardPathFormula = checkTask . getFormula ( ) ;
@ -134,7 +211,7 @@ namespace storm {
return std : : unique_ptr < CheckResult > ( new ExplicitQuantitativeCheckResult < ValueType > ( std : : move ( numericResult ) ) ) ;
}
}
template < typename SparseDtmcModelType >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : computeInstantaneousRewards ( Environment const & env , storm : : logic : : RewardMeasureType , CheckTask < storm : : logic : : InstantaneousRewardFormula , ValueType > const & checkTask ) {
storm : : logic : : InstantaneousRewardFormula const & rewardPathFormula = checkTask . getFormula ( ) ;
@ -142,7 +219,7 @@ namespace storm {
std : : vector < ValueType > numericResult = storm : : modelchecker : : helper : : SparseDtmcPrctlHelper < ValueType > : : computeInstantaneousRewards ( env , storm : : solver : : SolveGoal < ValueType > ( this - > getModel ( ) , checkTask ) , this - > getModel ( ) . getTransitionMatrix ( ) , checkTask . isRewardModelSet ( ) ? this - > getModel ( ) . getRewardModel ( checkTask . getRewardModel ( ) ) : this - > getModel ( ) . getRewardModel ( " " ) , rewardPathFormula . getBound < uint64_t > ( ) ) ;
return std : : unique_ptr < CheckResult > ( new ExplicitQuantitativeCheckResult < ValueType > ( std : : move ( numericResult ) ) ) ;
}
template < typename SparseDtmcModelType >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : computeReachabilityRewards ( Environment const & env , storm : : logic : : RewardMeasureType , CheckTask < storm : : logic : : EventuallyFormula , ValueType > const & checkTask ) {
storm : : logic : : EventuallyFormula const & eventuallyFormula = checkTask . getFormula ( ) ;
@ -152,7 +229,7 @@ namespace storm {
std : : vector < ValueType > numericResult = storm : : modelchecker : : helper : : SparseDtmcPrctlHelper < ValueType > : : computeReachabilityRewards ( env , storm : : solver : : SolveGoal < ValueType > ( this - > getModel ( ) , checkTask ) , this - > getModel ( ) . getTransitionMatrix ( ) , this - > getModel ( ) . getBackwardTransitions ( ) , rewardModel . get ( ) , subResult . getTruthValuesVector ( ) , checkTask . isQualitativeSet ( ) , checkTask . getHint ( ) ) ;
return std : : unique_ptr < CheckResult > ( new ExplicitQuantitativeCheckResult < ValueType > ( std : : move ( numericResult ) ) ) ;
}
template < typename SparseDtmcModelType >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : computeReachabilityTimes ( Environment const & env , storm : : logic : : RewardMeasureType , CheckTask < storm : : logic : : EventuallyFormula , ValueType > const & checkTask ) {
storm : : logic : : EventuallyFormula const & eventuallyFormula = checkTask . getFormula ( ) ;
@ -161,7 +238,7 @@ namespace storm {
std : : vector < ValueType > numericResult = storm : : modelchecker : : helper : : SparseDtmcPrctlHelper < ValueType > : : computeReachabilityTimes ( env , storm : : solver : : SolveGoal < ValueType > ( this - > getModel ( ) , checkTask ) , this - > getModel ( ) . getTransitionMatrix ( ) , this - > getModel ( ) . getBackwardTransitions ( ) , subResult . getTruthValuesVector ( ) , checkTask . isQualitativeSet ( ) , checkTask . getHint ( ) ) ;
return std : : unique_ptr < CheckResult > ( new ExplicitQuantitativeCheckResult < ValueType > ( std : : move ( numericResult ) ) ) ;
}
template < typename SparseDtmcModelType >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : computeTotalRewards ( Environment const & env , storm : : logic : : RewardMeasureType , CheckTask < storm : : logic : : TotalRewardFormula , ValueType > const & checkTask ) {
auto rewardModel = storm : : utility : : createFilteredRewardModel ( this - > getModel ( ) , checkTask ) ;
@ -171,18 +248,18 @@ namespace storm {
template < typename SparseDtmcModelType >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : computeLongRunAverageProbabilities ( Environment const & env , CheckTask < storm : : logic : : StateFormula , ValueType > const & checkTask ) {
storm : : logic : : StateFormula const & stateFormula = checkTask . getFormula ( ) ;
std : : unique_ptr < CheckResult > subResultPointer = this - > check ( env , stateFormula ) ;
ExplicitQualitativeCheckResult const & subResult = subResultPointer - > asExplicitQualitativeCheckResult ( ) ;
storm : : modelchecker : : helper : : SparseDeterministicInfiniteHorizonHelper < ValueType > helper ( this - > getModel ( ) . getTransitionMatrix ( ) ) ;
storm : : modelchecker : : helper : : setInformationFromCheckTaskDeterministic ( helper , checkTask , this - > getModel ( ) ) ;
auto values = helper . computeLongRunAverageProbabilities ( env , subResult . getTruthValuesVector ( ) ) ;
return std : : unique_ptr < CheckResult > ( new ExplicitQuantitativeCheckResult < ValueType > ( std : : move ( values ) ) ) ;
}
template < typename SparseDtmcModelType >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : computeLongRunAverageRewards ( Environment const & env , storm : : logic : : RewardMeasureType rewardMeasureType , CheckTask < storm : : logic : : LongRunAverageRewardFormula , ValueType > const & checkTask ) {
auto rewardModel = storm : : utility : : createFilteredRewardModel ( this - > getModel ( ) , checkTask ) ;
@ -191,7 +268,7 @@ namespace storm {
auto values = helper . computeLongRunAverageRewards ( env , rewardModel . get ( ) ) ;
return std : : unique_ptr < CheckResult > ( new ExplicitQuantitativeCheckResult < ValueType > ( std : : move ( values ) ) ) ;
}
template < typename SparseDtmcModelType >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : computeConditionalProbabilities ( Environment const & env , CheckTask < storm : : logic : : ConditionalFormula , ValueType > const & checkTask ) {
storm : : logic : : ConditionalFormula const & conditionalFormula = checkTask . getFormula ( ) ;
@ -206,28 +283,28 @@ namespace storm {
std : : vector < ValueType > numericResult = storm : : modelchecker : : helper : : SparseDtmcPrctlHelper < ValueType > : : computeConditionalProbabilities ( env , storm : : solver : : SolveGoal < ValueType > ( this - > getModel ( ) , checkTask ) , this - > getModel ( ) . getTransitionMatrix ( ) , this - > getModel ( ) . getBackwardTransitions ( ) , leftResult . getTruthValuesVector ( ) , rightResult . getTruthValuesVector ( ) , checkTask . isQualitativeSet ( ) ) ;
return std : : unique_ptr < CheckResult > ( new ExplicitQuantitativeCheckResult < ValueType > ( std : : move ( numericResult ) ) ) ;
}
template < typename SparseDtmcModelType >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : computeConditionalRewards ( Environment const & env , storm : : logic : : RewardMeasureType , CheckTask < storm : : logic : : ConditionalFormula , ValueType > const & checkTask ) {
storm : : logic : : ConditionalFormula const & conditionalFormula = checkTask . getFormula ( ) ;
STORM_LOG_THROW ( conditionalFormula . getSubformula ( ) . isReachabilityRewardFormula ( ) , storm : : exceptions : : InvalidPropertyException , " Illegal conditional probability formula. " ) ;
STORM_LOG_THROW ( conditionalFormula . getConditionFormula ( ) . isEventuallyFormula ( ) , storm : : exceptions : : InvalidPropertyException , " Illegal conditional probability formula. " ) ;
std : : unique_ptr < CheckResult > leftResultPointer = this - > check ( env , conditionalFormula . getSubformula ( ) . asReachabilityRewardFormula ( ) . getSubformula ( ) ) ;
std : : unique_ptr < CheckResult > rightResultPointer = this - > check ( env , conditionalFormula . getConditionFormula ( ) . asEventuallyFormula ( ) . getSubformula ( ) ) ;
ExplicitQualitativeCheckResult const & leftResult = leftResultPointer - > asExplicitQualitativeCheckResult ( ) ;
ExplicitQualitativeCheckResult const & rightResult = rightResultPointer - > asExplicitQualitativeCheckResult ( ) ;
std : : vector < ValueType > numericResult = storm : : modelchecker : : helper : : SparseDtmcPrctlHelper < ValueType > : : computeConditionalRewards ( env , storm : : solver : : SolveGoal < ValueType > ( this - > getModel ( ) , checkTask ) , this - > getModel ( ) . getTransitionMatrix ( ) , this - > getModel ( ) . getBackwardTransitions ( ) , checkTask . isRewardModelSet ( ) ? this - > getModel ( ) . getRewardModel ( checkTask . getRewardModel ( ) ) : this - > getModel ( ) . getRewardModel ( " " ) , leftResult . getTruthValuesVector ( ) , rightResult . getTruthValuesVector ( ) , checkTask . isQualitativeSet ( ) ) ;
return std : : unique_ptr < CheckResult > ( new ExplicitQuantitativeCheckResult < ValueType > ( std : : move ( numericResult ) ) ) ;
}
template < >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < storm : : models : : sparse : : Dtmc < storm : : RationalFunction > > : : checkQuantileFormula ( Environment const & env , CheckTask < storm : : logic : : QuantileFormula , ValueType > const & checkTask ) {
STORM_LOG_THROW ( false , storm : : exceptions : : NotImplementedException , " Quantiles for parametric models are not implemented. " ) ;
}
template < typename SparseDtmcModelType >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < SparseDtmcModelType > : : checkQuantileFormula ( Environment const & env , CheckTask < storm : : logic : : QuantileFormula , ValueType > const & checkTask ) {
STORM_LOG_THROW ( checkTask . isOnlyInitialStatesRelevantSet ( ) , storm : : exceptions : : InvalidOperationException , " Computing quantiles is only supported for the initial states of a model. " ) ;
@ -236,19 +313,19 @@ namespace storm {
helper : : rewardbounded : : QuantileHelper < SparseDtmcModelType > qHelper ( this - > getModel ( ) , checkTask . getFormula ( ) ) ;
auto res = qHelper . computeQuantile ( env ) ;
if ( res . size ( ) = = 1 & & res . front ( ) . size ( ) = = 1 ) {
return std : : unique_ptr < CheckResult > ( new ExplicitQuantitativeCheckResult < ValueType > ( initialState , std : : move ( res . front ( ) . front ( ) ) ) ) ;
} else {
return std : : unique_ptr < CheckResult > ( new ExplicitParetoCurveCheckResult < ValueType > ( initialState , std : : move ( res ) ) ) ;
}
}
template < typename SparseCtmcModelType >
std : : unique_ptr < CheckResult > SparseDtmcPrctlModelChecker < SparseCtmcModelType > : : computeSteadyStateDistribution ( Environment const & env ) {
// Initialize helper
storm : : modelchecker : : helper : : SparseDeterministicInfiniteHorizonHelper < ValueType > helper ( this - > getModel ( ) . getTransitionMatrix ( ) ) ;
// Compute result
std : : vector < ValueType > result ;
auto const & initialStates = this - > getModel ( ) . getInitialStates ( ) ;
@ -265,7 +342,7 @@ namespace storm {
return std : : unique_ptr < CheckResult > ( new ExplicitQuantitativeCheckResult < ValueType > ( std : : move ( result ) ) ) ;
}
template class SparseDtmcPrctlModelChecker < storm : : models : : sparse : : Dtmc < double > > ;
# ifdef STORM_HAVE_CARL