@ -121,6 +121,8 @@ namespace storm { 
			
		
	
		
			
				
					                ValueType  two  =  storm : : utility : : convertNumber < ValueType > ( 2.0 ) ;  
			
		
	
		
			
				
					                / /  Relative  errors  
			
		
	
		
			
				
					                bool  relative  =  env . solver ( ) . minMax ( ) . getRelativeTerminationCriterion ( ) ;  
			
		
	
		
			
				
					                / /  Use  no  termination  guaranteed  upper  bound  iteration  method  
			
		
	
		
			
				
					                bool  noTerminationGuarantee  =  env . solver ( ) . ovi ( ) . useNoTerminationGuaranteeMinimumMethod ( ) ;  
			
		
	
		
			
				
					                / /  Goal  precision  
			
		
	
		
			
				
					                ValueType  precision  =  storm : : utility : : convertNumber < ValueType > ( env . solver ( ) . minMax ( ) . getPrecision ( ) ) ;  
			
		
	
		
			
				
					                / /  Desired  max  difference  between  upperX  and  lowerX  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -135,142 +137,40 @@ namespace storm { 
			
		
	
		
			
				
					     
			
		
	
		
			
				
					                SolverStatus  status  =  SolverStatus : : InProgress ;  
			
		
	
		
			
				
					     
			
		
	
		
			
				
					                if ( env . solver ( ) . ovi ( ) . useTerminationGuaranteedMinimumMethod ( ) )  {  
			
		
	
		
			
				
					                    while  ( status  = =  SolverStatus : : InProgress  & &  overallIterations  <  maxOverallIterations )  {  
			
		
	
		
			
				
					                while  ( status  = =  SolverStatus : : InProgress  & &  overallIterations  <  maxOverallIterations )  {  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                         / /  Perform  value  iteration  until  convergence  
			
		
	
		
			
				
					                         + + valueIterationInvocations ;  
			
		
	
		
			
				
					                         auto  result  =  valueIterationCallback ( lowerX ,  auxVector ,  iterationPrecision ,  relative ,  overallIterations ,  maxOverallIterations ) ;  
			
		
	
		
			
				
					                         lastValueIterationIterations  =  result . iterations ;  
			
		
	
		
			
				
					                         overallIterations  + =  result . iterations ;  
			
		
	
		
			
				
					                    / /  Perform  value  iteration  until  convergence  
			
		
	
		
			
				
					                    + + valueIterationInvocations ;  
			
		
	
		
			
				
					                    auto  result  =  valueIterationCallback ( lowerX ,  auxVector ,  iterationPrecision ,  relative ,  overallIterations ,  maxOverallIterations ) ;  
			
		
	
		
			
				
					                    lastValueIterationIterations  =  result . iterations ;  
			
		
	
		
			
				
					                    overallIterations  + =  result . iterations ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                        if  ( result . status  ! =  SolverStatus : : Converged )  {  
			
		
	
		
			
				
					                            status  =  result . status ;  
			
		
	
		
			
				
					                        }  else  {  
			
		
	
		
			
				
					                            bool  intervalIterationNeeded  =  false ;  
			
		
	
		
			
				
					                            currentVerificationIterations  =  0 ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                            if  ( relative )  {  
			
		
	
		
			
				
					                                oviinternal : : guessUpperBoundRelative ( * lowerX ,  * upperX ,  relativeBoundGuessingScaler ) ;  
			
		
	
		
			
				
					                            }  else  {  
			
		
	
		
			
				
					                                oviinternal : : guessUpperBoundAbsolute ( * lowerX ,  * upperX ,  precision ) ;  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                            bool  cancelGuess  =  false ;  
			
		
	
		
			
				
					                            while  ( status  = =  SolverStatus : : InProgress  & &  overallIterations  <  maxOverallIterations )  {  
			
		
	
		
			
				
					                                + + overallIterations ;  
			
		
	
		
			
				
					                                + + currentVerificationIterations ;  
			
		
	
		
			
				
					                                / /  Perform  value  iteration  stepwise  for  lower  bound  and  guessed  upper  bound  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                                / /  Upper  bound  iteration  
			
		
	
		
			
				
					                                singleIterationCallback ( upperX ,  auxVector ,  overallIterations ) ;  
			
		
	
		
			
				
					                                / /  At  this  point , h  auxVector  contains  the  old  values  for  the  upper  bound  whereas  upperX  contains  the  new  ones .  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                                / /  Compare  the  new  upper  bound  candidate  with  the  old  one  
			
		
	
		
			
				
					                                bool  newUpperBoundAlwaysHigherEqual  =  true ;  
			
		
	
		
			
				
					                                bool  newUpperBoundAlwaysLowerEqual  =  true ;  
			
		
	
		
			
				
					                                for  ( uint64_t  i  =  0 ;  i  <  upperX - > size ( ) ;  + + i )  {  
			
		
	
		
			
				
					                                    if  ( ( * upperX ) [ i ]  <  ( * auxVector ) [ i ] )  {  
			
		
	
		
			
				
					                                        newUpperBoundAlwaysHigherEqual  =  false ;  
			
		
	
		
			
				
					                                    }  else  if  ( ( * upperX ) [ i ]  ! =  ( * auxVector ) [ i ] )  {  
			
		
	
		
			
				
					                                        newUpperBoundAlwaysLowerEqual  =  false ;  
			
		
	
		
			
				
					                                        std : : swap ( ( * upperX ) [ i ] ,  ( * auxVector ) [ i ] ) ;  
			
		
	
		
			
				
					                                    }  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                                if  ( newUpperBoundAlwaysHigherEqual  & !  newUpperBoundAlwaysLowerEqual )  {  
			
		
	
		
			
				
					                                    / /  All  values  moved  up  or  stayed  the  same  
			
		
	
		
			
				
					                                    / /  That  means  the  guess  for  an  upper  bound  is  actually  a  lower  bound  
			
		
	
		
			
				
					                                    iterationPrecision  =  oviinternal : : updateIterationPrecision ( env ,  * auxVector ,  * upperX ,  relative ,  relevantValues ) ;  
			
		
	
		
			
				
					                                    / /  We  assume  to  have  a  single  fixed  point .  We  can  thus  safely  set  the  new  lower  bound ,  to  the  wrongly  guessed  upper  bound  
			
		
	
		
			
				
					                                    / /  Set  lowerX  to  the  upper  bound  candidate  
			
		
	
		
			
				
					                                    std : : swap ( lowerX ,  upperX ) ;  
			
		
	
		
			
				
					                                    break ;  
			
		
	
		
			
				
					                                }  else  if  ( newUpperBoundAlwaysLowerEqual  & !  newUpperBoundAlwaysHigherEqual )  {  
			
		
	
		
			
				
					                                    / /  All  values  moved  down  or  stayed  the  same  and  we  have  a  maximum  difference  of  twice  the  requested  precision  
			
		
	
		
			
				
					                                    / /  We  can  safely  use  twice  the  requested  precision ,  as  we  calculate  the  center  of  both  vectors  
			
		
	
		
			
				
					                                    bool  reachedPrecision ;  
			
		
	
		
			
				
					                                    if  ( relevantValues )  {  
			
		
	
		
			
				
					                                        reachedPrecision  =  storm : : utility : : vector : : equalModuloPrecision ( * lowerX ,  * upperX ,  relevantValues . get ( ) ,  doublePrecision ,  relative ) ;  
			
		
	
		
			
				
					                                    }  else  {  
			
		
	
		
			
				
					                                        reachedPrecision  =  storm : : utility : : vector : : equalModuloPrecision ( * lowerX ,  * upperX ,  doublePrecision ,  relative ) ;  
			
		
	
		
			
				
					                                    }  
			
		
	
		
			
				
					                                    if  ( reachedPrecision )  {  
			
		
	
		
			
				
					                                        status  =  SolverStatus : : Converged ;  
			
		
	
		
			
				
					                                        break ;  
			
		
	
		
			
				
					                                    }  else  {  
			
		
	
		
			
				
					                                        / /  From  now  on ,  we  keep  updating  both  bounds  
			
		
	
		
			
				
					                                        intervalIterationNeeded  =  true ;  
			
		
	
		
			
				
					                                    }  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                                / /  At  this  point ,  the  old  upper  bounds  ( auxVector )  are  not  needed  anymore .  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                                / /  Check  whether  we  tried  this  guess  for  too  long  
			
		
	
		
			
				
					                                ValueType  scaledIterationCount  =  storm : : utility : : convertNumber < ValueType > ( currentVerificationIterations )  *  storm : : utility : : convertNumber < ValueType > ( env . solver ( ) . ovi ( ) . getMaxVerificationIterationFactor ( ) ) ;  
			
		
	
		
			
				
					                                if  ( ! intervalIterationNeeded  & &  scaledIterationCount  > =  storm : : utility : : convertNumber < ValueType > ( lastValueIterationIterations ) )  {  
			
		
	
		
			
				
					                                    cancelGuess  =  true ;  
			
		
	
		
			
				
					                                    / /  In  this  case  we  will  make  one  more  iteration  on  the  lower  bound  ( mainly  to  obtain  a  new  iterationPrecision )  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                                / /  Lower  bound  iteration  ( only  if  needed )  
			
		
	
		
			
				
					                                if  ( cancelGuess  | |  intervalIterationNeeded  | |  currentVerificationIterations  >  upperBoundOnlyIterations )  {  
			
		
	
		
			
				
					                                    singleIterationCallback ( lowerX ,  auxVector ,  overallIterations ) ;  
			
		
	
		
			
				
					                                    / /  At  this  point ,  auxVector  contains  the  old  values  for  the  lower  bound  whereas  lowerX  contains  the  new  ones .  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                                    / /  Check  whether  the  upper  and  lower  bounds  have  crossed ,  i . e . ,  the  upper  bound  is  smaller  than  the  lower  bound .  
			
		
	
		
			
				
					                                    bool  valuesCrossed  =  false ;  
			
		
	
		
			
				
					                                    for  ( uint64_t  i  =  0 ;  i  <  lowerX - > size ( ) ;  + + i )  {  
			
		
	
		
			
				
					                                        if  ( ( * upperX ) [ i ]  <  ( * lowerX ) [ i ] )  {  
			
		
	
		
			
				
					                                            valuesCrossed  =  true ;  
			
		
	
		
			
				
					                                            break ;  
			
		
	
		
			
				
					                                        }  
			
		
	
		
			
				
					                                    }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                                    if  ( cancelGuess  | |  valuesCrossed )  {  
			
		
	
		
			
				
					                                        / /  A  new  guess  is  needed .  
			
		
	
		
			
				
					                                        iterationPrecision  =  oviinternal : : updateIterationPrecision ( env ,  * auxVector ,  * lowerX ,  relative ,  relevantValues ) ;  
			
		
	
		
			
				
					                                        break ;  
			
		
	
		
			
				
					                                    }  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                else  {  
			
		
	
		
			
				
					                    while  ( status  = =  SolverStatus : : InProgress  & &  overallIterations  <  maxOverallIterations )  {  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                        / /  Perform  value  iteration  until  convergence  
			
		
	
		
			
				
					                        + + valueIterationInvocations ;  
			
		
	
		
			
				
					                        auto  result  =  valueIterationCallback ( lowerX ,  auxVector ,  iterationPrecision ,  relative ,  overallIterations ,  maxOverallIterations ) ;  
			
		
	
		
			
				
					                        lastValueIterationIterations  =  result . iterations ;  
			
		
	
		
			
				
					                        overallIterations  + =  result . iterations ;  
			
		
	
		
			
				
					                    if  ( result . status  ! =  SolverStatus : : Converged )  {  
			
		
	
		
			
				
					                        status  =  result . status ;  
			
		
	
		
			
				
					                    }  else  {  
			
		
	
		
			
				
					                        bool  intervalIterationNeeded  =  false ;  
			
		
	
		
			
				
					                        currentVerificationIterations  =  0 ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                        if  ( result . status  ! =  SolverStatus : : Converged  )  {  
			
		
	
		
			
				
					                            status  =  result . status ;  
			
		
	
		
			
				
					                        if  ( relative )  {  
			
		
	
		
			
				
					                            oviinternal : : guessUpperBoundRelative ( * lowerX ,  * upperX ,  relativeBoundGuessingScaler ) ;  
			
		
	
		
			
				
					                        }  else  {  
			
		
	
		
			
				
					                            bool  intervalIterationNeeded  =  false ;  
			
		
	
		
			
				
					                            currentVerificationIterations  =  0 ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                            if  ( relative )  {  
			
		
	
		
			
				
					                                oviinternal : : guessUpperBoundRelative ( * lowerX ,  * upperX ,  relativeBoundGuessingScaler ) ;  
			
		
	
		
			
				
					                            }  else  {  
			
		
	
		
			
				
					                                oviinternal : : guessUpperBoundAbsolute ( * lowerX ,  * upperX ,  precision ) ;  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                            bool  cancelGuess  =  false ;  
			
		
	
		
			
				
					                            while  ( status  = =  SolverStatus : : InProgress  & &  overallIterations  <  maxOverallIterations )  {  
			
		
	
		
			
				
					                                + + overallIterations ;  
			
		
	
		
			
				
					                                + + currentVerificationIterations ;  
			
		
	
		
			
				
					                                / /  Perform  value  iteration  stepwise  for  lower  bound  and  guessed  upper  bound  
			
		
	
		
			
				
					                            oviinternal : : guessUpperBoundAbsolute ( * lowerX ,  * upperX ,  precision ) ;  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                                / /  Upper  bound  iteration  
			
		
	
		
			
				
					                                singleIterationCallback ( upperX ,  auxVector ,  overallIterations ) ;  
			
		
	
		
			
				
					                        bool  cancelGuess  =  false ;  
			
		
	
		
			
				
					                        while  ( status  = =  SolverStatus : : InProgress  & &  overallIterations  <  maxOverallIterations )  {  
			
		
	
		
			
				
					                            + + overallIterations ;  
			
		
	
		
			
				
					                            + + currentVerificationIterations ;  
			
		
	
		
			
				
					                            / /  Perform  value  iteration  stepwise  for  lower  bound  and  guessed  upper  bound  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                                / /  At  this  point , h  auxVector  contains  the  old  values  for  the  upper  bound  whereas  upperX  contains  the  new  ones .  
			
		
	
		
			
				
					                            / /  Upper  bound  iteration  
			
		
	
		
			
				
					                            singleIterationCallback ( upperX ,  auxVector ,  overallIterations ) ;  
			
		
	
		
			
				
					                            / /  At  this  point , h  auxVector  contains  the  old  values  for  the  upper  bound  whereas  upperX  contains  the  new  ones .  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                                / /  Compare  the  new  upper  bound  candidate  with  the  old  one  
			
		
	
		
			
				
					                                bool  newUpperBoundAlwaysHigherEqual  =  true ;  
			
		
	
		
			
				
					                                bool  newUpperBoundAlwaysLowerEqual  =  true ;  
			
		
	
		
			
				
					                            / /  Compare  the  new  upper  bound  candidate  with  the  old  one  
			
		
	
		
			
				
					                            bool  newUpperBoundAlwaysHigherEqual  =  true ;  
			
		
	
		
			
				
					                            bool  newUpperBoundAlwaysLowerEqual  =  true ;  
			
		
	
		
			
				
					                            if ( noTerminationGuarantee )  {  
			
		
	
		
			
				
					                                bool  cancelOuterScan  =  false ;  
			
		
	
		
			
				
					                                for  ( uint64_t  i  =  0 ;  i  <  upperX - > size ( )  & !  cancelOuterScan ;  + + i )  {  
			
		
	
		
			
				
					                                    if  ( ( * upperX ) [ i ]  <  ( * auxVector ) [ i ] )  {  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -288,8 +188,8 @@ namespace storm { 
			
		
	
		
			
				
					                                        newUpperBoundAlwaysLowerEqual  =  false ;  
			
		
	
		
			
				
					                                        + + i ;  
			
		
	
		
			
				
					                                        while  ( i  <  upperX - > size ( ) )  {  
			
		
	
		
			
				
					                                            if  ( ( * upperX ) [ i ]  > ( * auxVector ) [ i ] )  {  
			
		
	
		
			
				
					                                                newUpperBoundAlwaysLow erEqual  =  false ;  
			
		
	
		
			
				
					                                            if  ( ( * upperX ) [ i ]  < ( * auxVector ) [ i ] )  {  
			
		
	
		
			
				
					                                                newUpperBoundAlwaysHigh erEqual  =  false ;  
			
		
	
		
			
				
					                                                cancelOuterScan  =  true ;  
			
		
	
		
			
				
					                                                break ;  
			
		
	
		
			
				
					                                            }  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -297,61 +197,71 @@ namespace storm { 
			
		
	
		
			
				
					                                        }  
			
		
	
		
			
				
					                                    }  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                                if  ( newUpperBoundAlwaysHigherEqual  & !  newUpperBoundAlwaysLowerEqual )  {  
			
		
	
		
			
				
					                                    / /  All  values  moved  up  or  stayed  the  same  
			
		
	
		
			
				
					                                    / /  That  means  the  guess  for  an  upper  bound  is  actually  a  lower  bound  
			
		
	
		
			
				
					                                    iterationPrecision  =  oviinternal : : updateIterationPrecision ( env ,  * auxVector ,  * upperX ,  relative ,  relevantValues ) ;  
			
		
	
		
			
				
					                                    / /  We  assume  to  have  a  single  fixed  point .  We  can  thus  safely  set  the  new  lower  bound ,  to  the  wrongly  guessed  upper  bound  
			
		
	
		
			
				
					                                    / /  Set  lowerX  to  the  upper  bound  candidate  
			
		
	
		
			
				
					                                    std : : swap ( lowerX ,  upperX ) ;  
			
		
	
		
			
				
					                                    break ;  
			
		
	
		
			
				
					                                }  else  if  ( newUpperBoundAlwaysLowerEqual  & !  newUpperBoundAlwaysHigherEqual )  {  
			
		
	
		
			
				
					                                    / /  All  values  moved  down  or  stayed  the  same  and  we  have  a  maximum  difference  of  twice  the  requested  precision  
			
		
	
		
			
				
					                                    / /  We  can  safely  use  twice  the  requested  precision ,  as  we  calculate  the  center  of  both  vectors  
			
		
	
		
			
				
					                                    bool  reachedPrecision ;  
			
		
	
		
			
				
					                                    if  ( relevantValues )  {  
			
		
	
		
			
				
					                                        reachedPrecision  =  storm : : utility : : vector : : equalModuloPrecision ( * lowerX ,  * upperX ,  relevantValues . get ( ) ,  doublePrecision ,  relative ) ;  
			
		
	
		
			
				
					                                    }  else  {  
			
		
	
		
			
				
					                                        reachedPrecision  =  storm : : utility : : vector : : equalModuloPrecision ( * lowerX ,  * upperX ,  doublePrecision ,  relative ) ;  
			
		
	
		
			
				
					                                    }  
			
		
	
		
			
				
					                                    if  ( reachedPrecision )  {  
			
		
	
		
			
				
					                                        status  =  SolverStatus : : Converged ;  
			
		
	
		
			
				
					                                        break ;  
			
		
	
		
			
				
					                                    }  else  {  
			
		
	
		
			
				
					                                        / /  From  now  on ,  we  keep  updating  both  bounds  
			
		
	
		
			
				
					                                        intervalIterationNeeded  =  true ;  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                            else  {  
			
		
	
		
			
				
					                                for  ( uint64_t  i  =  0 ;  i  <  upperX - > size ( ) ;  + + i )  {  
			
		
	
		
			
				
					                                    if  ( ( * upperX ) [ i ]  <  ( * auxVector ) [ i ] )  {  
			
		
	
		
			
				
					                                        newUpperBoundAlwaysHigherEqual  =  false ;  
			
		
	
		
			
				
					                                    }  else  if  ( ( * upperX ) [ i ]  ! =  ( * auxVector ) [ i ] )  {  
			
		
	
		
			
				
					                                        newUpperBoundAlwaysLowerEqual  =  false ;  
			
		
	
		
			
				
					                                        std : : swap ( ( * upperX ) [ i ] ,  ( * auxVector ) [ i ] ) ;  
			
		
	
		
			
				
					                                    }  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                                / /  At  this  point ,  the  old  upper  bounds  ( auxVector )  are  not  needed  anymore .   
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                                / /  Check  whether  we  tried  this  guess  for  too  long  
			
		
	
		
			
				
					                                ValueType  scaledIterationCount  =  storm : : utility : : convertNumber < ValueType > ( currentVerificationIterations )  *  storm : : utility : : convertNumber < ValueType > ( env . solver ( ) . ovi ( ) . getMaxVerificationIterationFactor ( ) ) ;  
			
		
	
		
			
				
					                                if  ( ! intervalIterationNeeded  & &  scaledIterationCount  > =  storm : : utility : : convertNumber < ValueType > ( lastValueIterationIterations ) )  {  
			
		
	
		
			
				
					                                    cancelGuess  =  true ;  
			
		
	
		
			
				
					                                    / /  In  this  case  we  will  make  one  more  iteration  on  the  lower  bound  ( mainly  to  obtain  a  new  iterationPrecision )  
			
		
	
		
			
				
					                            if  ( newUpperBoundAlwaysHigherEqual  & !  newUpperBoundAlwaysLowerEqual )  {  
			
		
	
		
			
				
					                                / /  All  values  moved  up  or  stayed  the  same  
			
		
	
		
			
				
					                                / /  That  means  the  guess  for  an  upper  bound  is  actually  a  lower  bound  
			
		
	
		
			
				
					                                iterationPrecision  =  oviinternal : : updateIterationPrecision ( env ,  * auxVector ,  * upperX ,  relative ,  relevantValues ) ;  
			
		
	
		
			
				
					                                / /  We  assume  to  have  a  single  fixed  point .  We  can  thus  safely  set  the  new  lower  bound ,  to  the  wrongly  guessed  upper  bound  
			
		
	
		
			
				
					                                / /  Set  lowerX  to  the  upper  bound  candidate  
			
		
	
		
			
				
					                                std : : swap ( lowerX ,  upperX ) ;  
			
		
	
		
			
				
					                                break ;  
			
		
	
		
			
				
					                            }  else  if  ( newUpperBoundAlwaysLowerEqual  & !  newUpperBoundAlwaysHigherEqual )  {  
			
		
	
		
			
				
					                                / /  All  values  moved  down  or  stayed  the  same  and  we  have  a  maximum  difference  of  twice  the  requested  precision  
			
		
	
		
			
				
					                                / /  We  can  safely  use  twice  the  requested  precision ,  as  we  calculate  the  center  of  both  vectors  
			
		
	
		
			
				
					                                bool  reachedPrecision ;  
			
		
	
		
			
				
					                                if  ( relevantValues )  {  
			
		
	
		
			
				
					                                    reachedPrecision  =  storm : : utility : : vector : : equalModuloPrecision ( * lowerX ,  * upperX ,  relevantValues . get ( ) ,  doublePrecision ,  relative ) ;  
			
		
	
		
			
				
					                                }  else  {  
			
		
	
		
			
				
					                                    reachedPrecision  =  storm : : utility : : vector : : equalModuloPrecision ( * lowerX ,  * upperX ,  doublePrecision ,  relative ) ;  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                                if  ( reachedPrecision )  {  
			
		
	
		
			
				
					                                    status  =  SolverStatus : : Converged ;  
			
		
	
		
			
				
					                                    break ;  
			
		
	
		
			
				
					                                }  else  {  
			
		
	
		
			
				
					                                    / /  From  now  on ,  we  keep  updating  both  bounds  
			
		
	
		
			
				
					                                    intervalIterationNeeded  =  true ;  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                            / /  At  this  point ,  the  old  upper  bounds  ( auxVector )  are  not  needed  anymore .  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                                / /  Lower  bound  iteration  ( only  if  needed )  
			
		
	
		
			
				
					                                if  ( cancelGuess  | |  intervalIterationNeeded  | |  currentVerificationIterations  >  upperBoundOnlyIterations )  {  
			
		
	
		
			
				
					                                    singleIterationCallback ( lowerX ,  auxVector ,  overallIterations ) ;  
			
		
	
		
			
				
					                                    / /  At  this  point ,  auxVector  contains  the  old  values  for  the  lower  bound  whereas  lowerX  contains  the  new  ones .  
			
		
	
		
			
				
					                            / /  Check  whether  we  tried  this  guess  for  too  long  
			
		
	
		
			
				
					                            ValueType  scaledIterationCount  =  storm : : utility : : convertNumber < ValueType > ( currentVerificationIterations )  *  storm : : utility : : convertNumber < ValueType > ( env . solver ( ) . ovi ( ) . getMaxVerificationIterationFactor ( ) ) ;  
			
		
	
		
			
				
					                            if  ( ! intervalIterationNeeded  & &  scaledIterationCount  > =  storm : : utility : : convertNumber < ValueType > ( lastValueIterationIterations ) )  {  
			
		
	
		
			
				
					                                cancelGuess  =  true ;  
			
		
	
		
			
				
					                                / /  In  this  case  we  will  make  one  more  iteration  on  the  lower  bound  ( mainly  to  obtain  a  new  iterationPrecision )  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                                    / /  Check  whether  the  upper  and  lower  bounds  have  crossed ,  i . e . ,  the  upper  bound  is  smaller  than  the  lower  bound .  
			
		
	
		
			
				
					                                    bool  valuesCrossed  =  false ;  
			
		
	
		
			
				
					                                    for  ( uint64_t  i  =  0 ;  i  <  lowerX - > size ( ) ;  + + i )  {  
			
		
	
		
			
				
					                                        if  ( ( * upperX ) [ i ]  <  ( * lowerX ) [ i ] )  {  
			
		
	
		
			
				
					                                            valuesCrossed  =  true ;  
			
		
	
		
			
				
					                                            break ;  
			
		
	
		
			
				
					                                        }  
			
		
	
		
			
				
					                                    }  
			
		
	
		
			
				
					                            / /  Lower  bound  iteration  ( only  if  needed )  
			
		
	
		
			
				
					                            if  ( cancelGuess  | |  intervalIterationNeeded  | |  currentVerificationIterations  >  upperBoundOnlyIterations )  {  
			
		
	
		
			
				
					                                singleIterationCallback ( lowerX ,  auxVector ,  overallIterations ) ;  
			
		
	
		
			
				
					                                / /  At  this  point ,  auxVector  contains  the  old  values  for  the  lower  bound  whereas  lowerX  contains  the  new  ones .  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                                    if  ( cancelGuess  | |  valuesCrossed )  {  
			
		
	
		
			
				
					                                        / /  A  new  guess  is  needed .  
			
		
	
		
			
				
					                                        iterationPrecision  =  oviinternal : : updateIterationPrecision ( env ,  * auxVector ,  * lowerX ,  relative ,  relevantValues ) ;  
			
		
	
		
			
				
					                                / /  Check  whether  the  upper  and  lower  bounds  have  crossed ,  i . e . ,  the  upper  bound  is  smaller  than  the  lower  bound .  
			
		
	
		
			
				
					                                bool  valuesCrossed  =  false ;  
			
		
	
		
			
				
					                                for  ( uint64_t  i  =  0 ;  i  <  lowerX - > size ( ) ;  + + i )  {  
			
		
	
		
			
				
					                                    if  ( ( * upperX ) [ i ]  <  ( * lowerX ) [ i ] )  {  
			
		
	
		
			
				
					                                        valuesCrossed  =  true ;  
			
		
	
		
			
				
					                                        break ;  
			
		
	
		
			
				
					                                    }  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                                if  ( cancelGuess  | |  valuesCrossed )  {  
			
		
	
		
			
				
					                                    / /  A  new  guess  is  needed .  
			
		
	
		
			
				
					                                    iterationPrecision  =  oviinternal : : updateIterationPrecision ( env ,  * auxVector ,  * lowerX ,  relative ,  relevantValues ) ;  
			
		
	
		
			
				
					                                    break ;  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                    }