@ -71,49 +71,27 @@ namespace storm { 
			
		
	
		
			
				
					             
			
		
	
		
			
				
					        template < typename  ParametricType ,  typename  ConstantType >  
			
		
	
		
			
				
					        void  SparseDtmcRegionModelChecker < ParametricType ,  ConstantType > : : specifyFormula ( std : : shared_ptr < storm : : logic : : Formula >  formula )  {  
			
		
	
		
			
				
					            std : : chrono : : high_resolution_clock : : time_point  timePreprocessing Start  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
			
		
	
		
			
				
					            std : : chrono : : high_resolution_clock : : time_point  timeSpecifyFormula Start  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
			
		
	
		
			
				
					            STORM_LOG_THROW ( this - > canHandle ( * formula ) ,  storm : : exceptions : : InvalidArgumentException ,  " Tried to specify a formula that can not be handled. " ) ;  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            this - > hasOnlyLinearFunctions = false ;  
			
		
	
		
			
				
					            this - > isResultConstant = false ;  
			
		
	
		
			
				
					            this - > isApproximationApplicable = false ;  
			
		
	
		
			
				
					            this - > smtSolver = nullptr ;  
			
		
	
		
			
				
					            this - > approximationModel = nullptr ;  
			
		
	
		
			
				
					            this - > samplingModel = nullptr ;  
			
		
	
		
			
				
					            this - > reachabilityFunction = nullptr ;  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            //Get bounds, comparison type, target states, ..
  
			
		
	
		
			
				
					            //Note: canHandle already ensures that the formula has the right shape.
  
			
		
	
		
			
				
					            this - > specifiedFormula  =  formula ;  
			
		
	
		
			
				
					            std : : unique_ptr < CheckResult >  targetStatesResultPtr ;  
			
		
	
		
			
				
					            if  ( this - > specifiedFormula - > isProbabilityOperatorFormula ( ) )  {  
			
		
	
		
			
				
					                this - > computeRewards = false ;  
			
		
	
		
			
				
					                storm : : logic : : ProbabilityOperatorFormula  const &  probabilityOperatorFormula  =  this - > specifiedFormula - > asProbabilityOperatorFormula ( ) ;  
			
		
	
		
			
				
					                this - > specifiedFormulaCompType = probabilityOperatorFormula . getComparisonType ( ) ;  
			
		
	
		
			
				
					                this - > specifiedFormulaBound = probabilityOperatorFormula . getBound ( ) ;  
			
		
	
		
			
				
					                targetStatesResultPtr = this - > eliminationModelChecker . check ( probabilityOperatorFormula . getSubformula ( ) . asEventuallyFormula ( ) . getSubformula ( ) ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            else  if  ( this - > specifiedFormula - > isRewardOperatorFormula ( ) )  {  
			
		
	
		
			
				
					                this - > computeRewards = true ;  
			
		
	
		
			
				
					                storm : : logic : : RewardOperatorFormula  const &  rewardOperatorFormula  =  this - > specifiedFormula - > asRewardOperatorFormula ( ) ;  
			
		
	
		
			
				
					                this - > specifiedFormulaCompType = rewardOperatorFormula . getComparisonType ( ) ;  
			
		
	
		
			
				
					                this - > specifiedFormulaBound = rewardOperatorFormula . getBound ( ) ;  
			
		
	
		
			
				
					                targetStatesResultPtr = this - > eliminationModelChecker . check ( rewardOperatorFormula . getSubformula ( ) . asReachabilityRewardFormula ( ) . getSubformula ( ) ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            else  {  
			
		
	
		
			
				
					                STORM_LOG_THROW ( false ,  storm : : exceptions : : InvalidPropertyException ,  " The specified property  "  < <  formula  < <  " is not supported " ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            storm : : storage : : BitVector  const &  targetStates  =  targetStatesResultPtr - > asExplicitQualitativeCheckResult ( ) . getTruthValuesVector ( ) ;  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            // get a more simple model with a single target state, a single sink state and where states with constant outgoing transitions have been removed
  
			
		
	
		
			
				
					            // Note: also checks for linear functions and a constant result
  
			
		
	
		
			
				
					            computeSimplifiedModel ( targetStates ) ;  
			
		
	
		
			
				
					            // set some information regarding the formula and model. Also computes a more simple version of the model
  
			
		
	
		
			
				
					            preprocess ( ) ;  
			
		
	
		
			
				
					            if ( ! this - > isResultConstant ) {  
			
		
	
		
			
				
					                //now create the model used for Approximation
  
			
		
	
		
			
				
					                if ( storm : : settings : : regionSettings ( ) . doApprox ( ) ) {  
			
		
	
		
			
				
					                    initializeApproximationModel ( * this - > simplifiedModel ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                //now create the model used for Sampling
  
			
		
	
		
			
				
					                if ( storm : : settings : : regionSettings ( ) . doSample ( ) | |  ( storm : : settings : : regionSettings ( ) . getApproxMode ( ) = = storm : : settings : : modules : : RegionSettings : : ApproxMode : : TESTFIRST ) ) {  
			
		
	
		
			
				
					                if ( storm : : settings : : regionSettings ( ) . getSampleMode ( ) = = storm : : settings : : modules : : RegionSettings : : SampleMode : : INSTANTIATE  | |  ( storm : : settings : : regionSettings ( ) . getApproxMode ( ) = = storm : : settings : : modules : : RegionSettings : : ApproxMode : : TESTFIRST ) ) {  
			
		
	
		
			
				
					                    initializeSamplingModel ( * this - > simplifiedModel ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                //Check if the reachability function needs to be computed
  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -123,8 +101,8 @@ namespace storm { 
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            //some information for statistics...
  
			
		
	
		
			
				
					            std : : chrono : : high_resolution_clock : : time_point  timePreprocessing End  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
			
		
	
		
			
				
					            this - > timePreprocessing =  timePreprocessingEnd  -  timePreprocessing Start ;  
			
		
	
		
			
				
					            std : : chrono : : high_resolution_clock : : time_point  timeSpecifyFormula End  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
			
		
	
		
			
				
					            this - > timeSpecifyFormula =  timeSpecifyFormulaEnd  -  timeSpecifyFormula Start ;  
			
		
	
		
			
				
					            this - > numOfCheckedRegions = 0 ;  
			
		
	
		
			
				
					            this - > numOfRegionsSolvedThroughSampling = 0 ;  
			
		
	
		
			
				
					            this - > numOfRegionsSolvedThroughApproximation = 0 ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -140,84 +118,127 @@ namespace storm { 
			
		
	
		
			
				
					        }  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        template < typename  ParametricType ,  typename  ConstantType >  
			
		
	
		
			
				
					        void  SparseDtmcRegionModelChecker < ParametricType ,  ConstantType > : : computeSimplifiedModel ( storm : : storage : : BitVector  const &  targetStates ) {  
			
		
	
		
			
				
					            std : : chrono : : high_resolution_clock : : time_point  timeComputeSimplifiedModelStart  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
			
		
	
		
			
				
					            //Compute the subset of states that have a probability of 0 or 1, respectively and reduce the considered states accordingly.
  
			
		
	
		
			
				
					            std : : pair < storm : : storage : : BitVector ,  storm : : storage : : BitVector >  statesWithProbability01  =  storm : : utility : : graph : : performProb01 ( this - > model ,  storm : : storage : : BitVector ( this - > model . getNumberOfStates ( ) , true ) ,  targetStates ) ;  
			
		
	
		
			
				
					            storm : : storage : : BitVector  statesWithProbability0  =  statesWithProbability01 . first ;  
			
		
	
		
			
				
					            storm : : storage : : BitVector  statesWithProbability1  =  statesWithProbability01 . second ;  
			
		
	
		
			
				
					            //if the target states are not reached with probability 1, then the expected reward is defined as infinity
  
			
		
	
		
			
				
					            if  ( this - > computeRewards  & &  ! this - > model . getInitialStates ( ) . isSubsetOf ( statesWithProbability1 ) ) {  
			
		
	
		
			
				
					                STORM_LOG_WARN ( " The expected reward of the initial state is constant (infinity) " ) ;  
			
		
	
		
			
				
					                this - > reachabilityFunction  =  std : : make_shared < ParametricType > ( storm : : utility : : infinity < ParametricType > ( ) ) ;  
			
		
	
		
			
				
					                this - > isResultConstant = true ;  
			
		
	
		
			
				
					                this - > hasOnlyLinearFunctions = true ;  
			
		
	
		
			
				
					                return ;  //nothing else to do...
  
			
		
	
		
			
				
					        void  SparseDtmcRegionModelChecker < ParametricType ,  ConstantType > : : preprocess ( ) {  
			
		
	
		
			
				
					            std : : chrono : : high_resolution_clock : : time_point  timePreprocessingStart  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
			
		
	
		
			
				
					            STORM_LOG_THROW ( this - > model . getInitialStates ( ) . getNumberOfSetBits ( )  = =  1 ,  storm : : exceptions : : InvalidArgumentException ,  " Input model is required to have exactly one initial state. " ) ;  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            //first some preprocessing depending on the type of the considered formula
  
			
		
	
		
			
				
					            storm : : storage : : BitVector  maybeStates ,  targetStates ;  
			
		
	
		
			
				
					            boost : : optional < std : : vector < ParametricType > >  stateRewards ;  
			
		
	
		
			
				
					            if  ( this - > specifiedFormula - > isProbabilityOperatorFormula ( ) )  {  
			
		
	
		
			
				
					                preprocessForProbabilities ( maybeStates ,  targetStates ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            storm : : storage : : BitVector  maybeStates  =  ~ ( statesWithProbability0  |  statesWithProbability1 ) ;  
			
		
	
		
			
				
					            // If the initial state is known to have either probability 0 or 1, we can directly set the reachProbFunction.
  
			
		
	
		
			
				
					            if  ( ! this - > computeRewards  & &  this - > model . getInitialStates ( ) . isDisjointFrom ( maybeStates ) )  {  
			
		
	
		
			
				
					                STORM_LOG_WARN ( " The probability of the initial state is constant (0 or 1) " ) ;  
			
		
	
		
			
				
					                this - > reachabilityFunction  =  std : : make_shared < ParametricType > ( statesWithProbability0 . get ( * ( this - > model . getInitialStates ( ) . begin ( ) ) )  ?  storm : : utility : : zero < ParametricType > ( )  :  storm : : utility : : one < ParametricType > ( ) ) ;  
			
		
	
		
			
				
					                this - > isResultConstant = true ;  
			
		
	
		
			
				
					                this - > hasOnlyLinearFunctions = true ;  
			
		
	
		
			
				
					                return ;  //nothing else to do...
  
			
		
	
		
			
				
					            else  if  ( this - > specifiedFormula - > isRewardOperatorFormula ( ) )  {  
			
		
	
		
			
				
					                std : : vector < ParametricType >  stateRewardsAsVector ;  
			
		
	
		
			
				
					                preprocessForRewards ( maybeStates ,  targetStates ,  stateRewardsAsVector ) ;  
			
		
	
		
			
				
					                stateRewards = std : : move ( stateRewardsAsVector ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            else  {  
			
		
	
		
			
				
					                STORM_LOG_THROW ( false ,  storm : : exceptions : : InvalidPropertyException ,  " The specified property  "  < <  this - > specifiedFormula  < <  " is not supported " ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            // Determine the set of states that is reachable from the initial state without jumping over a target state.
  
			
		
	
		
			
				
					            storm : : storage : : BitVector  reachableStates  =  storm : : utility : : graph : : getReachableStates ( this - > model . getTransitionMatrix ( ) ,  this - > model . getInitialStates ( ) ,  maybeStates ,  statesWithProbability1 ) ;  
			
		
	
		
			
				
					            storm : : storage : : BitVector  reachableStates  =  storm : : utility : : graph : : getReachableStates ( this - > model . getTransitionMatrix ( ) ,  this - > model . getInitialStates ( ) ,  maybeStates ,  targetStates ) ;  
			
		
	
		
			
				
					            // Subtract from the maybe states the set of states that is not reachable (on a path from the initial to a target state).
  
			
		
	
		
			
				
					            maybeStates  & =  reachableStates ;  
			
		
	
		
			
				
					            // Create a vector for the probabilities to go to a state with probability 1  in one step.
  
			
		
	
		
			
				
					            std : : vector < ParametricType >  oneStepProbabilities  =  this - > model . getTransitionMatrix ( ) . getConstrainedRowSumVector ( maybeStates ,  statesWithProbability1 ) ;  
			
		
	
		
			
				
					            // Create a vector for the probabilities to go to a target state  in one step.
  
			
		
	
		
			
				
					            std : : vector < ParametricType >  oneStepProbabilities  =  this - > model . getTransitionMatrix ( ) . getConstrainedRowSumVector ( maybeStates ,  targetStates ) ;  
			
		
	
		
			
				
					            // Determine the initial state of the sub-model.
  
			
		
	
		
			
				
					            storm : : storage : : sparse : : state_type  initialState  =  * ( this - > model . getInitialStates ( )  %  maybeStates ) . begin ( ) ;  
			
		
	
		
			
				
					            // 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 ) ;  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            // eliminate all states with only constant outgoing transitions
  
			
		
	
		
			
				
					            //TODO: maybe also states with constant incoming tranistions. THEN the ordering of the eliminated states does matter.
  
			
		
	
		
			
				
					            // eliminate all states with only constant outgoing transitions (and possibly rewards)
  
			
		
	
		
			
				
					            // 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 ) ;  
			
		
	
		
			
				
					            // Create a bit vector that represents the current subsystem, i.e., states that we have not eliminated.
  
			
		
	
		
			
				
					            storm : : storage : : BitVector  subsystem  =  storm : : storage : : BitVector  ( submatrix . getRowCount ( ) ,  true ) ;  
			
		
	
		
			
				
					            //temporarily unselect the initial state to skip it. 
  
			
		
	
		
			
				
					            subsystem . set ( initialState ,  fals e ) ;  
			
		
	
		
			
				
					            this - > hasOnlyLinearFunctions = true ;  
			
		
	
		
			
				
					            bool  allReachableFunctionsAreConstant = true ;  
			
		
	
		
			
				
					            boost : : optional < std : : vector < ParametricType > >  missingStateRewards ;  
			
		
	
		
			
				
					            for  ( auto  const &  state  :  subsystem )  {  
			
		
	
		
			
				
					                bool  stateHasOnlyConstantOutgoingTransitions = true ;  
			
		
	
		
			
				
					                for ( auto  const &  entry  :  submatrix . getRow ( state ) ) {  
			
		
	
		
			
				
					            storm : : storage : : BitVector  subsystem ( submatrix . getRowCount ( ) ,  true ) ;  
			
		
	
		
			
				
					            //The states that we consider to eliminate 
  
			
		
	
		
			
				
					            storm : : storage : : BitVector  considerToEliminate ( submatrix . getRowCount ( ) ,  tru e ) ;  
			
		
	
		
			
				
					            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 ( ) ) ) {  
			
		
	
		
			
				
					                        allReachableFunctionsAre Constant= false ;  
			
		
	
		
			
				
					                        stateHasOnlyConstantOutgoingTransitions = false ;  
			
		
	
		
			
				
					                        this - > hasOnlyLinearFunctions & =  storm : : utility : : regions : : functionIsLinear < ParametricType > ( entry . getValue ( ) ) ;  
			
		
	
		
			
				
					                        this - > isResult Constant= false ;  
			
		
	
		
			
				
					                        eliminateThisState = false ;  
			
		
	
		
			
				
					                        this - > isApproximationApplicable & =  storm : : utility : : regions : : functionIsLinear < ParametricType > ( entry . getValue ( ) ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                if ( ! this - > parametricTypeComparator . isConstant ( oneStepProbabilities [ state ] ) ) {  
			
		
	
		
			
				
					                    allReachableFunctionsAreConstant = false ;  
			
		
	
		
			
				
					                    stateHasOnlyConstantOutgoingTransitions = false ;  
			
		
	
		
			
				
					                    this - > hasOnlyLinearFunctions  & =  storm : : utility : : regions : : functionIsLinear < ParametricType > ( 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)
  
			
		
	
		
			
				
					                    std : : set < VariableType >  probVars ;  
			
		
	
		
			
				
					                    for ( auto  const &  predecessor  :  flexibleBackwardTransitions . getRow ( state ) ) {  
			
		
	
		
			
				
					                        for ( auto  const &  predecessorTransition  :  flexibleTransitions . getRow ( predecessor . getColumn ( ) ) ) {  
			
		
	
		
			
				
					                            storm : : utility : : regions : : gatherOccurringVariables ( predecessorTransition . getValue ( ) ,  probVars ) ;  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    std : : set < VariableType >  rewardVars ;  
			
		
	
		
			
				
					                    storm : : utility : : regions : : gatherOccurringVariables ( stateRewards . get ( ) [ state ] ,  rewardVars ) ;  
			
		
	
		
			
				
					                    for ( auto  const &  rewardVar  :  rewardVars ) {  
			
		
	
		
			
				
					                        if ( probVars . find ( rewardVar ) ! = probVars . end ( ) ) {  
			
		
	
		
			
				
					                            eliminateThisState = false ;  
			
		
	
		
			
				
					                            break ;  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                if ( stateHasOnlyConstantOutgoingTransitions ) {  
			
		
	
		
			
				
					                    this - > eliminationModelChecker . eliminateState ( flexibleTransitions ,  oneStepProbabilities ,  state ,  flexibleBackwardTransitions ,  missingStateRewards ) ;  
			
		
	
		
			
				
					                if ( eliminateThisState ) {  
			
		
	
		
			
				
					                    this - > eliminationModelChecker . eliminateState ( flexibleTransitions ,  oneStepProbabilities ,  state ,  flexibleBackwardTransitions ,  stateRewards ) ;  
			
		
	
		
			
				
					                    subsystem . set ( state , false ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            subsystem . set ( initialState ,  true ) ;  
			
		
	
		
			
				
					            STORM_LOG_DEBUG ( " Eliminated  "  < <  subsystem . size ( )  -  subsystem . getNumberOfSetBits ( )  < <  "  of  "  < <  subsystem . size ( )  < <  "  states that had constant outgoing transitions. "  < <  std : : endl ) ;  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            if ( allReachableFunctionsAreConstant ) {  
			
		
	
		
			
				
					            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  :  submatrix . getRow ( initialState ) ) {  
			
		
	
		
			
				
					                    allReachableFunctionsAreConstant & = this - > parametricTypeComparator . isConstant ( entry . getValue ( ) ) ;  
			
		
	
		
			
				
					                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 ;  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                allReachableFunctionsAreConstant & = this - > parametricTypeComparator . isConstant ( oneStepProbabilities [ initialState ] ) ;  
			
		
	
		
			
				
					                // Set the flag accordingly
  
			
		
	
		
			
				
					                this - > isResultConstant = allReachableFunctionsAreConstant ;  
			
		
	
		
			
				
					                STORM_LOG_WARN_COND ( ! this - > isResultConstant ,  " For the given property, the reachability probability is constant, i.e., independent of the region " ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            STORM_LOG_WARN_COND ( ! this - > isResultConstant ,  " For the given property, the reachability Value is constant, i.e., independent of the region " ) ;  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            //Build the simplified 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.
  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -234,21 +255,28 @@ namespace storm { 
			
		
	
		
			
				
					            //We can now fill in the data.
  
			
		
	
		
			
				
					            storm : : storage : : SparseMatrixBuilder < ParametricType >  matrixBuilder ( numStates ,  numStates ) ;  
			
		
	
		
			
				
					            for ( storm : : storage : : sparse : : state_type  oldStateIndex  :  subsystem ) {   
			
		
	
		
			
				
					                ParametricType  valueToSinkState = storm : : utility : : regions : : getNewFunction < ParametricType ,  CoefficientType > ( storm : : utility : : one < CoefficientType > ( ) ) ;  
			
		
	
		
			
				
					                ParametricType  missingProbability = storm : : utility : : regions : : getNewFunction < ParametricType ,  CoefficientType > ( storm : : utility : : one < CoefficientType > ( ) ) ;  
			
		
	
		
			
				
					                //go through columns:
  
			
		
	
		
			
				
					                for ( auto  const &  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. " ) ;  
			
		
	
		
			
				
					                    valueToSinkState - = entry . getValue ( ) ;  
			
		
	
		
			
				
					                    missingProbability - = entry . getValue ( ) ;  
			
		
	
		
			
				
					                    matrixBuilder . addNextValue ( newStateIndexMap [ oldStateIndex ] , newStateIndexMap [ entry . getColumn ( ) ] , entry . getValue ( ) ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                //transition to target state
  
			
		
	
		
			
				
					                if ( ! this - > parametricTypeComparator . isZero ( oneStepProbabilities [ oldStateIndex ] ) ) {   
			
		
	
		
			
				
					                    valueToSinkState - = oneStepProbabilities [ oldStateIndex ] ;  
			
		
	
		
			
				
					                    matrixBuilder . addNextValue ( newStateIndexMap [ oldStateIndex ] ,  targetState ,  oneStepProbabilities [ oldStateIndex ] ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                //transition to sink state
  
			
		
	
		
			
				
					                if ( ! this - > parametricTypeComparator . isZero ( valueToSinkState ) ) {   
			
		
	
		
			
				
					                    matrixBuilder . addNextValue ( newStateIndexMap [ oldStateIndex ] ,  sinkState ,  valueToSinkState ) ;  
			
		
	
		
			
				
					                if ( this - > computeRewards ) {  
			
		
	
		
			
				
					                    // the missing probability always leads to target
  
			
		
	
		
			
				
					                    if ( ! this - > parametricTypeComparator . isZero ( missingProbability ) ) {  
			
		
	
		
			
				
					                        matrixBuilder . addNextValue ( newStateIndexMap [ oldStateIndex ] ,  targetState , missingProbability ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                }  else {  
			
		
	
		
			
				
					                    //transition to target state
  
			
		
	
		
			
				
					                    if ( ! this - > parametricTypeComparator . isZero ( oneStepProbabilities [ oldStateIndex ] ) ) {  
			
		
	
		
			
				
					                        missingProbability - = oneStepProbabilities [ oldStateIndex ] ;  
			
		
	
		
			
				
					                        matrixBuilder . addNextValue ( newStateIndexMap [ oldStateIndex ] ,  targetState ,  oneStepProbabilities [ oldStateIndex ] ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    //transition to sink state
  
			
		
	
		
			
				
					                    if ( ! this - > parametricTypeComparator . isZero ( missingProbability ) ) {   
			
		
	
		
			
				
					                        matrixBuilder . addNextValue ( newStateIndexMap [ oldStateIndex ] ,  sinkState ,  missingProbability ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            //add self loops on the additional states (i.e., target and sink)
  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -266,15 +294,95 @@ namespace storm { 
			
		
	
		
			
				
					            sinkLabel . set ( sinkState ,  true ) ;  
			
		
	
		
			
				
					            labeling . addLabel ( " sink " ,  std : : move ( sinkLabel ) ) ;  
			
		
	
		
			
				
					            // other ingredients
  
			
		
	
		
			
				
					            boost : : optional < std : : vector < ParametricType > >  noStateRewards ;  
			
		
	
		
			
				
					            if ( this - > computeRewards ) {  
			
		
	
		
			
				
					                storm : : utility : : vector : : selectVectorValues ( stateRewards . get ( ) ,  subsystem ,  stateRewards . get ( ) ) ;  
			
		
	
		
			
				
					                stateRewards - > push_back ( storm : : utility : : zero < ParametricType > ( ) ) ;  //target state
  
			
		
	
		
			
				
					                stateRewards - > push_back ( storm : : utility : : zero < ParametricType > ( ) ) ;  //sink state
  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            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 ( noStateRewards ) ,  std : : move ( noTransitionRewards ) ,  std : : move ( noChoiceLabeling ) ) ;  
			
		
	
		
			
				
					            std : : chrono : : high_resolution_clock : : time_point  timeComputeSimplifiedModelEnd  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
			
		
	
		
			
				
					            this - > timeComputeSimplifiedModel  =  timeComputeSimplifiedModelEnd  -  timeComputeSimplifiedModelStart ;              
			
		
	
		
			
				
					            this - > simplifiedModel  =  std : : make_shared < storm : : models : : sparse : : Dtmc < ParametricType > > ( matrixBuilder . build ( ) ,  std : : move ( labeling ) ,  std : : move ( stateRewards ) ,  std : : move ( noTransitionRewards ) ,  std : : move ( noChoiceLabeling ) ) ;  
			
		
	
		
			
				
					            std : : chrono : : high_resolution_clock : : time_point  timePreprocessingEnd  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
			
		
	
		
			
				
					            this - > timePreprocessing  =  timePreprocessingEnd  -  timePreprocessingStart ;    
			
		
	
		
			
				
					        }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        template < typename  ParametricType ,  typename  ConstantType >  
			
		
	
		
			
				
					        void  SparseDtmcRegionModelChecker < ParametricType ,  ConstantType > : : preprocessForProbabilities ( storm : : storage : : BitVector &  maybeStates ,  storm : : storage : : BitVector &  targetStates )  {  
			
		
	
		
			
				
					            this - > computeRewards = false ;  
			
		
	
		
			
				
					            //Get bounds, comparison type, target states
  
			
		
	
		
			
				
					            storm : : logic : : ProbabilityOperatorFormula  const &  probabilityOperatorFormula  =  this - > specifiedFormula - > asProbabilityOperatorFormula ( ) ;  
			
		
	
		
			
				
					            this - > specifiedFormulaCompType = probabilityOperatorFormula . getComparisonType ( ) ;  
			
		
	
		
			
				
					            this - > specifiedFormulaBound = probabilityOperatorFormula . getBound ( ) ;  
			
		
	
		
			
				
					            std : : unique_ptr < CheckResult >  targetStatesResultPtr = this - > eliminationModelChecker . check ( probabilityOperatorFormula . getSubformula ( ) . asEventuallyFormula ( ) . getSubformula ( ) ) ;  
			
		
	
		
			
				
					            targetStates  =  std : : move ( targetStatesResultPtr - > asExplicitQualitativeCheckResult ( ) . getTruthValuesVector ( ) ) ;  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					            //maybeStates: Compute the subset of states that have a probability of 0 or 1, respectively and reduce the considered states accordingly.
  
			
		
	
		
			
				
					            std : : pair < storm : : storage : : BitVector ,  storm : : storage : : BitVector >  statesWithProbability01  =  storm : : utility : : graph : : performProb01 ( this - > model ,  storm : : storage : : BitVector ( this - > model . getNumberOfStates ( ) , true ) ,  targetStates ) ;  
			
		
	
		
			
				
					            maybeStates  =  ~ ( statesWithProbability01 . first  |  statesWithProbability01 . second ) ;  
			
		
	
		
			
				
					            // If the initial state is known to have either probability 0 or 1, we can directly set the reachProbFunction.
  
			
		
	
		
			
				
					            storm : : storage : : sparse : : state_type  initialState  =  * this - > model . getInitialStates ( ) . begin ( ) ;  
			
		
	
		
			
				
					            if  ( ! maybeStates . get ( initialState ) )  {  
			
		
	
		
			
				
					                STORM_LOG_WARN ( " The probability of the initial state is constant (zero or one) " ) ;  
			
		
	
		
			
				
					                this - > reachabilityFunction  =  std : : make_shared < ParametricType > ( statesWithProbability01 . first . get ( initialState )  ?  storm : : utility : : zero < ParametricType > ( )  :  storm : : utility : : one < ParametricType > ( ) ) ;  
			
		
	
		
			
				
					                this - > isResultConstant = true ;  
			
		
	
		
			
				
					                return ;  //nothing else to do...
  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            //extend target states
  
			
		
	
		
			
				
					            targetStates = statesWithProbability01 . second ;  
			
		
	
		
			
				
					        }  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        template < typename  ParametricType ,  typename  ConstantType >  
			
		
	
		
			
				
					        void  SparseDtmcRegionModelChecker < ParametricType ,  ConstantType > : : preprocessForRewards ( storm : : storage : : BitVector &  maybeStates ,  storm : : storage : : BitVector &  targetStates ,  std : : vector < ParametricType > &  stateRewards )  {  
			
		
	
		
			
				
					            this - > computeRewards = true ;  
			
		
	
		
			
				
					            STORM_LOG_THROW ( this - > model . hasStateRewards ( )  | |  this - > model . hasTransitionRewards ( ) ,  storm : : exceptions : : InvalidArgumentException ,  " Input model does not have a reward model. " ) ;  
			
		
	
		
			
				
					            //Get bounds, comparison type, target states
  
			
		
	
		
			
				
					            storm : : logic : : RewardOperatorFormula  const &  rewardOperatorFormula  =  this - > specifiedFormula - > asRewardOperatorFormula ( ) ;  
			
		
	
		
			
				
					            this - > specifiedFormulaCompType = rewardOperatorFormula . getComparisonType ( ) ;  
			
		
	
		
			
				
					            this - > specifiedFormulaBound = rewardOperatorFormula . getBound ( ) ;  
			
		
	
		
			
				
					            std : : unique_ptr < CheckResult >  targetStatesResultPtr = this - > eliminationModelChecker . check ( rewardOperatorFormula . getSubformula ( ) . asReachabilityRewardFormula ( ) . getSubformula ( ) ) ;  
			
		
	
		
			
				
					            targetStates  =  std : : move ( targetStatesResultPtr - > asExplicitQualitativeCheckResult ( ) . getTruthValuesVector ( ) ) ;  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					            //maybeStates: Compute the subset of states that has a reachability reward less than infinity.
  
			
		
	
		
			
				
					            storm : : storage : : BitVector  statesWithProbability1  =  storm : : utility : : graph : : performProb1 ( this - > model . getBackwardTransitions ( ) ,  storm : : storage : : BitVector ( this - > model . getNumberOfStates ( ) ,  true ) ,  targetStates ) ;  
			
		
	
		
			
				
					            maybeStates  =  ~ targetStates  &  statesWithProbability1 ;  
			
		
	
		
			
				
					            // If the initial state is known to have 0 reward or an infinite reward value, we can directly set the reachRewardFunction.
  
			
		
	
		
			
				
					            storm : : storage : : sparse : : state_type  initialState  =  * this - > model . getInitialStates ( ) . begin ( ) ;  
			
		
	
		
			
				
					            if  ( ! maybeStates . get ( initialState ) )  {  
			
		
	
		
			
				
					                STORM_LOG_WARN ( " The expected reward of the initial state is constant (infinity or zero) " ) ;  
			
		
	
		
			
				
					                this - > reachabilityFunction  =  std : : make_shared < ParametricType > ( statesWithProbability1 . get ( initialState )  ?  storm : : utility : : zero < ParametricType > ( )  :  storm : : utility : : infinity < ParametricType > ( ) ) ;  
			
		
	
		
			
				
					                this - > isResultConstant = true ;  
			
		
	
		
			
				
					                return ;  //nothing else to do...
  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            stateRewards = std : : vector < ParametricType > ( maybeStates . getNumberOfSetBits ( ) ) ;  
			
		
	
		
			
				
					            if  ( this - > model . hasTransitionRewards ( ) )  {  
			
		
	
		
			
				
					                // If a transition-based reward model is available, we initialize the state reward vector to the row sums of the matrix
  
			
		
	
		
			
				
					                // that results from taking the pointwise product of the transition probability matrix and the transition reward matrix.
  
			
		
	
		
			
				
					                std : : vector < ParametricType >  pointwiseProductRowSumVector  =  this - > model . getTransitionMatrix ( ) . getPointwiseProductRowSumVector ( this - > model . getTransitionRewardMatrix ( ) ) ;  
			
		
	
		
			
				
					                storm : : utility : : vector : : selectVectorValues ( stateRewards ,  maybeStates ,  pointwiseProductRowSumVector ) ;  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                if  ( this - > model . hasStateRewards ( ) )  {  
			
		
	
		
			
				
					                    // If a state-based reward model is also available, we need to add this vector
  
			
		
	
		
			
				
					                    // as well. As the state reward vector contains entries not just for the states
  
			
		
	
		
			
				
					                    // that we still consider (i.e. maybeStates), we need to extract these values
  
			
		
	
		
			
				
					                    // first.
  
			
		
	
		
			
				
					                    std : : vector < ParametricType >  subStateRewards ( stateRewards . size ( ) ) ;  
			
		
	
		
			
				
					                    storm : : utility : : vector : : selectVectorValues ( subStateRewards ,  maybeStates ,  this - > model . getStateRewardVector ( ) ) ;  
			
		
	
		
			
				
					                    storm : : utility : : vector : : addVectors ( stateRewards ,  subStateRewards ,  stateRewards ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					            }  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
  
			
		
	
		
			
				
					                // states that we still consider (i.e. maybeStates), we need to extract these values
  
			
		
	
		
			
				
					                // first.
  
			
		
	
		
			
				
					                storm : : utility : : vector : : selectVectorValues ( stateRewards ,  maybeStates ,  this - > model . getStateRewardVector ( ) ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					        }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        template < typename  ParametricType ,  typename  ConstantType >  
			
		
	
		
			
				
					        void  SparseDtmcRegionModelChecker < ParametricType ,  ConstantType > : : initializeApproximationModel ( storm : : models : : sparse : : Dtmc < ParametricType >  const &  simpleModel )  {  
			
		
	
		
			
				
					            std : : chrono : : high_resolution_clock : : time_point  timeInitApproxModelStart  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -311,16 +419,20 @@ namespace storm { 
			
		
	
		
			
				
					            //now compute the functions using methods from elimination model checker
  
			
		
	
		
			
				
					            storm : : storage : : BitVector  newInitialStates  =  simpleModel . getInitialStates ( )  %  maybeStates ;  
			
		
	
		
			
				
					            storm : : storage : : BitVector  phiStates ( simpleModel . getNumberOfStates ( ) ,  true ) ;  
			
		
	
		
			
				
					            boost : : optional < std : : vector < ParametricType > >  noStateRewards ;  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            boost : : optional < std : : vector < ParametricType > >  stateRewards ;  
			
		
	
		
			
				
					            if ( this - > computeRewards ) {  
			
		
	
		
			
				
					                std : : vector < ParametricType >  stateRewardsAsVector ( maybeStates . getNumberOfSetBits ( ) ) ;  
			
		
	
		
			
				
					                storm : : utility : : vector : : selectVectorValues ( stateRewardsAsVector ,  maybeStates ,  simpleModel . getStateRewardVector ( ) ) ;  
			
		
	
		
			
				
					                stateRewards = std : : move ( stateRewardsAsVector ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            std : : vector < std : : size_t >  statePriorities  =  this - > eliminationModelChecker . getStatePriorities ( forwardTransitions , backwardTransitions , newInitialStates , oneStepProbabilities ) ;  
			
		
	
		
			
				
					            this - > reachabilityFunction = std : : make_shared < ParametricType > ( this - > eliminationModelChecker . computeReachabilityValue ( forwardTransitions ,  oneStepProbabilities ,  backwardTransitions ,  newInitialStates  ,  phiStates ,  simpleModel . getStates ( " target " ) ,  noStateRewards ,  statePriorities ) ) ;  
			
		
	
		
			
				
					            /*    std::string funcStr = " (/ " +
  
			
		
	
		
			
				
					                                this - > reachProbFunction - > nominator ( ) . toString ( false ,  true )  +  "   "  +  
			
		
	
		
			
				
					                                this - > reachProb Function - > denominator ( ) . toString ( false ,  true )  +  
			
		
	
		
			
				
					            this - > reachabilityFunction = std : : make_shared < ParametricType > ( this - > eliminationModelChecker . computeReachabilityValue ( forwardTransitions ,  oneStepProbabilities ,  backwardTransitions ,  newInitialStates  ,  phiStates ,  simpleModel . getStates ( " target " ) ,  s tateRewards,  statePriorities ) ) ;  
			
		
	
		
			
				
					                /* std::string funcStr = " (/ " +
  
			
		
	
		
			
				
					                                this - > reachability Function - > nominator ( ) . toString ( false ,  true )  +  "   "  +  
			
		
	
		
			
				
					                                this - > reachability Function - > denominator ( ) . toString ( false ,  true )  +  
			
		
	
		
			
				
					                            "  ) " ;  
			
		
	
		
			
				
					                std : : cout  < <  std : : endl  < < " the resulting reach prob function is  "  < <  std : : endl  < <  funcStr  < <  std : : endl  < <  std : : endl ; */  
			
		
	
		
			
				
					            STORM_LOG_DEBUG ( " Computed reachProb Function " ) ;  
			
		
	
		
			
				
					            STORM_LOG_DEBUG ( " Computed reachability Function " ) ;  
			
		
	
		
			
				
					            std : : chrono : : high_resolution_clock : : time_point  timeComputeReachabilityFunctionEnd  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
			
		
	
		
			
				
					            this - > timeComputeReachabilityFunction  =  timeComputeReachabilityFunctionEnd - timeComputeReachabilityFunctionStart ;  
			
		
	
		
			
				
					        }  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -336,8 +448,8 @@ namespace storm { 
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            //switches for the different steps.
  
			
		
	
		
			
				
					            bool  done = false ;  
			
		
	
		
			
				
					            STORM_LOG_WARN_COND (  ( ! storm : : settings : : regionSettings ( ) . doApprox ( )  | |  this - > hasOnlyLinearFunctions ) ,  " the approximation is only correct if the model has only linear functions. As this is not the case, approximation is deactivated " ) ;  
			
		
	
		
			
				
					            bool  doApproximation = storm : : settings : : regionSettings ( ) . doApprox ( )  & &  this - > hasOnlyLinearFunctions ;  
			
		
	
		
			
				
					            STORM_LOG_WARN_COND (  ( ! storm : : settings : : regionSettings ( ) . doApprox ( )  | |  this - > isApproximationApplicable ) ,  " the approximation is only correct if the model has only linear functions. As this is not the case, approximation is deactivated " ) ;  
			
		
	
		
			
				
					            bool  doApproximation = storm : : settings : : regionSettings ( ) . doApprox ( )  & &  this - > isApproximationApplicable ;  
			
		
	
		
			
				
					            bool  doSampling = storm : : settings : : regionSettings ( ) . doSample ( ) ;  
			
		
	
		
			
				
					            bool  doFullSmt = storm : : settings : : regionSettings ( ) . doSmt ( ) ;  
			
		
	
		
			
				
					             
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -429,7 +541,7 @@ namespace storm { 
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        template < typename  ParametricType ,  typename  ConstantType >  
			
		
	
		
			
				
					        bool  SparseDtmcRegionModelChecker < ParametricType ,  ConstantType > : : checkApproximativeValues ( ParameterRegion &  region ,  std : : vector < ConstantType > &  lowerBounds ,  std : : vector < ConstantType > &  upperBounds )  {  
			
		
	
		
			
				
					            STORM_LOG_THROW ( this - > hasOnlyLinearFunctions ,  storm : : exceptions : : UnexpectedException ,  " Tried to perform approximative method (only applicable if all functions are linear), but there are nonlinear functions. " ) ;  
			
		
	
		
			
				
					            STORM_LOG_THROW ( this - > isApproximationApplicable ,  storm : : exceptions : : UnexpectedException ,  " Tried to perform approximative method (only applicable if all functions are linear), but there are nonlinear functions. " ) ;  
			
		
	
		
			
				
					            std : : chrono : : high_resolution_clock : : time_point  timeMDPBuildStart  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
			
		
	
		
			
				
					            getApproximationModel ( ) - > instantiate ( region ) ;  
			
		
	
		
			
				
					            std : : chrono : : high_resolution_clock : : time_point  timeMDPBuildEnd  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -772,8 +884,8 @@ namespace storm { 
			
		
	
		
			
				
					                return ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            std : : chrono : : milliseconds  timeSpecifyFormulaInMilliseconds  =  std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeSpecifyFormula ) ;  
			
		
	
		
			
				
					            std : : chrono : : milliseconds  timePreprocessingInMilliseconds  =  std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timePreprocessing ) ;  
			
		
	
		
			
				
					            std : : chrono : : milliseconds  timeComputeSimplifiedModelInMilliseconds  =  std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeComputeSimplifiedModel ) ;  
			
		
	
		
			
				
					            std : : chrono : : milliseconds  timeInitSamplingModelInMilliseconds  =  std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeInitSamplingModel ) ;  
			
		
	
		
			
				
					            std : : chrono : : milliseconds  timeInitApproxModelInMilliseconds  =  std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeInitApproxModel ) ;  
			
		
	
		
			
				
					            std : : chrono : : milliseconds  timeComputeReachabilityFunctionInMilliseconds  =  std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeComputeReachabilityFunction ) ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -783,7 +895,7 @@ namespace storm { 
			
		
	
		
			
				
					            std : : chrono : : milliseconds  timeMDPBuildInMilliseconds  =  std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeMDPBuild ) ;  
			
		
	
		
			
				
					            std : : chrono : : milliseconds  timeFullSmtInMilliseconds  =  std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeFullSmt ) ;  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            std : : chrono : : high_resolution_clock : : duration  timeOverall  =  timePreprocessing   +  timeCheckRegion ;  // + ...
  
			
		
	
		
			
				
					            std : : chrono : : high_resolution_clock : : duration  timeOverall  =  timeSpecifyFormula   +  timeCheckRegion ;  // + ...
  
			
		
	
		
			
				
					            std : : chrono : : milliseconds  timeOverallInMilliseconds  =  std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( timeOverall ) ;  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            uint_fast64_t  numOfSolvedRegions =  this - > numOfRegionsExistsBoth  +  this - > numOfRegionsAllSat  +  this - > numOfRegionsAllViolated ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -791,14 +903,14 @@ namespace storm { 
			
		
	
		
			
				
					            outstream  < <  std : : endl  < <  " Region Model Checker Statistics: "  < <  std : : endl ;  
			
		
	
		
			
				
					            outstream  < <  " ----------------------------------------------- "  < <  std : : endl ;  
			
		
	
		
			
				
					            outstream  < <  " Model:  "  < <  this - > model . getNumberOfStates ( )  < <  "  states,  "  < <  this - > model . getNumberOfTransitions ( )  < <  "  transitions. "  < <  std : : endl ;  
			
		
	
		
			
				
					            outstream  < <  " Formula:  "  < <  * this - > specifiedFormula  < <  std : : endl ;  
			
		
	
		
			
				
					            if ( this - > isResultConstant ) {  
			
		
	
		
			
				
					                outstream  < <  " The requested value is constant (i.e. independent of any parameters) "  < <  std : : endl ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            else {  
			
		
	
		
			
				
					                outstream  < <  " Simplified model:  "  < <  this - > simplifiedModel - > getNumberOfStates ( )  < <  "  states,  "  < <  this - > simplifiedModel - > getNumberOfTransitions ( )  < <  "  transitions "  < <  std : : endl ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            outstream  < <  " Formula:  "  < <  * this - > specifiedFormula  < <  std : : endl ;  
			
		
	
		
			
				
					            outstream  < <  ( this - > hasOnlyLinearFunctions  ?  " A "  :  " Not a " )  < <  " ll occuring functions in the model are linear "  < <  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 ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -812,8 +924,8 @@ namespace storm { 
			
		
	
		
			
				
					            outstream  < <  std : : endl ;  
			
		
	
		
			
				
					            outstream  < <  " Running times: "  < <  std : : endl ;  
			
		
	
		
			
				
					            outstream  < <  "    "  < <  timeOverallInMilliseconds . count ( )  < <  " ms overall (excluding model parsing, bisimulation (if applied)) "  < <  std : : endl ;  
			
		
	
		
			
				
					            outstream  < <  "    "  < <  timePreprocessing InMilliseconds . count ( )  < <  " ms Preprocessing  including...  "  < <  std : : endl ;  
			
		
	
		
			
				
					            outstream  < <  "      "  < <  timeComputeSimplifiedModel InMilliseconds . count ( )  < <  " ms to obtain a simplified model ( state elimination of const transitions) "  < <  std : : endl ;  
			
		
	
		
			
				
					            outstream  < <  "    "  < <  timeSpecifyFormula InMilliseconds . count ( )  < <  " ms Initialization for the specified formula,  including...  "  < <  std : : endl ;  
			
		
	
		
			
				
					            outstream  < <  "      "  < <  timePreprocessing InMilliseconds . count ( )  < <  " ms for Preprocessing (mainly to obtain a simplified model, i.e.,  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 ;