@ -1,6 +1,7 @@ 
			
		 
		
	
		
			
				 
				 
				# include  "src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h" 
  
				 
				 
				# include  "src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h" 
  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				# include  <vector> 
  
				 
				 
				# include  <vector> 
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				# include  <memory> 
  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				# include  "src/utility/macros.h" 
  
				 
				 
				# include  "src/utility/macros.h" 
  
			
		 
		
	
		
			
				 
				 
				# include  "src/utility/vector.h" 
  
				 
				 
				# include  "src/utility/vector.h" 
  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -9,6 +10,8 @@ 
			
		 
		
	
		
			
				 
				 
				# include  "src/modelchecker/results/ExplicitQualitativeCheckResult.h" 
  
				 
				 
				# include  "src/modelchecker/results/ExplicitQualitativeCheckResult.h" 
  
			
		 
		
	
		
			
				 
				 
				# include  "src/modelchecker/results/ExplicitQuantitativeCheckResult.h" 
  
				 
				 
				# include  "src/modelchecker/results/ExplicitQuantitativeCheckResult.h" 
  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				# include  "src/storage/StronglyConnectedComponentDecomposition.h" 
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				# include  "src/exceptions/InvalidPropertyException.h" 
  
				 
				 
				# include  "src/exceptions/InvalidPropertyException.h" 
  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				namespace  storm  {  
				 
				 
				namespace  storm  {  
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -297,6 +300,132 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				            return  std : : unique_ptr < CheckResult > ( new  ExplicitQuantitativeCheckResult < ValueType > ( this - > computeReachabilityRewardsHelper ( subResult . getTruthValuesVector ( ) ,  qualitative ) ) ) ;  
				 
				 
				            return  std : : unique_ptr < CheckResult > ( new  ExplicitQuantitativeCheckResult < ValueType > ( this - > computeReachabilityRewardsHelper ( subResult . getTruthValuesVector ( ) ,  qualitative ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				        }  
				 
				 
				        }  
			
		 
		
	
		
			
				 
				 
				         
				 
				 
				         
			
		 
		
	
		
			
				 
				 
				 
				 
				 
						template < typename  ValueType >  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
						std : : vector < ValueType >  SparseDtmcPrctlModelChecker < ValueType > : : computeLongRunAverageHelper ( bool  minimize ,  storm : : storage : : BitVector  const &  psiStates ,  bool  qualitative )  const  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							// If there are no goal states, we avoid the computation and directly return zero.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							auto  numOfStates  =  this - > getModel ( ) . getNumberOfStates ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							if  ( psiStates . empty ( ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								return  std : : vector < ValueType > ( numOfStates ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							}  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							// Likewise, if all bits are set, we can avoid the computation and set.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							if  ( ( ~ psiStates ) . empty ( ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								return  std : : vector < ValueType > ( numOfStates ,  storm : : utility : : one < ValueType > ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							}  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							// Start by decomposing the DTMC into its BSCCs.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							storm : : storage : : StronglyConnectedComponentDecomposition < double >  bsccDecomposition ( this - > getModelAs < storm : : models : : AbstractModel < ValueType > > ( ) ,  false ,  true ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							// Get some data members for convenience.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							typename  storm : : storage : : SparseMatrix < ValueType >  const &  transitionMatrix  =  this - > getModel ( ) . getTransitionMatrix ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							// Now start with compute the long-run average for all BSCCs in isolation.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							std : : vector < ValueType >  lraValuesForBsccs ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							// While doing so, we already gather some information for the following steps.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							std : : vector < uint_fast64_t >  stateToBsccIndexMap ( numOfStates ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							storm : : storage : : BitVector  statesInBsccs ( numOfStates ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							for  ( uint_fast64_t  currentBsccIndex  =  0 ;  currentBsccIndex  <  bsccDecomposition . size ( ) ;  + + currentBsccIndex )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								storm : : storage : : StronglyConnectedComponent  const &  bscc  =  bsccDecomposition [ currentBsccIndex ] ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								// Gather information for later use.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								for  ( auto  const &  state  :  bscc )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
									statesInBsccs . set ( state ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
									stateToBsccIndexMap [ state ]  =  currentBsccIndex ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								}  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								// Compute the LRA value for the current BSCC
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								lraValuesForBsccs . push_back ( this - > computeLraForBSCC ( transitionMatrix ,  psiStates ,  bscc ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							}  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							// For fast transition rewriting, we build some auxiliary data structures.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							storm : : storage : : BitVector  statesNotContainedInAnyBscc  =  ~ statesInBsccs ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							// Prepare result vector.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							std : : vector < ValueType >  result ( numOfStates ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							//Set the values for all states in BSCCs.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							for  ( auto  state  :  statesInBsccs )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								result [ state ]  =  lraValuesForBsccs [ stateToBsccIndexMap [ state ] ] ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							}  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							//for all states not in any bscc set the result to the minimal/maximal value of the reachable BSCCs
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							//there might be a more efficient way to do this...
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							for  ( auto  state  :  statesNotContainedInAnyBscc ) {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								//calculate what result values the reachable states in BSCCs have
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								storm : : storage : : BitVector  currentState ( numOfStates ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								currentState . set ( state ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								storm : : storage : : BitVector  reachableStates  =  storm : : utility : : graph : : getReachableStates (  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
									transitionMatrix ,  currentState ,  storm : : storage : : BitVector ( numOfStates ,  true ) ,  statesInBsccs  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
									) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								storm : : storage : : BitVector  reachableBsccStates  =  statesInBsccs  &  reachableStates ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								std : : vector < ValueType >  reachableResults ( reachableBsccStates . getNumberOfSetBits ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								storm : : utility : : vector : : selectVectorValues ( reachableResults ,  reachableBsccStates ,  result ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								//now select the minimal/maximal element
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								if  ( minimize ) {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
									result [ state ]  =  * std : : min_element ( reachableResults . begin ( ) ,  reachableResults . end ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								}  else  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
									result [ state ]  =  * std : : max_element ( reachableResults . begin ( ) ,  reachableResults . end ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								}  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							}  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							return  result ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
						}  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
						template < typename  ValueType >  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
						std : : unique_ptr < CheckResult >  SparseDtmcPrctlModelChecker < ValueType > : : computeLongRunAverage ( storm : : logic : : StateFormula  const &  stateFormula ,  bool  qualitative ,  boost : : optional < storm : : logic : : OptimalityType >  const &  optimalityType )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							STORM_LOG_THROW ( optimalityType ,  storm : : exceptions : : InvalidArgumentException ,  " Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model. " ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							std : : unique_ptr < CheckResult >  subResultPointer  =  this - > check ( stateFormula ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							ExplicitQualitativeCheckResult  const &  subResult  =  subResultPointer - > asExplicitQualitativeCheckResult ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							return  std : : unique_ptr < CheckResult > ( new  ExplicitQuantitativeCheckResult < ValueType > ( this - > computeLongRunAverageHelper ( optimalityType . get ( )  = =  storm : : logic : : OptimalityType : : Minimize ,  subResult . getTruthValuesVector ( ) ,  qualitative ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
						}  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
						template < typename  ValueType >  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
						ValueType  SparseDtmcPrctlModelChecker < ValueType > : : computeLraForBSCC ( storm : : storage : : SparseMatrix < ValueType >  const &  transitionMatrix ,  storm : : storage : : BitVector  const &  psiStates ,  storm : : storage : : StronglyConnectedComponent  const &  bscc )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							//if size is one we can immediately derive the result
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							if  ( bscc . size ( )  = =  1 ) {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								if  ( psiStates . get ( * ( bscc . begin ( ) ) ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
									return  storm : : utility : : one < ValueType > ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								}  else {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
									return  storm : : utility : : zero < ValueType > ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								}  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							}  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							std : : unique_ptr < storm : : solver : : LinearEquationSolver < ValueType > >  solver  =  storm : : utility : : solver : : getLinearEquationSolver < ValueType > ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							storm : : storage : : BitVector  subsystem  =  storm : : storage : : BitVector ( transitionMatrix . getRowCount ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							subsystem . set ( bscc . begin ( ) ,  bscc . end ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							storm : : storage : : SparseMatrix < ValueType >  subsystemMatrix  =  transitionMatrix . getSubmatrix ( false ,  subsystem ,  subsystem ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							std : : vector < ValueType >  steadyStateDist ( subsystemMatrix . getRowCount ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							steadyStateDist [ 0 ]  =  storm : : utility : : one < ValueType > ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							solver - > solveEquationSystem ( subsystemMatrix ,  steadyStateDist ,  steadyStateDist ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							ValueType  length  =  storm : : utility : : zero < ValueType > ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							for  ( auto  value  :  steadyStateDist )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								length  + =  value ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							}  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							storm : : utility : : vector : : scaleVectorInPlace ( steadyStateDist ,  storm : : utility : : one < ValueType > ( )  /  length ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							std : : vector < ValueType >  steadyStateForPsiStates ( transitionMatrix . getRowCount ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							storm : : utility : : vector : : setVectorValues ( steadyStateForPsiStates ,  psiStates  &  subsystem ,  steadyStateDist ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							ValueType  result  =  storm : : utility : : zero < ValueType > ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							for  ( auto  value  :  steadyStateForPsiStates )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
								result  + =  value ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							}  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
							return  result ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
						}  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				        template < typename  ValueType >  
				 
				 
				        template < typename  ValueType >  
			
		 
		
	
		
			
				 
				 
				        storm : : models : : Dtmc < ValueType >  const &  SparseDtmcPrctlModelChecker < ValueType > : : getModel ( )  const  {  
				 
				 
				        storm : : models : : Dtmc < ValueType >  const &  SparseDtmcPrctlModelChecker < ValueType > : : getModel ( )  const  {  
			
		 
		
	
		
			
				 
				 
				            return  this - > template  getModelAs < storm : : models : : Dtmc < ValueType > > ( ) ;  
				 
				 
				            return  this - > template  getModelAs < storm : : models : : Dtmc < ValueType > > ( ) ;