@ -1,4 +1,4 @@
# include "src/modelchecker/exploration/SparseMdp ExplorationModelChecker.h"
# include "src/modelchecker/exploration/SparseExplorationModelChecker.h"
# include "src/modelchecker/exploration/ExplorationInformation.h"
# include "src/modelchecker/exploration/StateGeneration.h"
@ -33,20 +33,20 @@
namespace storm {
namespace modelchecker {
template < typename ValueType >
SparseMdp ExplorationModelChecker < ValueType > : : SparseMdp ExplorationModelChecker ( storm : : prism : : Program const & program , boost : : optional < std : : map < storm : : expressions : : Variable , storm : : expressions : : Expression > > const & constantDefinitions ) : program ( storm : : utility : : prism : : preprocessProgram < ValueType > ( program , constantDefinitions ) ) , variableInformation ( this - > program ) , randomGenerator ( std : : chrono : : system_clock : : now ( ) . time_since_epoch ( ) . count ( ) ) , comparator ( ) {
template < typename ValueType , typename StateType >
SparseExplorationModelChecker < ValueType , StateType > : : SparseExplorationModelChecker ( storm : : prism : : Program const & program , boost : : optional < std : : map < storm : : expressions : : Variable , storm : : expressions : : Expression > > const & constantDefinitions ) : program ( storm : : utility : : prism : : preprocessProgram < ValueType > ( program , constantDefinitions ) ) , variableInformation ( this - > program ) , randomGenerator ( std : : chrono : : system_clock : : now ( ) . time_since_epoch ( ) . count ( ) ) , comparator ( storm : : settings : : explorationSettings ( ) . getPrecision ( ) ) {
// Intentionally left empty.
}
template < typename ValueType >
bool SparseMdp ExplorationModelChecker < ValueType > : : canHandle ( CheckTask < storm : : logic : : Formula > const & checkTask ) const {
template < typename ValueType , typename StateType >
bool SparseExplorationModelChecker < ValueType , Stat eType > : : canHandle ( CheckTask < storm : : logic : : Formula > const & checkTask ) const {
storm : : logic : : Formula const & formula = checkTask . getFormula ( ) ;
storm : : logic : : FragmentSpecification fragment = storm : : logic : : reachability ( ) ;
return formula . isInFragment ( fragment ) & & checkTask . isOnlyInitialStatesRelevantSet ( ) ;
}
template < typename ValueType >
std : : unique_ptr < CheckResult > SparseMdp ExplorationModelChecker < ValueType > : : computeUntilProbabilities ( CheckTask < storm : : logic : : UntilFormula > const & checkTask ) {
template < typename ValueType , typename StateType >
std : : unique_ptr < CheckResult > SparseExplorationModelChecker < ValueType , Stat eType > : : computeUntilProbabilities ( CheckTask < storm : : logic : : UntilFormula > const & checkTask ) {
storm : : logic : : UntilFormula const & untilFormula = checkTask . getFormula ( ) ;
storm : : logic : : Formula const & conditionFormula = untilFormula . getLeftSubformula ( ) ;
storm : : logic : : Formula const & targetFormula = untilFormula . getRightSubformula ( ) ;
@ -66,8 +66,8 @@ namespace storm {
return std : : make_unique < ExplicitQuantitativeCheckResult < ValueType > > ( std : : get < 0 > ( boundsForInitialState ) , std : : get < 1 > ( boundsForInitialState ) ) ;
}
template < typename ValueType >
std : : tuple < typename SparseMdpExplorationModelChecker < ValueType > : : StateType , ValueType , ValueType > SparseMdpExplorationModelChecker < Valu eType> : : performExploration ( StateGeneration < StateType , ValueType > & stateGeneration , ExplorationInformation < StateType , ValueType > & explorationInformation ) const {
template < typename ValueType , typename StateType >
std : : tuple < StateType , ValueType , ValueType > SparseExplorationModelChecker < ValueType , Stat eType> : : performExploration ( StateGeneration < StateType , ValueType > & stateGeneration , ExplorationInformation < StateType , ValueType > & explorationInformation ) const {
// Generate the initial state so we know where to start the simulation.
stateGeneration . computeInitialStates ( ) ;
STORM_LOG_THROW ( stateGeneration . getNumberOfInitialStates ( ) = = 1 , storm : : exceptions : : NotSupportedException , " Currently only models with one initial state are supported by the exploration engine. " ) ;
@ -119,8 +119,8 @@ namespace storm {
return std : : make_tuple ( initialStateIndex , bounds . getLowerBoundForState ( initialStateIndex , explorationInformation ) , bounds . getUpperBoundForState ( initialStateIndex , explorationInformation ) ) ;
}
template < typename ValueType >
bool SparseMdp ExplorationModelChecker < ValueType > : : samplePathFromInitialState ( StateGeneration < StateType , ValueType > & stateGeneration , ExplorationInformation < StateType , ValueType > & explorationInformation , StateActionStack & stack , Bounds < StateType , ValueType > & bounds , Statistics < StateType , ValueType > & stats ) const {
template < typename ValueType , typename StateType >
bool SparseExplorationModelChecker < ValueType , Stat eType > : : samplePathFromInitialState ( StateGeneration < StateType , ValueType > & stateGeneration , ExplorationInformation < StateType , ValueType > & explorationInformation , StateActionStack & stack , Bounds < StateType , ValueType > & bounds , Statistics < StateType , ValueType > & stats ) const {
// Start the search from the initial state.
stack . push_back ( std : : make_pair ( stateGeneration . getFirstInitialState ( ) , 0 ) ) ;
@ -181,8 +181,8 @@ namespace storm {
return foundTerminalState ;
}
template < typename ValueType >
bool SparseMdp ExplorationModelChecker < ValueType > : : exploreState ( StateGeneration < StateType , ValueType > & stateGeneration , StateType const & currentStateId , storm : : generator : : CompressedState const & currentState , ExplorationInformation < StateType , ValueType > & explorationInformation , Bounds < StateType , ValueType > & bounds , Statistics < StateType , ValueType > & stats ) const {
template < typename ValueType , typename StateType >
bool SparseExplorationModelChecker < ValueType , Stat eType > : : exploreState ( StateGeneration < StateType , ValueType > & stateGeneration , StateType const & currentStateId , storm : : generator : : CompressedState const & currentState , ExplorationInformation < StateType , ValueType > & explorationInformation , Bounds < StateType , ValueType > & bounds , Statistics < StateType , ValueType > & stats ) const {
bool isTerminalState = false ;
bool isTargetState = false ;
@ -283,8 +283,8 @@ namespace storm {
return isTerminalState ;
}
template < typename ValueType >
typename SparseMdp ExplorationModelChecker < ValueType > : : ActionType SparseMdp ExplorationModelChecker < ValueType > : : sampleActionOfState ( StateType const & currentStateId , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > & bounds ) const {
template < typename ValueType , typename StateType >
typename SparseExplorationModelChecker < ValueType , Stat eType > : : ActionType SparseExplorationModelChecker < ValueType , Stat eType > : : sampleActionOfState ( StateType const & currentStateId , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > & bounds ) const {
// Determine the values of all available actions.
std : : vector < std : : pair < ActionType , ValueType > > actionValues ;
StateType rowGroup = explorationInformation . getRowGroup ( currentStateId ) ;
@ -321,14 +321,13 @@ namespace storm {
return actionValues [ distribution ( randomGenerator ) ] . first ;
}
template < typename ValueType >
typename SparseMdp ExplorationModelChecker< ValueType > : : StateType SparseMdpExplorationModelChecker < Valu eType> : : sampleSuccessorFromAction ( ActionType const & chosenAction , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > const & bounds ) const {
template < typename ValueType , typename StateType >
StateType Sparse ExplorationModelChecker< ValueType , Stat eType> : : sampleSuccessorFromAction ( ActionType const & chosenAction , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > const & bounds ) const {
std : : vector < storm : : storage : : MatrixEntry < StateType , ValueType > > const & row = explorationInformation . getRowOfMatrix ( chosenAction ) ;
if ( row . size ( ) = = 1 ) {
return row . front ( ) . getColumn ( ) ;
}
// Depending on the selected next-state heuristic, we give the states other likelihoods of getting chosen.
if ( explorationInformation . useDifferenceProbabilitySumHeuristic ( ) | | explorationInformation . useProbabilityHeuristic ( ) ) {
std : : vector < ValueType > probabilities ( row . size ( ) ) ;
@ -347,14 +346,15 @@ namespace storm {
// Now sample according to the probabilities.
std : : discrete_distribution < StateType > distribution ( probabilities . begin ( ) , probabilities . end ( ) ) ;
return row [ distribution ( randomGenerator ) ] . getColumn ( ) ;
} else if ( explorationInformation . useUniformHeuristic ( ) ) {
} else {
STORM_LOG_ASSERT ( explorationInformation . useUniformHeuristic ( ) , " Illegal next-state heuristic. " ) ;
std : : uniform_int_distribution < ActionType > distribution ( 0 , row . size ( ) - 1 ) ;
return row [ distribution ( randomGenerator ) ] . getColumn ( ) ;
}
}
template < typename ValueType >
bool SparseMdp ExplorationModelChecker < ValueType > : : performPrecomputation ( StateActionStack const & stack , ExplorationInformation < StateType , ValueType > & explorationInformation , Bounds < StateType , ValueType > & bounds , Statistics < StateType , ValueType > & stats ) const {
template < typename ValueType , typename StateType >
bool SparseExplorationModelChecker < ValueType , Stat eType > : : performPrecomputation ( StateActionStack const & stack , ExplorationInformation < StateType , ValueType > & explorationInformation , Bounds < StateType , ValueType > & bounds , Statistics < StateType , ValueType > & stats ) const {
+ + stats . numberOfPrecomputations ;
// Outline:
@ -370,7 +370,7 @@ namespace storm {
std : : vector < StateType > relevantStates ;
if ( explorationInformation . useLocalPrecomputation ( ) ) {
for ( auto const & stateActionPair : stack ) {
if ( explorationInformation . maximize ( ) | | ! comparator . isOne ( bounds . getLowerBoundForState ( stateActionPair . first , explorationInformation ) ) ) {
if ( explorationInformation . maximize ( ) | | ! storm : : utility : : isOne ( bounds . getLowerBoundForState ( stateActionPair . first , explorationInformation ) ) ) {
relevantStates . push_back ( stateActionPair . first ) ;
}
}
@ -486,8 +486,8 @@ namespace storm {
return true ;
}
template < typename ValueType >
void SparseMdp ExplorationModelChecker < ValueType > : : collapseMec ( storm : : storage : : MaximalEndComponent const & mec , std : : vector < StateType > const & relevantStates , storm : : storage : : SparseMatrix < ValueType > const & relevantStatesMatrix , ExplorationInformation < StateType , ValueType > & explorationInformation , Bounds < StateType , ValueType > & bounds ) const {
template < typename ValueType , typename StateType >
void SparseExplorationModelChecker < ValueType , Stat eType > : : collapseMec ( storm : : storage : : MaximalEndComponent const & mec , std : : vector < StateType > const & relevantStates , storm : : storage : : SparseMatrix < ValueType > const & relevantStatesMatrix , ExplorationInformation < StateType , ValueType > & explorationInformation , Bounds < StateType , ValueType > & bounds ) const {
bool containsTargetState = false ;
// Now we record all actions leaving the EC.
@ -498,7 +498,7 @@ namespace storm {
StateType originalRowGroup = explorationInformation . getRowGroup ( originalState ) ;
// Check whether a target state is contained in the MEC.
if ( ! containsTargetState & & comparator . isOne ( bounds . getLowerBoundForRowGroup ( originalRowGroup ) ) ) {
if ( ! containsTargetState & & storm : : utility : : isOne ( bounds . getLowerBoundForRowGroup ( originalRowGroup ) ) ) {
containsTargetState = true ;
}
@ -555,8 +555,8 @@ namespace storm {
}
}
template < typename ValueType >
ValueType SparseMdp ExplorationModelChecker < ValueType > : : computeLowerBoundOfAction ( ActionType const & action , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > const & bounds ) const {
template < typename ValueType , typename StateType >
ValueType SparseExplorationModelChecker < ValueType , Stat eType > : : computeLowerBoundOfAction ( ActionType const & action , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > const & bounds ) const {
ValueType result = storm : : utility : : zero < ValueType > ( ) ;
for ( auto const & element : explorationInformation . getRowOfMatrix ( action ) ) {
result + = element . getValue ( ) * bounds . getLowerBoundForState ( element . getColumn ( ) , explorationInformation ) ;
@ -564,8 +564,8 @@ namespace storm {
return result ;
}
template < typename ValueType >
ValueType SparseMdp ExplorationModelChecker < ValueType > : : computeUpperBoundOfAction ( ActionType const & action , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > const & bounds ) const {
template < typename ValueType , typename StateType >
ValueType SparseExplorationModelChecker < ValueType , Stat eType > : : computeUpperBoundOfAction ( ActionType const & action , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > const & bounds ) const {
ValueType result = storm : : utility : : zero < ValueType > ( ) ;
for ( auto const & element : explorationInformation . getRowOfMatrix ( action ) ) {
result + = element . getValue ( ) * bounds . getUpperBoundForState ( element . getColumn ( ) , explorationInformation ) ;
@ -573,8 +573,8 @@ namespace storm {
return result ;
}
template < typename ValueType >
std : : pair < ValueType , ValueType > SparseMdp ExplorationModelChecker < ValueType > : : computeBoundsOfAction ( ActionType const & action , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > const & bounds ) const {
template < typename ValueType , typename StateType >
std : : pair < ValueType , ValueType > SparseExplorationModelChecker < ValueType , Stat eType > : : computeBoundsOfAction ( ActionType const & action , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > const & bounds ) const {
// TODO: take into account self-loops?
std : : pair < ValueType , ValueType > result = std : : make_pair ( storm : : utility : : zero < ValueType > ( ) , storm : : utility : : zero < ValueType > ( ) ) ;
for ( auto const & element : explorationInformation . getRowOfMatrix ( action ) ) {
@ -584,8 +584,8 @@ namespace storm {
return result ;
}
template < typename ValueType >
std : : pair < ValueType , ValueType > SparseMdp ExplorationModelChecker < ValueType > : : computeBoundsOfState ( StateType const & currentStateId , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > const & bounds ) const {
template < typename ValueType , typename StateType >
std : : pair < ValueType , ValueType > SparseExplorationModelChecker < ValueType , Stat eType > : : computeBoundsOfState ( StateType const & currentStateId , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > const & bounds ) const {
StateType group = explorationInformation . getRowGroup ( currentStateId ) ;
std : : pair < ValueType , ValueType > result = getLowestBounds ( explorationInformation . getOptimizationDirection ( ) ) ;
for ( ActionType action = explorationInformation . getStartRowOfGroup ( group ) ; action < explorationInformation . getStartRowOfGroup ( group + 1 ) ; + + action ) {
@ -595,8 +595,8 @@ namespace storm {
return result ;
}
template < typename ValueType >
void SparseMdp ExplorationModelChecker < ValueType > : : updateProbabilityBoundsAlongSampledPath ( StateActionStack & stack , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > & bounds ) const {
template < typename ValueType , typename StateType >
void SparseExplorationModelChecker < ValueType , Stat eType > : : updateProbabilityBoundsAlongSampledPath ( StateActionStack & stack , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > & bounds ) const {
stack . pop_back ( ) ;
while ( ! stack . empty ( ) ) {
updateProbabilityOfAction ( stack . back ( ) . first , stack . back ( ) . second , explorationInformation , bounds ) ;
@ -604,8 +604,8 @@ namespace storm {
}
}
template < typename ValueType >
void SparseMdp ExplorationModelChecker < ValueType > : : updateProbabilityOfAction ( StateType const & state , ActionType const & action , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > & bounds ) const {
template < typename ValueType , typename StateType >
void SparseExplorationModelChecker < ValueType , Stat eType > : : updateProbabilityOfAction ( StateType const & state , ActionType const & action , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > & bounds ) const {
// Compute the new lower/upper values of the action.
std : : pair < ValueType , ValueType > newBoundsForAction = computeBoundsOfAction ( action , explorationInformation , bounds ) ;
@ -639,8 +639,8 @@ namespace storm {
}
}
template < typename ValueType >
ValueType SparseMdp ExplorationModelChecker < ValueType > : : computeBoundOverAllOtherActions ( storm : : OptimizationDirection const & direction , StateType const & state , ActionType const & action , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > const & bounds ) const {
template < typename ValueType , typename StateType >
ValueType SparseExplorationModelChecker < ValueType , Stat eType > : : computeBoundOverAllOtherActions ( storm : : OptimizationDirection const & direction , StateType const & state , ActionType const & action , ExplorationInformation < StateType , ValueType > const & explorationInformation , Bounds < StateType , ValueType > const & bounds ) const {
ValueType bound = getLowestBound ( explorationInformation . getOptimizationDirection ( ) ) ;
ActionType group = explorationInformation . getRowGroup ( state ) ;
@ -658,14 +658,14 @@ namespace storm {
return bound ;
}
template < typename ValueType >
std : : pair < ValueType , ValueType > SparseMdp ExplorationModelChecker < ValueType > : : getLowestBounds ( storm : : OptimizationDirection const & direction ) const {
template < typename ValueType , typename StateType >
std : : pair < ValueType , ValueType > SparseExplorationModelChecker < ValueType , Stat eType > : : getLowestBounds ( storm : : OptimizationDirection const & direction ) const {
ValueType val = getLowestBound ( direction ) ;
return std : : make_pair ( val , val ) ;
}
template < typename ValueType >
ValueType SparseMdp ExplorationModelChecker < ValueType > : : getLowestBound ( storm : : OptimizationDirection const & direction ) const {
template < typename ValueType , typename StateType >
ValueType SparseExplorationModelChecker < ValueType , Stat eType > : : getLowestBound ( storm : : OptimizationDirection const & direction ) const {
if ( direction = = storm : : OptimizationDirection : : Maximize ) {
return storm : : utility : : zero < ValueType > ( ) ;
} else {
@ -673,8 +673,8 @@ namespace storm {
}
}
template < typename ValueType >
std : : pair < ValueType , ValueType > SparseMdp ExplorationModelChecker < ValueType > : : combineBounds ( storm : : OptimizationDirection const & direction , std : : pair < ValueType , ValueType > const & bounds1 , std : : pair < ValueType , ValueType > const & bounds2 ) const {
template < typename ValueType , typename StateType >
std : : pair < ValueType , ValueType > SparseExplorationModelChecker < ValueType , Stat eType > : : combineBounds ( storm : : OptimizationDirection const & direction , std : : pair < ValueType , ValueType > const & bounds1 , std : : pair < ValueType , ValueType > const & bounds2 ) const {
if ( direction = = storm : : OptimizationDirection : : Maximize ) {
return std : : make_pair ( std : : max ( bounds1 . first , bounds2 . first ) , std : : max ( bounds1 . second , bounds2 . second ) ) ;
} else {
@ -682,6 +682,6 @@ namespace storm {
}
}
template class SparseMdp ExplorationModelChecker < double > ;
template class SparseExplorationModelChecker < double , uint32_t > ;
}
}