@ -14,6 +14,8 @@ 
			
		
	
		
			
				
					# include  "storm/storage/BitVector.h" 
  
			
		
	
		
			
				
					# include  "storm/storage/MaximalEndComponentDecomposition.h" 
  
			
		
	
		
			
				
					# include  "storm/utility/vector.h" 
  
			
		
	
		
			
				
					# include  "storm/settings/SettingsManager.h" 
  
			
		
	
		
			
				
					# include  "storm/settings/modules/CoreSettings.h" 
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# include  "storm/logic/ProbabilityOperatorFormula.h" 
  
			
		
	
		
			
				
					# include  "storm/logic/BoundedUntilFormula.h" 
  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -185,9 +187,10 @@ namespace storm { 
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                template < typename  ModelType >  
			
		
	
		
			
				
					                std : : vector < std : : vector < typename  ModelType : : ValueType > >  QuantileHelper < ModelType > : : computeQuantile ( Environment  const &  env )  {  
			
		
	
		
			
				
					                std : : vector < std : : vector < typename  ModelType : : ValueType > >  QuantileHelper < ModelType > : : computeQuantile ( Environment  const &  env )  const  {  
			
		
	
		
			
				
					                    std : : vector < std : : vector < ValueType > >  result ;  
			
		
	
		
			
				
					                    Environment  envCpy  =  env ;  // It might be necessary to increase the precision during the computation
  
			
		
	
		
			
				
					                    numCheckedEpochs  =  0 ;  numPrecisionRefinements  =  0 ;  
			
		
	
		
			
				
					                    if  ( getOpenDimensions ( ) . getNumberOfSetBits ( )  = =  1 )  {  
			
		
	
		
			
				
					                        uint64_t  dimension  =  * getOpenDimensions ( ) . begin ( ) ;  
			
		
	
		
			
				
					                         
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -201,6 +204,7 @@ namespace storm { 
			
		
	
		
			
				
					                                    break ;  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                                increasePrecision ( envCpy ) ;  
			
		
	
		
			
				
					                                + + numPrecisionRefinements ;  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                        }  else  if  ( zeroSatisfiesFormula )  {  
			
		
	
		
			
				
					                            // thus also infSatisfiesFormula is true, i.e., all bound values satisfy the formula
  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -218,6 +222,10 @@ namespace storm { 
			
		
	
		
			
				
					                    }  else  {  
			
		
	
		
			
				
					                        STORM_LOG_THROW ( false ,  storm : : exceptions : : NotSupportedException ,  " The quantile formula considers  "  < <  getOpenDimensions ( ) . getNumberOfSetBits ( )  < <  "  open dimensions. Only one- or two-dimensional quantiles are supported. " ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    if  ( storm : : settings : : getModule < storm : : settings : : modules : : CoreSettings > ( ) . isShowStatisticsSet ( ) )  {  
			
		
	
		
			
				
					                        std : : cout  < <  " Number of checked epochs:  "  < <  numCheckedEpochs  < <  std : : endl ;  
			
		
	
		
			
				
					                        std : : cout  < <  " Number of required precision refinements:  "  < <  numPrecisionRefinements  < <  std : : endl ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    return  result ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -253,11 +261,10 @@ namespace storm { 
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                template < typename  ModelType >  
			
		
	
		
			
				
					                std : : vector < std : : vector < typename  ModelType : : ValueType > >  QuantileHelper < ModelType > : : computeTwoDimensionalQuantile ( Environment &  env )  {  
			
		
	
		
			
				
					                std : : vector < std : : vector < typename  ModelType : : ValueType > >  QuantileHelper < ModelType > : : computeTwoDimensionalQuantile ( Environment &  env )  const  {  
			
		
	
		
			
				
					                    std : : vector < std : : vector < ValueType > >  result ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                    auto  const &  probOpFormula  =  quantileFormula . getSubformula ( ) . asProbabilityOperatorFormula ( ) ;  
			
		
	
		
			
				
					                    storm : : logic : : ComparisonType  probabilityBound  =  probOpFormula . getBound ( ) . comparisonType ;  
			
		
	
		
			
				
					                    auto  const &  boundedUntilFormula  =  probOpFormula . getSubformula ( ) . asBoundedUntilFormula ( ) ;  
			
		
	
		
			
				
					                    std : : vector < storm : : storage : : BitVector >  dimensionsAsBitVector ;  
			
		
	
		
			
				
					                    std : : vector < uint64_t >  dimensions ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -282,15 +289,12 @@ namespace storm { 
			
		
	
		
			
				
					                                for  ( uint64_t  i  =  0 ;  i  <  2 ;  + + i )  {  
			
		
	
		
			
				
					                                    // find out whether the bounds B_i = 0 and B_1-i = infinity satisfy the formula
  
			
		
	
		
			
				
					                                    bool  zeroInfSatisfiesFormula  =  checkLimitValue ( env ,  dimensionsAsBitVector [ 1 - i ] ) ;  
			
		
	
		
			
				
					                                    std : : cout  < <  " Formula sat is  "  < <  zeroInfSatisfiesFormula  < <  "  and lower bound is  "  < <  storm : : logic : : isLowerBound ( probabilityBound )  < <  std : : endl ;  
			
		
	
		
			
				
					                                    if  ( zeroInfSatisfiesFormula  = =  storm : : solver : : minimize ( optimizationDirections [ 0 ] ) )  {  
			
		
	
		
			
				
					                                        // There is bound value b such that the point B_i=0 and B_1-i = b is part of the result
  
			
		
	
		
			
				
					                                        singleQuantileValues . emplace_back ( 0 ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                                    }  else  {  
			
		
	
		
			
				
					                                        // Compute quantile where 1-i is set to infinity
  
			
		
	
		
			
				
					                                        std : : cout  < <  " Computing quantile for single dimension  "  < <  dimensions [ i ]  < <  std : : endl ;  
			
		
	
		
			
				
					                                        singleQuantileValues . push_back ( computeQuantileForDimension ( env ,  dimensions [ i ] ) . get ( ) ) ;  
			
		
	
		
			
				
					                                        std : : cout  < <  " .. Result is  "  < <  singleQuantileValues . back ( ) . first  < <  std : : endl ;  
			
		
	
		
			
				
					                                        if  ( ! storm : : solver : : minimize ( optimizationDirections [ i ] ) )  {  
			
		
	
		
			
				
					                                            // When maximizing bounds, the computed single dimensional quantile value is sat for all values of the other bound.
  
			
		
	
		
			
				
					                                            // Increase the computed value so that there is at least one unsat assignment of bounds with B[i] = singleQuantileValues[i]
  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -302,10 +306,10 @@ namespace storm { 
			
		
	
		
			
				
					                                        - - singleQuantileValues [ i ] . first ;  
			
		
	
		
			
				
					                                    }  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                                std : : cout  < <  " Found starting point. Beginning 2D exploration "  < <  std : : endl ;  
			
		
	
		
			
				
					                                std : : vector < int64_t >  currentEpochValues  =  { ( int64_t )  singleQuantileValues [ 0 ] . first ,  ( int64_t )  singleQuantileValues [ 1 ] . first } ;  // signed int is needed to allow lower bounds >-1 (aka >=0).
  
			
		
	
		
			
				
					                                while  ( ! exploreTwoDimensionalQuantile ( env ,  singleQuantileValues ,  currentEpochValues ,  result ) )  {  
			
		
	
		
			
				
					                                    increasePrecision ( env ) ;  
			
		
	
		
			
				
					                                    + + numPrecisionRefinements ;  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                            }  else  if  ( infInfProbSatisfiesFormula )  {  
			
		
	
		
			
				
					                                // then also zeroZeroProb satisfies the formula, i.e., all bound values satisfy the formula
  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -354,7 +358,6 @@ namespace storm { 
			
		
	
		
			
				
					                    std : : vector < ValueType >  x ,  b ;  
			
		
	
		
			
				
					                    std : : unique_ptr < storm : : solver : : MinMaxLinearEquationSolver < ValueType > >  minMaxSolver ;  
			
		
	
		
			
				
					                     
			
		
	
		
			
				
					                    std : : cout  < <  " Starting quantile exploration with: ( "  < <  currentEpochValues [ 0 ]  < <  " ,  "  < <  currentEpochValues [ 1 ]  < <  " ). "  < <  std : : endl ;  
			
		
	
		
			
				
					                    if  ( currentEpochValues [ 0 ]  <  0  & &  currentEpochValues [ 1 ]  <  0 )  {  
			
		
	
		
			
				
					                        // This case can only happen in these cases:
  
			
		
	
		
			
				
					                        assert ( lowerCostBounds [ 0 ] ) ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -379,11 +382,11 @@ namespace storm { 
			
		
	
		
			
				
					                            if  ( exploredEpochs . count ( epoch )  = =  0 )  {  
			
		
	
		
			
				
					                                auto &  epochModel  =  rewardUnfolding . setCurrentEpoch ( epoch ) ;  
			
		
	
		
			
				
					                                rewardUnfolding . setSolutionForCurrentEpoch ( epochModel . analyzeSingleObjective ( env ,  quantileFormula . getSubformula ( ) . asProbabilityOperatorFormula ( ) . getOptimalityType ( ) ,  x ,  b ,  minMaxSolver ,  lowerBound ,  upperBound ) ) ;  
			
		
	
		
			
				
					                                + + numCheckedEpochs ;  
			
		
	
		
			
				
					                                exploredEpochs . insert ( epoch ) ;  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                        ValueType  currValue  =  rewardUnfolding . getInitialStateResult ( currEpoch ) ;  
			
		
	
		
			
				
					                        std : : cout  < <  " Numeric result for epoch  "  < <  rewardUnfolding . getEpochManager ( ) . toString ( currEpoch )  < <  "  is  "  < <  currValue  < <  std : : endl ;  
			
		
	
		
			
				
					                        bool  propertySatisfied ;  
			
		
	
		
			
				
					                        if  ( env . solver ( ) . isForceSoundness ( ) )  {  
			
		
	
		
			
				
					                            auto  lowerUpperValue  =  getLowerUpperBound ( env ,  currValue ) ;  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -419,7 +422,6 @@ namespace storm { 
			
		
	
		
			
				
					                                convertedPoint . push_back ( storm : : utility : : convertNumber < ValueType > ( point [ i ] )  *  rewardUnfolding . getDimension ( dimensions [ i ] ) . scalingFactor ) ;  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                            if  ( ! convertedPoint . empty ( ) )  {  
			
		
	
		
			
				
					                                std : : cout  < <  " Found another result point: ( "  < <  convertedPoint [ 0 ]  < <  " ,  "  < <  convertedPoint [ 1 ]  < <  " ). "  < <  std : : endl ;  
			
		
	
		
			
				
					                                resultPoints . push_back ( std : : move ( convertedPoint ) ) ;  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                             
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -482,11 +484,11 @@ namespace storm { 
			
		
	
		
			
				
					                            if  ( exploredEpochs . count ( epoch )  = =  0 )  {  
			
		
	
		
			
				
					                                auto &  epochModel  =  rewardUnfolding . setCurrentEpoch ( epoch ) ;  
			
		
	
		
			
				
					                                rewardUnfolding . setSolutionForCurrentEpoch ( epochModel . analyzeSingleObjective ( env ,  quantileFormula . getSubformula ( ) . asProbabilityOperatorFormula ( ) . getOptimalityType ( ) ,  x ,  b ,  minMaxSolver ,  lowerBound ,  upperBound ) ) ;  
			
		
	
		
			
				
					                                + + numCheckedEpochs ;  
			
		
	
		
			
				
					                                exploredEpochs . insert ( epoch ) ;  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                        ValueType  currValue  =  rewardUnfolding . getInitialStateResult ( currEpoch ) ;  
			
		
	
		
			
				
					                        std : : cout  < <  " Numeric result for epoch  "  < <  rewardUnfolding . getEpochManager ( ) . toString ( currEpoch )  < <  "  is  "  < <  currValue  < <  std : : endl ;  
			
		
	
		
			
				
					                         
			
		
	
		
			
				
					                        bool  propertySatisfied ;  
			
		
	
		
			
				
					                        if  ( env . solver ( ) . isForceSoundness ( ) )  {  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -537,6 +539,7 @@ namespace storm { 
			
		
	
		
			
				
					                                return  lowerSat ;  
			
		
	
		
			
				
					                            }  else  {  
			
		
	
		
			
				
					                                increasePrecision ( env ) ;  
			
		
	
		
			
				
					                                + + numPrecisionRefinements ;  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                        }  else  {  
			
		
	
		
			
				
					                            return  probabilityBound . isSatisfied ( numericResult ) ;  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -585,6 +588,7 @@ namespace storm { 
			
		
	
		
			
				
					                    for  ( auto  const &  epoch  :  epochOrder )  {  
			
		
	
		
			
				
					                        auto &  epochModel  =  rewardUnfolding . setCurrentEpoch ( epoch ) ;  
			
		
	
		
			
				
					                        rewardUnfolding . setSolutionForCurrentEpoch ( epochModel . analyzeSingleObjective ( env ,  quantileFormula . getSubformula ( ) . asProbabilityOperatorFormula ( ) . getOptimalityType ( ) ,  x ,  b ,  minMaxSolver ,  lowerBound ,  upperBound ) ) ;  
			
		
	
		
			
				
					                        + + numCheckedEpochs ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                    ValueType  numericResult  =  rewardUnfolding . getInitialStateResult ( initEpoch ) ;