@ -82,6 +82,105 @@ namespace storm { 
			
		
	
		
			
				
					                return  result ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            template < typename  ValueType >  
			
		
	
		
			
				
					            std : : vector < ValueType >  analyzeTrivialEpochModel ( OptimizationDirection  dir ,  typename  storm : : modelchecker : : multiobjective : : MultiDimensionalRewardUnfolding < ValueType ,  true > : : EpochModel &  epochModel )  {  
			
		
	
		
			
				
					                // Assert that the epoch model is indeed trivial
  
			
		
	
		
			
				
					                assert ( epochModel . epochMatrix . getEntryCount ( )  = =  0 ) ;  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                std : : vector < ValueType >  epochResult ;  
			
		
	
		
			
				
					                epochResult . reserve ( epochModel . epochInStates . getNumberOfSetBits ( ) ) ;  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                auto  stepSolutionIt  =  epochModel . stepSolutions . begin ( ) ;  
			
		
	
		
			
				
					                auto  stepChoiceIt  =  epochModel . stepChoices . begin ( ) ;  
			
		
	
		
			
				
					                for  ( auto  const &  state  :  epochModel . epochInStates )  {  
			
		
	
		
			
				
					                    // Obtain the best choice for this state
  
			
		
	
		
			
				
					                    ValueType  bestValue ;  
			
		
	
		
			
				
					                    uint64_t  lastChoice  =  epochModel . epochMatrix . getRowGroupIndices ( ) [ state  +  1 ] ;  
			
		
	
		
			
				
					                    bool  isFirstChoice  =  true ;  
			
		
	
		
			
				
					                    for  ( uint64_t  choice  =  epochModel . epochMatrix . getRowGroupIndices ( ) [ state ] ;  choice  <  lastChoice ;  + + choice )  {  
			
		
	
		
			
				
					                        while  ( * stepChoiceIt  <  choice )  {  
			
		
	
		
			
				
					                            + + stepChoiceIt ;  
			
		
	
		
			
				
					                            + + stepSolutionIt ;  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                         
			
		
	
		
			
				
					                        ValueType  choiceValue  =  storm : : utility : : zero < ValueType > ( ) ;  
			
		
	
		
			
				
					                        if  ( epochModel . objectiveRewardFilter . front ( ) . get ( choice ) )  {  
			
		
	
		
			
				
					                            choiceValue  + =  epochModel . objectiveRewards . front ( ) [ choice ] ;  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                        if  ( * stepChoiceIt  = =  choice )  {  
			
		
	
		
			
				
					                            choiceValue  + =  * stepSolutionIt ;  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                         
			
		
	
		
			
				
					                        if  ( isFirstChoice )  {  
			
		
	
		
			
				
					                            bestValue  =  std : : move ( choiceValue ) ;  
			
		
	
		
			
				
					                            isFirstChoice  =  false ;  
			
		
	
		
			
				
					                        }  else  {  
			
		
	
		
			
				
					                            if  ( storm : : solver : : minimize ( dir ) )  {  
			
		
	
		
			
				
					                                if  ( choiceValue  <  bestValue )  {  
			
		
	
		
			
				
					                                    bestValue  =  std : : move ( choiceValue ) ;  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                            }  else  {  
			
		
	
		
			
				
					                                if  ( choiceValue  >  bestValue )  {  
			
		
	
		
			
				
					                                    bestValue  =  std : : move ( choiceValue ) ;  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    // Insert the solution w.r.t. this choice
  
			
		
	
		
			
				
					                    epochResult . push_back ( std : : move ( bestValue ) ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                return  epochResult ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            template < typename  ValueType >  
			
		
	
		
			
				
					            std : : vector < ValueType >  analyzeNonTrivialEpochModel ( OptimizationDirection  dir ,  typename  storm : : modelchecker : : multiobjective : : MultiDimensionalRewardUnfolding < ValueType ,  true > : : EpochModel &  epochModel ,  std : : vector < ValueType > &  x ,  std : : vector < ValueType > &  b ,  std : : unique_ptr < storm : : solver : : MinMaxLinearEquationSolver < ValueType > > &  minMaxSolver ,  storm : : solver : : MinMaxLinearEquationSolverFactory < ValueType >  const &  minMaxLinearEquationSolverFactory ,  ValueType  const &  precision ,  SolutionType  const &  type )  {  
			
		
	
		
			
				
					  
			
		
	
		
			
				
					                // Update some data for the case that the Matrix has changed
  
			
		
	
		
			
				
					                if  ( epochModel . epochMatrixChanged )  {  
			
		
	
		
			
				
					                    x . assign ( epochModel . epochMatrix . getRowGroupCount ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                    minMaxSolver  =  minMaxLinearEquationSolverFactory . create ( epochModel . epochMatrix ) ;  
			
		
	
		
			
				
					                    minMaxSolver - > setHasUniqueSolution ( ) ;  
			
		
	
		
			
				
					                    minMaxSolver - > setPrecision ( precision ) ;  
			
		
	
		
			
				
					                    minMaxSolver - > setOptimizationDirection ( dir ) ;  
			
		
	
		
			
				
					                    minMaxSolver - > setCachingEnabled ( true ) ;  
			
		
	
		
			
				
					                    minMaxSolver - > setTrackScheduler ( true ) ;  
			
		
	
		
			
				
					                    auto  req  =  minMaxSolver - > getRequirements ( dir ) ;  
			
		
	
		
			
				
					                    minMaxSolver - > setLowerBound ( storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                    req . clearLowerBounds ( ) ;  
			
		
	
		
			
				
					                    if  ( type  = =  SolutionType : : UntilProbabilities )  {  
			
		
	
		
			
				
					                        minMaxSolver - > setUpperBound ( storm : : utility : : one < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                        req . clearUpperBounds ( ) ;  
			
		
	
		
			
				
					                    }  else  if  ( type  = =  SolutionType : : ExpectedRewards )  {  
			
		
	
		
			
				
					                        // TODO
  
			
		
	
		
			
				
					                        STORM_LOG_WARN_COND ( ! req . requiresUpperBounds ( ) ,  " Upper bounds for expected reward are not specified. " ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    STORM_LOG_THROW ( req . empty ( ) ,  storm : : exceptions : : UncheckedRequirementException ,  " At least one requirement was not checked. " ) ;  
			
		
	
		
			
				
					                    minMaxSolver - > setRequirementsChecked ( ) ;  
			
		
	
		
			
				
					                }  else  {  
			
		
	
		
			
				
					                    auto  choicesTmp  =  minMaxSolver - > getSchedulerChoices ( ) ;  
			
		
	
		
			
				
					                    minMaxSolver - > setInitialScheduler ( std : : move ( choicesTmp ) ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                // Prepare the right hand side of the equation system
  
			
		
	
		
			
				
					                b . assign ( epochModel . epochMatrix . getRowCount ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                std : : vector < ValueType >  const &  objectiveValues  =  epochModel . objectiveRewards . front ( ) ;  
			
		
	
		
			
				
					                for  ( auto  const &  choice  :  epochModel . objectiveRewardFilter . front ( ) )  {  
			
		
	
		
			
				
					                    b [ choice ]  =  objectiveValues [ choice ] ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                auto  stepSolutionIt  =  epochModel . stepSolutions . begin ( ) ;  
			
		
	
		
			
				
					                for  ( auto  const &  choice  :  epochModel . stepChoices )  {  
			
		
	
		
			
				
					                    b [ choice ]  + =  * stepSolutionIt ;  
			
		
	
		
			
				
					                    + + stepSolutionIt ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                assert ( stepSolutionIt  = =  epochModel . stepSolutions . end ( ) ) ;  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                // Solve the minMax equation system
  
			
		
	
		
			
				
					                minMaxSolver - > solveEquations ( x ,  b ) ;  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                return  storm : : utility : : vector : : filterVector ( x ,  epochModel . epochInStates ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            template < typename  ValueType >  
			
		
	
		
			
				
					            std : : map < storm : : storage : : sparse : : state_type ,  ValueType >  SparseMdpPrctlHelper < ValueType > : : computeRewardBoundedValues ( SolutionType  const &  type ,  OptimizationDirection  dir ,  storm : : modelchecker : : multiobjective : : MultiDimensionalRewardUnfolding < ValueType ,  true > &  rewardUnfolding ,  storm : : storage : : BitVector  const &  initialStates ,  storm : : solver : : MinMaxLinearEquationSolverFactory < ValueType >  const &  minMaxLinearEquationSolverFactory )  {  
			
		
	
		
			
				
					                storm : : utility : : Stopwatch  swAll ( true ) ,  swBuild ,  swCheck ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -92,14 +191,8 @@ namespace storm { 
			
		
	
		
			
				
					                std : : vector < ValueType >  x ,  b ;  
			
		
	
		
			
				
					                std : : unique_ptr < storm : : solver : : MinMaxLinearEquationSolver < ValueType > >  minMaxSolver ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                ValueType  precision  =  storm : : utility : : convertNumber < ValueType > ( storm : : settings : : getModule < storm : : settings : : modules : : GeneralSettings > ( ) . getPrecision ( ) ) ;  
			
		
	
		
			
				
					                uint64_t  epochCount  =  0 ;  
			
		
	
		
			
				
					                for  ( uint64_t  dim  =  0 ;  dim  <  rewardUnfolding . getEpochManager ( ) . getDimensionCount ( ) ;  + + dim )  {  
			
		
	
		
			
				
					                    epochCount  + =  rewardUnfolding . getEpochManager ( ) . getDimensionOfEpoch ( initEpoch ,  dim )  +  1 ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                if  ( storm : : settings : : getModule < storm : : settings : : modules : : GeneralSettings > ( ) . isSoundSet ( ) )  {  
			
		
	
		
			
				
					                    precision  =  precision  /  storm : : utility : : convertNumber < ValueType > ( epochCount ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                ValueType  precision  =  rewardUnfolding . getRequiredEpochModelPrecision ( initEpoch ,  storm : : utility : : convertNumber < ValueType > ( storm : : settings : : getModule < storm : : settings : : modules : : GeneralSettings > ( ) . getPrecision ( ) ) ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                storm : : utility : : ProgressMeasurement  progress ( " epochs " ) ;  
			
		
	
		
			
				
					                progress . setMaxCount ( epochOrder . size ( ) ) ;  
			
		
	
		
			
				
					                progress . startNewMeasurement ( 0 ) ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -110,95 +203,9 @@ namespace storm { 
			
		
	
		
			
				
					                    swBuild . stop ( ) ;  swCheck . start ( ) ;  
			
		
	
		
			
				
					                    // If the epoch matrix is empty we do not need to solve a linear equation system
  
			
		
	
		
			
				
					                    if  ( epochModel . epochMatrix . getEntryCount ( )  = =  0 )  {  
			
		
	
		
			
				
					                        std : : vector < ValueType >  epochResult ;  
			
		
	
		
			
				
					                        epochResult . reserve ( epochModel . epochInStates . getNumberOfSetBits ( ) ) ;  
			
		
	
		
			
				
					                         
			
		
	
		
			
				
					                        auto  stepSolutionIt  =  epochModel . stepSolutions . begin ( ) ;  
			
		
	
		
			
				
					                        auto  stepChoiceIt  =  epochModel . stepChoices . begin ( ) ;  
			
		
	
		
			
				
					                        for  ( auto  const &  state  :  epochModel . epochInStates )  {  
			
		
	
		
			
				
					                            // Obtain the best choice for this state
  
			
		
	
		
			
				
					                            ValueType  bestValue ;  
			
		
	
		
			
				
					                            uint64_t  lastChoice  =  epochModel . epochMatrix . getRowGroupIndices ( ) [ state  +  1 ] ;  
			
		
	
		
			
				
					                            bool  isFirstChoice  =  true ;  
			
		
	
		
			
				
					                            for  ( uint64_t  choice  =  epochModel . epochMatrix . getRowGroupIndices ( ) [ state ] ;  choice  <  lastChoice ;  + + choice )  {  
			
		
	
		
			
				
					                                while  ( * stepChoiceIt  <  choice )  {  
			
		
	
		
			
				
					                                    + + stepChoiceIt ;  
			
		
	
		
			
				
					                                    + + stepSolutionIt ;  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                                 
			
		
	
		
			
				
					                                ValueType  choiceValue  =  storm : : utility : : zero < ValueType > ( ) ;  
			
		
	
		
			
				
					                                if  ( epochModel . objectiveRewardFilter . front ( ) . get ( choice ) )  {  
			
		
	
		
			
				
					                                    choiceValue  + =  epochModel . objectiveRewards . front ( ) [ choice ] ;  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                                if  ( * stepChoiceIt  = =  choice )  {  
			
		
	
		
			
				
					                                    choiceValue  + =  * stepSolutionIt ;  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                                 
			
		
	
		
			
				
					                                if  ( isFirstChoice )  {  
			
		
	
		
			
				
					                                    bestValue  =  std : : move ( choiceValue ) ;  
			
		
	
		
			
				
					                                    isFirstChoice  =  false ;  
			
		
	
		
			
				
					                                }  else  {  
			
		
	
		
			
				
					                                    if  ( storm : : solver : : minimize ( dir ) )  {  
			
		
	
		
			
				
					                                        if  ( choiceValue  <  bestValue )  {  
			
		
	
		
			
				
					                                            bestValue  =  std : : move ( choiceValue ) ;  
			
		
	
		
			
				
					                                        }  
			
		
	
		
			
				
					                                    }  else  {  
			
		
	
		
			
				
					                                        if  ( choiceValue  >  bestValue )  {  
			
		
	
		
			
				
					                                            bestValue  =  std : : move ( choiceValue ) ;  
			
		
	
		
			
				
					                                        }  
			
		
	
		
			
				
					                                    }  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                            // Insert the solution w.r.t. this choice
  
			
		
	
		
			
				
					                            epochResult . push_back ( std : : move ( bestValue ) ) ;  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                         
			
		
	
		
			
				
					                        rewardUnfolding . setSolutionForCurrentEpoch ( std : : move ( epochResult ) ) ;  
			
		
	
		
			
				
					                        rewardUnfolding . setSolutionForCurrentEpoch ( analyzeTrivialEpochModel < ValueType > ( dir ,  epochModel ) ) ;  
			
		
	
		
			
				
					                    }  else  {  
			
		
	
		
			
				
					                        // Update some data for the case that the Matrix has changed
  
			
		
	
		
			
				
					                        if  ( epochModel . epochMatrixChanged )  {  
			
		
	
		
			
				
					                            x . assign ( epochModel . epochMatrix . getRowGroupCount ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                            minMaxSolver  =  minMaxLinearEquationSolverFactory . create ( epochModel . epochMatrix ) ;  
			
		
	
		
			
				
					                            minMaxSolver - > setHasUniqueSolution ( ) ;  
			
		
	
		
			
				
					                            minMaxSolver - > setPrecision ( precision ) ;  
			
		
	
		
			
				
					                            minMaxSolver - > setOptimizationDirection ( dir ) ;  
			
		
	
		
			
				
					                            minMaxSolver - > setCachingEnabled ( true ) ;  
			
		
	
		
			
				
					                            minMaxSolver - > setTrackScheduler ( true ) ;  
			
		
	
		
			
				
					                            auto  req  =  minMaxSolver - > getRequirements ( dir ) ;  
			
		
	
		
			
				
					                            minMaxSolver - > setLowerBound ( storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                            req . clearLowerBounds ( ) ;  
			
		
	
		
			
				
					                            if  ( type  = =  SolutionType : : UntilProbabilities )  {  
			
		
	
		
			
				
					                                minMaxSolver - > setUpperBound ( storm : : utility : : one < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                                req . clearUpperBounds ( ) ;  
			
		
	
		
			
				
					                            }  else  if  ( type  = =  SolutionType : : ExpectedRewards )  {  
			
		
	
		
			
				
					                                // TODO
  
			
		
	
		
			
				
					                                STORM_LOG_WARN_COND ( ! req . requiresUpperBounds ( ) ,  " Upper bounds for expected reward are not specified. " ) ;  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                            STORM_LOG_THROW ( req . empty ( ) ,  storm : : exceptions : : UncheckedRequirementException ,  " At least one requirement was not checked. " ) ;  
			
		
	
		
			
				
					                            minMaxSolver - > setRequirementsChecked ( ) ;  
			
		
	
		
			
				
					                        }  else  {  
			
		
	
		
			
				
					                            auto  choicesTmp  =  minMaxSolver - > getSchedulerChoices ( ) ;  
			
		
	
		
			
				
					                            minMaxSolver - > setInitialScheduler ( std : : move ( choicesTmp ) ) ;  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                         
			
		
	
		
			
				
					                        // Prepare the right hand side of the equation system
  
			
		
	
		
			
				
					                        b . assign ( epochModel . epochMatrix . getRowCount ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                        std : : vector < ValueType >  const &  objectiveValues  =  epochModel . objectiveRewards . front ( ) ;  
			
		
	
		
			
				
					                        for  ( auto  const &  choice  :  epochModel . objectiveRewardFilter . front ( ) )  {  
			
		
	
		
			
				
					                            b [ choice ]  =  objectiveValues [ choice ] ;  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                        auto  stepSolutionIt  =  epochModel . stepSolutions . begin ( ) ;  
			
		
	
		
			
				
					                        for  ( auto  const &  choice  :  epochModel . stepChoices )  {  
			
		
	
		
			
				
					                            b [ choice ]  + =  * stepSolutionIt ;  
			
		
	
		
			
				
					                            + + stepSolutionIt ;  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                        assert ( stepSolutionIt  = =  epochModel . stepSolutions . end ( ) ) ;  
			
		
	
		
			
				
					                         
			
		
	
		
			
				
					                        // Solve the minMax equation system
  
			
		
	
		
			
				
					                        minMaxSolver - > solveEquations ( x ,  b ) ;  
			
		
	
		
			
				
					                         
			
		
	
		
			
				
					                        // Plug in the result into the reward unfolding
  
			
		
	
		
			
				
					                        rewardUnfolding . setSolutionForCurrentEpoch ( storm : : utility : : vector : : filterVector ( x ,  epochModel . epochInStates ) ) ;  
			
		
	
		
			
				
					                        rewardUnfolding . setSolutionForCurrentEpoch ( analyzeNonTrivialEpochModel < ValueType > ( dir ,  epochModel ,  x ,  b ,  minMaxSolver ,  minMaxLinearEquationSolverFactory ,  precision ,  type ) ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    swCheck . stop ( ) ;  
			
		
	
		
			
				
					                    + + numCheckedEpochs ;