@ -88,17 +88,17 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if ( ! this - > isResultConstant ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                //now create the model used for Approximation
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if ( storm : : settings : : regionSettings ( ) . doApprox ( ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    initializeApproximationModel ( * this - > simplifi ed Model ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    initializeApproximationModel ( * this - > simpleModel ,  this - > simpleFormula ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                //now create the model used for Sampling
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if ( storm : : settings : : regionSettings ( ) . getSampleMode ( ) = = storm : : settings : : modules : : RegionSettings : : SampleMode : : INSTANTIATE  | |  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        ( ! storm : : settings : : regionSettings ( ) . doSample ( )  & &  storm : : settings : : regionSettings ( ) . getApproxMode ( ) = = storm : : settings : : modules : : RegionSettings : : ApproxMode : : TESTFIRST ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    initializeSamplingModel ( * this - > simplifi ed Model ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    initializeSamplingModel ( * this - > simpleModel ,  this - > simpleFormula ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                //Check if the reachability function needs to be computed
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if ( ( storm : : settings : : regionSettings ( ) . getSmtMode ( ) = = storm : : settings : : modules : : RegionSettings : : SmtMode : : FUNCTION )  | |   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        ( storm : : settings : : regionSettings ( ) . getSampleMode ( ) = = storm : : settings : : modules : : RegionSettings : : SampleMode : : EVALUATE ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    computeReachabilityFunction ( * this - > simplifi ed Model ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    computeReachabilityFunction ( * this - > simpleModel ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            //some information for statistics...
  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -148,7 +148,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // We then build the submatrix that only has the transitions of the maybe states.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            storm : : storage : : SparseMatrix < ParametricType >  submatrix  =  this - > model . getTransitionMatrix ( ) . getSubmatrix ( false ,  maybeStates ,  maybeStates ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // e liminate all states with only constant outgoing transitions (and possibly rewards) 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // E liminate all states with only constant outgoing transitions
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Convert the reduced matrix to a more flexible format to be able to perform state elimination more easily.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            auto  flexibleTransitions  =  this - > eliminationModelChecker . getFlexibleSparseMatrix ( submatrix ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            auto  flexibleBackwardTransitions =  this - > eliminationModelChecker . getFlexibleSparseMatrix ( submatrix . transpose ( ) ,  true ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -157,27 +157,21 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            //The states that we consider to eliminate
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            storm : : storage : : BitVector  considerToEliminate ( submatrix . getRowCount ( ) ,  true ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            considerToEliminate . set ( initialState ,  false ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > isApproximationApplicable = true ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > isResultConstant = true ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( auto  const &  state  :  considerToEliminate )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                bool  eliminateThisState = true ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for ( auto  const &  entry  :  flexibleTransitions . getRow ( state ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if ( ! this - > parametricTypeComparator . isConstant ( entry . getValue ( ) ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        this - > isResultConstant = false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        eliminateThisState = false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        this - > isApproximationApplicable  & =  storm : : utility : : regions : : functionIsLinear < ParametricType > ( entry . getValue ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        break ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if ( ! this - > parametricTypeComparator . isConstant ( oneStepProbabilities [ state ] ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    this - > isResultConstant = false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    eliminateThisState = false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    this - > isApproximationApplicable  & =  storm : : utility : : regions : : functionIsLinear < ParametricType > ( oneStepProbabilities [ state ] ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if ( this - > computeRewards  & &  eliminateThisState  & &  ! this - > parametricTypeComparator . isConstant ( stateRewards . get ( ) [ state ] ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    //Note: The state reward does not need to be constant but we need to make sure that
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    //no parameter of this reward function occurs as a parameter in the probability functions of the predecessors
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // (otherwise, more complex functions might occur in our simplified model)
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // TODO: test if we should really remove these states (the resulting reward functions are less simple this way)
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // (otherwise, more complex functions might occur in our simple model)
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    std : : set < VariableType >  probVars ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    for ( auto  const &  predecessor  :  flexibleBackwardTransitions . getRow ( state ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        for ( auto  const &  predecessorTransition  :  flexibleTransitions . getRow ( predecessor . getColumn ( ) ) ) {  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -199,48 +193,8 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_DEBUG ( " Eliminated  "  < <  subsystem . size ( )  -  subsystem . getNumberOfSetBits ( )  < <  "  of  "  < <  subsystem . size ( )  < <  "  states that had constant outgoing transitions. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if ( this - > isResultConstant ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                //Check if this is also the case for the initial state
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for ( auto  const &  entry  :  flexibleTransitions . getRow ( initialState ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    this - > isResultConstant & = this - > parametricTypeComparator . isConstant ( entry . getValue ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                this - > isResultConstant & = this - > parametricTypeComparator . isConstant ( oneStepProbabilities [ initialState ] ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if ( this - > computeRewards  & &  ( this - > isApproximationApplicable  | |  this - > isResultConstant ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                //We will need to check whether this is also the case for the reward functions.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for ( auto  const &  state  :  maybeStates ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    std : : set < VariableType >  rewardVars ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if ( this - > model . hasStateRewards ( )  & &  ! this - > parametricTypeComparator . isConstant ( this - > model . getStateRewardVector ( ) [ state ] ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        this - > isResultConstant = false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        this - > isApproximationApplicable  & =  storm : : utility : : regions : : functionIsLinear < ParametricType > ( this - > model . getStateRewardVector ( ) [ state ] ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        storm : : utility : : regions : : gatherOccurringVariables ( stateRewards . get ( ) [ state ] ,  rewardVars ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if ( this - > model . hasTransitionRewards ( ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        for ( auto  const &  entry  :  this - > model . getTransitionRewardMatrix ( ) . getRow ( state ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            if ( ! this - > parametricTypeComparator . isConstant ( entry . getValue ( ) ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                this - > isResultConstant = false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                this - > isApproximationApplicable  & =  storm : : utility : : regions : : functionIsLinear < ParametricType > ( entry . getValue ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                storm : : utility : : regions : : gatherOccurringVariables ( entry . getValue ( ) ,  rewardVars ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if ( ! rewardVars . empty ( ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        std : : set < VariableType >  probVars ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        for ( auto  const &  entry :  this - > model . getTransitionMatrix ( ) . getRow ( state ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            storm : : utility : : regions : : gatherOccurringVariables ( entry . getValue ( ) ,  probVars ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        for ( auto  const &  rewardVar  :  rewardVars ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            if ( probVars . find ( rewardVar ) ! = probVars . end ( ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                this - > isApproximationApplicable = false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                break ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_WARN_COND ( ! this - > isResultConstant ,  " For the given property, the reachability Value is constant, i.e., independent of the region " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            //Build the simplifi ed  model
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            //Build the simple model
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            //The matrix. The flexibleTransitions matrix might have empty rows where states have been eliminated.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            //The new matrix should not have such rows. We therefore leave them out, but we have to change the indices of the states accordingly.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < storm : : storage : : sparse : : state_type >  newStateIndexMap ( flexibleTransitions . getNumberOfRows ( ) ,  flexibleTransitions . getNumberOfRows ( ) ) ;  //initialize with some illegal index to easily check if a transition leads to an unselected state
  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -258,25 +212,25 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for ( storm : : storage : : sparse : : state_type  oldStateIndex  :  subsystem ) {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                ParametricType  missingProbability = storm : : utility : : regions : : getNewFunction < ParametricType ,  CoefficientType > ( storm : : utility : : one < CoefficientType > ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                //go through columns:
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for ( auto  const  &  entry :  flexibleTransitions . getRow ( oldStateIndex ) ) {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for ( auto &  entry :  flexibleTransitions . getRow ( oldStateIndex ) ) {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    STORM_LOG_THROW ( newStateIndexMap [ entry . getColumn ( ) ] ! = flexibleTransitions . getNumberOfRows ( ) ,  storm : : exceptions : : UnexpectedException ,  " There is a transition to a state that should have been eliminated. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    missingProbability - = entry . getValue ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    matrixBuilder . addNextValue ( newStateIndexMap [ oldStateIndex ] , newStateIndexMap [ entry . getColumn ( ) ] , entry . getValue ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    matrixBuilder . addNextValue ( newStateIndexMap [ oldStateIndex ] , newStateIndexMap [ entry . getColumn ( ) ] ,  storm : : utility : : simplify (  entry . getValue ( ) ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if ( this - > computeRewards ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // the missing probability always leads to target
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if ( ! this - > parametricTypeComparator . isZero ( missingProbability ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        matrixBuilder . addNextValue ( newStateIndexMap [ oldStateIndex ] ,  targetState , missingProbability ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        matrixBuilder . addNextValue ( newStateIndexMap [ oldStateIndex ] ,  targetState ,  storm : : utility : : simplify (  missingProbability ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  else {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    //transition to target state
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if ( ! this - > parametricTypeComparator . isZero ( oneStepProbabilities [ oldStateIndex ] ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        missingProbability - = oneStepProbabilities [ oldStateIndex ] ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        matrixBuilder . addNextValue ( newStateIndexMap [ oldStateIndex ] ,  targetState ,  oneStepProbabilities [ oldStateIndex ] ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        matrixBuilder . addNextValue ( newStateIndexMap [ oldStateIndex ] ,  targetState ,  storm : : utility : : simplify ( oneStepProbabilities [ oldStateIndex ] ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    //transition to sink state
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if ( ! this - > parametricTypeComparator . isZero ( missingProbability ) ) {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        matrixBuilder . addNextValue ( newStateIndexMap [ oldStateIndex ] ,  sinkState ,  missingProbability ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        matrixBuilder . addNextValue ( newStateIndexMap [ oldStateIndex ] ,  sinkState ,  storm : : utility : : simplify ( missingProbability ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -296,14 +250,29 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            labeling . addLabel ( " sink " ,  std : : move ( sinkLabel ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // other ingredients
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if ( this - > computeRewards ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : utility : : vector : : selectVectorValues ( stateRewards . get ( ) ,  subsystem ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                stateRewards - > push_back ( storm : : utility : : zero < ParametricType > ( ) ) ;  //target state
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                stateRewards - > push_back ( storm : : utility : : zero < ParametricType > ( ) ) ;  //sink state
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : size_t  newState  =  0 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( auto  oldstate  :  subsystem )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if ( oldstate ! = newState ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        stateRewards . get ( ) [ newState + + ]  =  std : : move ( storm : : utility : : simplify ( stateRewards . get ( ) [ oldstate ] ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        + + newState ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                stateRewards . get ( ) [ newState + + ]  =  storm : : utility : : zero < ParametricType > ( ) ;  //target state
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                stateRewards . get ( ) [ newState + + ]  =  storm : : utility : : zero < ParametricType > ( ) ;  //sink state
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                stateRewards . get ( ) . resize ( newState ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            boost : : optional < storm : : storage : : SparseMatrix < ParametricType > >  noTransitionRewards ;    
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            boost : : optional < std : : vector < boost : : container : : flat_set < uint_fast64_t > > >  noChoiceLabeling ;              
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // the final model
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > simplifiedModel  =  std : : make_shared < storm : : models : : sparse : : Dtmc < ParametricType > > ( matrixBuilder . build ( ) ,  std : : move ( labeling ) ,  std : : move ( stateRewards ) ,  std : : move ( noTransitionRewards ) ,  std : : move ( noChoiceLabeling ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > simpleModel  =  std : : make_shared < storm : : models : : sparse : : Dtmc < ParametricType > > ( matrixBuilder . build ( ) ,  std : : move ( labeling ) ,  std : : move ( stateRewards ) ,  std : : move ( noTransitionRewards ) ,  std : : move ( noChoiceLabeling ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // the corresponding formula
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : shared_ptr < storm : : logic : : Formula >  targetFormulaPtr ( new  storm : : logic : : AtomicLabelFormula ( " target " ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if ( this - > computeRewards ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                this - > simpleFormula  =  std : : shared_ptr < storm : : logic : : Formula > ( new  storm : : logic : : ReachabilityRewardFormula ( targetFormulaPtr ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                this - > simpleFormula  =  std : : shared_ptr < storm : : logic : : Formula > ( new  storm : : logic : : EventuallyFormula ( targetFormulaPtr ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : chrono : : high_resolution_clock : : time_point  timePreprocessingEnd  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > timePreprocessing  =  timePreprocessingEnd  -  timePreprocessingStart ;    
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -331,6 +300,22 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            //extend target states
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            targetStates = statesWithProbability01 . second ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            //check if approximation is applicable and whether the result is constant
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > isApproximationApplicable = true ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > isResultConstant = true ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( auto  state = maybeStates . begin ( ) ;  ( state ! = maybeStates . end ( ) )  & &  this - > isApproximationApplicable ;  + + state )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for ( auto  const &  entry  :  this - > model . getTransitionMatrix ( ) . getRow ( * state ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if ( ! this - > parametricTypeComparator . isConstant ( entry . getValue ( ) ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        this - > isResultConstant = false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        if ( ! storm : : utility : : regions : : functionIsLinear < ParametricType > ( entry . getValue ( ) ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            this - > isApproximationApplicable = false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            break ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_WARN_COND ( ! this - > isResultConstant ,  " For the given property, the reachability Value is constant, i.e., independent of the region " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -373,6 +358,9 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    storm : : utility : : vector : : selectVectorValues ( subStateRewards ,  maybeStates ,  this - > model . getStateRewardVector ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    storm : : utility : : vector : : addVectors ( stateRewards ,  subStateRewards ,  stateRewards ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for ( auto &  stateReward :  stateRewards ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    storm : : utility : : simplify ( stateReward ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // If only a state-based reward model is  available, we take this vector as the
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // right-hand side. As the state reward vector contains entries not just for the
  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -380,26 +368,73 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // first.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : utility : : vector : : selectVectorValues ( stateRewards ,  maybeStates ,  this - > model . getStateRewardVector ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for ( auto &  stateReward :  stateRewards ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : utility : : simplify ( stateReward ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             //check if approximation is applicable and whether the result is constant
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > isApproximationApplicable = true ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > isResultConstant = true ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : set < VariableType >  rewardPars ;  //the set of parameters that occur on a reward function
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : set < VariableType >  probPars ;    //the set of parameters that occur on a probability function
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( auto  state = maybeStates . begin ( ) ;  state ! = maybeStates . end ( )  & &  this - > isApproximationApplicable ;  + + state )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                //Constant/Linear probability functions
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for ( auto  const &  entry  :  this - > model . getTransitionMatrix ( ) . getRow ( * state ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if ( ! this - > parametricTypeComparator . isConstant ( entry . getValue ( ) ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        this - > isResultConstant = false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        if ( ! storm : : utility : : regions : : functionIsLinear < ParametricType > ( entry . getValue ( ) ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            this - > isApproximationApplicable = false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            break ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        storm : : utility : : regions : : gatherOccurringVariables ( entry . getValue ( ) ,  probPars ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                //Constant/Linear state rewards
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if ( this - > model . hasStateRewards ( )  & &  ! this - > parametricTypeComparator . isConstant ( this - > model . getStateRewardVector ( ) [ * state ] ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    this - > isResultConstant = false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if ( ! storm : : utility : : regions : : functionIsLinear < ParametricType > ( this - > model . getStateRewardVector ( ) [ * state ] ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        this - > isApproximationApplicable = false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        break ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    storm : : utility : : regions : : gatherOccurringVariables ( this - > model . getStateRewardVector ( ) [ * state ] ,  rewardPars ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                //Constant/Linear transition rewards
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if ( this - > model . hasTransitionRewards ( ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    for ( auto  const &  entry  :  this - > model . getTransitionRewardMatrix ( ) . getRow ( * state ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        if ( ! this - > parametricTypeComparator . isConstant ( entry . getValue ( ) ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            this - > isResultConstant = false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            if ( ! storm : : utility : : regions : : functionIsLinear < ParametricType > ( entry . getValue ( ) ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                this - > isApproximationApplicable = false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                break ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            storm : : utility : : regions : : gatherOccurringVariables ( entry . getValue ( ) ,  rewardPars ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            //Finally, we need to check whether rewardPars and probPars are disjoint
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            //Note: It would also work to simply rename the parameters that occur in both sets.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            //This is to avoid getting functions with local maxima like p * (1-p)
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for ( auto  const &  rewardVar  :  rewardPars ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if ( probPars . find ( rewardVar ) ! = probPars . end ( ) ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    this - > isApproximationApplicable = false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    break ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_WARN_COND ( ! this - > isResultConstant ,  " For the given property, the reachability Value is constant, i.e., independent of the region " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ParametricType ,  typename  ConstantType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        void  SparseDtmcRegionModelChecker < ParametricType ,  ConstantType > : : initializeApproximationModel ( storm : : models : : sparse : : Dtmc < ParametricType >  const &  simpleModel )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        void  SparseDtmcRegionModelChecker < ParametricType ,  ConstantType > : : initializeApproximationModel ( storm : : models : : sparse : : Dtmc < ParametricType >  const &  model ,  std : : shared_ptr < storm : : logic : : Formula >  formula )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : chrono : : high_resolution_clock : : time_point  timeInitApproxModelStart  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > approximationModel = std : : make_shared < ApproximationModel > ( simpleModel ,  this - > computeRewards ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > approximationModel = std : : make_shared < ApproximationModel > ( model ,  formula ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : chrono : : high_resolution_clock : : time_point  timeInitApproxModelEnd  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > timeInitApproxModel = timeInitApproxModelEnd  -  timeInitApproxModelStart ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_DEBUG ( " Initialized Approximation Model " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ParametricType ,  typename  ConstantType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        void  SparseDtmcRegionModelChecker < ParametricType ,  ConstantType > : : initializeSamplingModel ( storm : : models : : sparse : : Dtmc < ParametricType >  const &  simpleModel )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        void  SparseDtmcRegionModelChecker < ParametricType ,  ConstantType > : : initializeSamplingModel ( storm : : models : : sparse : : Dtmc < ParametricType >  const &  model ,  std : : shared_ptr < storm : : logic : : Formula >  formula )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : chrono : : high_resolution_clock : : time_point  timeInitSamplingModelStart  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > samplingModel = std : : make_shared < SamplingModel > ( simpleModel ,  this - > computeRewards ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > samplingModel = std : : make_shared < SamplingModel > ( model ,  formula ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : chrono : : high_resolution_clock : : time_point  timeInitSamplingModelEnd  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > timeInitSamplingModel  =  timeInitSamplingModelEnd  -  timeInitSamplingModelStart ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_DEBUG ( " Initialized Sampling Model " ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -408,8 +443,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ParametricType ,  typename  ConstantType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        void  SparseDtmcRegionModelChecker < ParametricType ,  ConstantType > : : computeReachabilityFunction ( storm : : models : : sparse : : Dtmc < ParametricType >  const &  simpleModel ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : chrono : : high_resolution_clock : : time_point  timeComputeReachabilityFunctionStart  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            //get the one step probabilities and the transition matrix of the simplified model without target/sink state
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            //TODO check if this takes long... we could also store the oneSteps while creating the simplified model. Or(?) we keep the matrix the way it is and give the target state one step probability 1.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            //get the one step probabilities and the transition matrix of the simple model without target/sink state
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            storm : : storage : : SparseMatrix < ParametricType >  backwardTransitions ( simpleModel . getBackwardTransitions ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < ParametricType >  oneStepProbabilities ( simpleModel . getNumberOfStates ( ) - 2 ,  storm : : utility : : zero < ParametricType > ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for ( auto  const &  entry  :  backwardTransitions . getRow ( * ( simpleModel . getStates ( " target " ) . begin ( ) ) ) ) {  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -534,7 +568,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            uint_fast64_t  progress = 0 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            uint_fast64_t  checkedRegions = 0 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for ( auto &  region  :  regions ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                this - > checkRegion ( region ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                checkRegion ( region ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if ( ( checkedRegions + + ) * 10 / regions . size ( ) = = progress ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    std : : cout  < <  progress + + ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    std : : cout . flush ( ) ;  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -646,7 +680,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        std : : shared_ptr < typename  SparseDtmcRegionModelChecker < ParametricType ,  ConstantType > : : ApproximationModel >  const &  SparseDtmcRegionModelChecker < ParametricType ,  ConstantType > : : getApproximationModel ( )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if ( this - > approximationModel = = nullptr ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_WARN ( " Approximation model requested but it has not been initialized when specifying the formula. Will initialize it now. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                initializeApproximationModel ( * this - > simplifi ed Model ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                initializeApproximationModel ( * this - > simpleModel ,  this - > simpleFormula ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  this - > approximationModel ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -701,7 +735,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        std : : shared_ptr < typename  SparseDtmcRegionModelChecker < ParametricType ,  ConstantType > : : SamplingModel >  const &  SparseDtmcRegionModelChecker < ParametricType ,  ConstantType > : : getSamplingModel ( )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if ( this - > samplingModel = = nullptr ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_WARN ( " Sampling model requested but it has not been initialized when specifying the formula. Will initialize it now. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                initializeSamplingModel ( * this - > simplifi ed Model ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                initializeSamplingModel ( * this - > simpleModel ,  this - > simpleFormula ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  this - > samplingModel ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -710,7 +744,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        std : : shared_ptr < ParametricType >  const &  SparseDtmcRegionModelChecker < ParametricType ,  ConstantType > : : getReachabilityFunction ( )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if ( this - > reachabilityFunction = = nullptr ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_WARN ( " Reachability Function requested but it has not been computed when specifying the formula. Will compute it now. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                computeReachabilityFunction ( * this - > simplifi ed Model ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                computeReachabilityFunction ( * this - > simpleModel ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  this - > reachabilityFunction ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -912,24 +946,26 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                outstream  < <  " The requested value is constant (i.e. independent of any parameters) "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            else {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                outstream  < <  " Simplifi ed  model:  "  < <  this - > simplifi ed Model - > getNumberOfStates ( )  < <  "  states,  "  < <  this - > simplifi ed Model - > getNumberOfTransitions ( )  < <  "  transitions "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                outstream  < <  " Simple model:  "  < <  this - > simpleModel - > getNumberOfStates ( )  < <  "  states,  "  < <  this - > simpleModel - > getNumberOfTransitions ( )  < <  "  transitions "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  " Approximation is  "  < <  ( this - > isApproximationApplicable  ?  " "  :  " not  " )  < <  " applicable "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  " Number of checked regions:  "  < <  this - > numOfCheckedRegions  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  "   Number of solved regions:   "  < <   numOfSolvedRegions  < <  " ( "  < <  numOfSolvedRegions * 100 / this - > numOfCheckedRegions  < <  " %) "  < <   std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  "     AllSat:       "  < <   this - > numOfRegionsAllSat  < <  " ( "  < <  this - > numOfRegionsAllSat * 100 / this - > numOfCheckedRegions  < <  " %) "  < <   std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  "     AllViolated:  "  < <   this - > numOfRegionsAllViolated  < <  " ( "  < <  this - > numOfRegionsAllViolated * 100 / this - > numOfCheckedRegions  < <  " %) "  < <   std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  "     ExistsBoth:   "  < <   this - > numOfRegionsExistsBoth  < <  " ( "  < <  this - > numOfRegionsExistsBoth * 100 / this - > numOfCheckedRegions  < <  " %) "  < <   std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  "     Unsolved:     "  < <   this - > numOfCheckedRegions  -  numOfSolvedRegions  < <  " ( "  < <  ( this - > numOfCheckedRegions  -  numOfSolvedRegions ) * 100 / this - > numOfCheckedRegions  < <  " %) "  < <   std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  "   --  Note: %-numbers are relative to the NUMBER of regions, not the size of their area -- "  < <   std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  "    "  < <  this - > numOfRegionsSolvedThroughApproximation  < <  "  regions solved through Approximation "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  "    "  < <  this - > numOfRegionsSolvedThroughSampling  < <  "  regions solved through Sampling "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  "    "  < <  this - > numOfRegionsSolvedThroughFullSmt  < <  "  regions solved through FullSmt "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if ( this - > numOfCheckedRegions > 0 ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                outstream  < <  "   Number of solved regions:   "  < <   numOfSolvedRegions  < <  " ( "  < <  numOfSolvedRegions * 100 / this - > numOfCheckedRegions  < <  " %) "  < <   std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                outstream  < <  "     AllSat:       "  < <   this - > numOfRegionsAllSat  < <  " ( "  < <  this - > numOfRegionsAllSat * 100 / this - > numOfCheckedRegions  < <  " %) "  < <   std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                outstream  < <  "     AllViolated:  "  < <   this - > numOfRegionsAllViolated  < <  " ( "  < <  this - > numOfRegionsAllViolated * 100 / this - > numOfCheckedRegions  < <  " %) "  < <   std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                outstream  < <  "     ExistsBoth:   "  < <   this - > numOfRegionsExistsBoth  < <  " ( "  < <  this - > numOfRegionsExistsBoth * 100 / this - > numOfCheckedRegions  < <  " %) "  < <   std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                outstream  < <  "     Unsolved:     "  < <   this - > numOfCheckedRegions  -  numOfSolvedRegions  < <  " ( "  < <  ( this - > numOfCheckedRegions  -  numOfSolvedRegions ) * 100 / this - > numOfCheckedRegions  < <  " %) "  < <   std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                outstream  < <  "   --  Note: %-numbers are relative to the NUMBER of regions, not the size of their area -- "  < <   std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                outstream  < <  "    "  < <  this - > numOfRegionsSolvedThroughApproximation  < <  "  regions solved through Approximation "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                outstream  < <  "    "  < <  this - > numOfRegionsSolvedThroughSampling  < <  "  regions solved through Sampling "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                outstream  < <  "    "  < <  this - > numOfRegionsSolvedThroughFullSmt  < <  "  regions solved through FullSmt "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                outstream  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  " Running times: "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  "    "  < <  timeOverallInMilliseconds . count ( )  < <  " ms overall (excluding model parsing, bisimulation (if applied)) "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  "    "  < <  timeSpecifyFormulaInMilliseconds . count ( )  < <  " ms Initialization for the specified formula, including...  "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  "      "  < <  timePreprocessingInMilliseconds . count ( )  < <  " ms for Preprocessing (mainly to obtain a simplified model, i.e.,  state elimination of const transitions) "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  "      "  < <  timePreprocessingInMilliseconds . count ( )  < <  " ms for Preprocessing (mainly:  state elimination of const transitions) "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  "      "  < <  timeInitApproxModelInMilliseconds . count ( )  < <  " ms to initialize the Approximation Model "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  "      "  < <  timeInitSamplingModelInMilliseconds . count ( )  < <  " ms to initialize the Sampling Model "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            outstream  < <  "      "  < <  timeComputeReachabilityFunctionInMilliseconds . count ( )  < <  " ms to compute the reachability function "  < <  std : : endl ;