@ -82,6 +82,105 @@ namespace storm { 
		
	
		
			
				                return  result ;                 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 >             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 )  {             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 ;                 storm : : utility : : Stopwatch  swAll ( true ) ,  swBuild ,  swCheck ;  
		
	
	
		
			
				
					
					
					
						
							 
					
				 
				@ -92,14 +191,8 @@ namespace storm { 
		
	
		
			
				                std : : vector < ValueType >  x ,  b ;                 std : : vector < ValueType >  x ,  b ;  
		
	
		
			
				                std : : unique_ptr < storm : : solver : : MinMaxLinearEquationSolver < ValueType > >  minMaxSolver ;                 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 " ) ;                 storm : : utility : : ProgressMeasurement  progress ( " epochs " ) ;  
		
	
		
			
				                progress . setMaxCount ( epochOrder . size ( ) ) ;                 progress . setMaxCount ( epochOrder . size ( ) ) ;  
		
	
		
			
				                progress . startNewMeasurement ( 0 ) ;                 progress . startNewMeasurement ( 0 ) ;  
		
	
	
		
			
				
					
					
					
						
							 
					
				 
				@ -110,95 +203,9 @@ namespace storm { 
		
	
		
			
				                    swBuild . stop ( ) ;  swCheck . start ( ) ;                     swBuild . stop ( ) ;  swCheck . start ( ) ;  
		
	
		
			
				                    // If the epoch matrix is empty we do not need to solve a linear equation system
                     // If the epoch matrix is empty we do not need to solve a linear equation system
  
		
	
		
			
				                    if  ( epochModel . epochMatrix . getEntryCount ( )  = =  0 )  {                     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  {                     }  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 ( ) ;                     swCheck . stop ( ) ;  
		
	
		
			
				                    + + numCheckedEpochs ;                     + + numCheckedEpochs ;