@ -90,6 +90,13 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Set data for LRA objectives (if available)
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( ! lraObjectives . empty ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    lraMecDecomposition  =  LraMecDecomposition ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    lraMecDecomposition - > mecs  =  storm : : storage : : MaximalEndComponentDecomposition < ValueType > ( transitionMatrix ,  transitionMatrix . transpose ( true ) ,  totalReward0EStates ,  actionsWithoutRewardInUnboundedPhase ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    lraMecDecomposition - > auxMecValues . resize ( lraMecDecomposition - > mecs . size ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // initialize data for the results
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                checkHasBeenCalled  =  false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                objectiveResults . resize ( this - > objectives . size ( ) ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -98,21 +105,37 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                optimalChoices . resize ( transitionMatrix . getRowGroupCount ( ) ,  0 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            template  < class  SparseModelType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            void  StandardPcaaWeightVectorChecker < SparseModelType > : : check ( Environment  const &  env ,  std : : vector < ValueType >  const &  weightVector )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                checkHasBeenCalled  =  true ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_INFO ( " Invoked WeightVectorChecker with weights  "  < <  std : : endl  < <  " \t "  < <  storm : : utility : : vector : : toString ( storm : : utility : : vector : : convertNumericVector < double > ( weightVector ) ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Prepare and invoke weighted infinite horizon (long run average) phase
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : vector < ValueType >  weightedRewardVector ( transitionMatrix . getRowCount ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( auto  objIndex  :  objectivesWithNoUpperTimeBound )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( ! lraObjectives . empty ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    boost : : optional < std : : vector < ValueType > >  weightedStateRewardVector ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    for  ( auto  objIndex  :  lraObjectives )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        ValueType  weight  =  storm : : solver : : minimize ( this - > objectives [ objIndex ] . formula - > getOptimalityType ( ) )  ?  - weightVector [ objIndex ]  :  weightVector [ objIndex ] ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        storm : : utility : : vector : : addScaledVector ( weightedRewardVector ,  actionRewards [ objIndex ] ,  weight ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        if  ( ! stateRewards [ objIndex ] . empty ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            weightedStateRewardVector - > resize ( transitionMatrix . getRowGroupCount ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            storm : : utility : : vector : : addScaledVector ( weightedStateRewardVector . get ( ) ,  stateRewards [ objIndex ] ,  weight ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    infiniteHorizonWeightedPhase ( env ,  weightedRewardVector ,  weightedStateRewardVector ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Clear all values of the weighted reward vector
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    weightedRewardVector . assign ( weightedRewardVector . size ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Prepare and invoke weighted indefinite horizon (unbounded total reward) phase
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                auto  totalRewardObjectives  =  objectivesWithNoUpperTimeBound  &  ~ lraObjectives ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( auto  objIndex  :  totalRewardObjectives )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if  ( storm : : solver : : minimize ( this - > objectives [ objIndex ] . formula - > getOptimalityType ( ) ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        storm : : utility : : vector : : addScaledVector ( weightedRewardVector ,  actionRewards [ objIndex ] ,  - weightVector [ objIndex ] ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        storm : : utility : : vector : : addScaledVector ( weightedRewardVector ,  actionRewards [ objIndex ] ,  weightVector [ objIndex ] ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                unboundedWeightedPhase ( env ,  weightedRewardVector ,  weightVector ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                unboundedIndividualPhase ( env ,  weightVector ) ;  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -282,9 +305,32 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  result ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            template  < class  SparseModelType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            void  StandardPcaaWeightVectorChecker < SparseModelType > : : infiniteHorizonWeightedPhase ( Environment  const &  env ,  std : : vector < ValueType >  const &  weightedActionRewardVector ,  boost : : optional < std : : vector < ValueType > >  const &  weightedStateRewardVector )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Compute the optimal (weighted) lra value for each mec, keeping track of the optimal choices
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_ASSERT ( lraMecDecomposition ,  " Mec decomposition for lra computations not initialized. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : modelchecker : : helper : : SparseNondeterministicInfiniteHorizonHelper < ValueType >  helper  =  createNondetInfiniteHorizonHelper ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                helper . provideLongRunComponentDecomposition ( lraMecDecomposition - > mecs ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                helper . setOptimizationDirection ( storm : : solver : : OptimizationDirection : : Maximize ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                helper . setProduceScheduler ( true ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( uint64_t  mecIndex  =  0 ;  mecIndex  <  lraMecDecomposition - > mecs . size ( ) ;  + + mecIndex )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    auto  const &  mec  =  lraMecDecomposition - > mecs [ mecIndex ] ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    auto  actionValueGetter  =  [ & weightedActionRewardVector ]  ( uint64_t  const &  a )  {  return  weightedActionRewardVector [ a ] ;  } ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    typename  storm : : modelchecker : : helper : : SparseNondeterministicInfiniteHorizonHelper < ValueType > : : ValueGetter  stateValueGetter ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if  ( weightedStateRewardVector )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        stateValueGetter  =  [ & weightedStateRewardVector ]  ( uint64_t  const &  s )  {  return  weightedStateRewardVector . get ( ) [ s ] ;  } ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        stateValueGetter  =  [ ]  ( uint64_t  const & )  {  return  storm : : utility : : zero < ValueType > ( ) ;  } ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    lraMecDecomposition - > auxMecValues [ mecIndex ]  =  helper . computeLraForComponent ( env ,  stateValueGetter ,  actionValueGetter ,  mec ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Extract the produced optimal choices for the MECs
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                this - > optimalChoices  =  std : : move ( helper . getProducedOptimalChoices ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            template  < class  SparseModelType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            void  StandardPcaaWeightVectorChecker < SparseModelType > : : unboundedWeightedPhase ( Environment  const &  env ,  std : : vector < ValueType >  const &  weightedRewardVector ,  std : : vector < ValueType >  const &  weightVector )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( this - > objectivesWithNoUpperTimeBound . empty ( )  | |  ! storm : : utility : : vector : : hasNonZeroEntry ( weightedRewardVector ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( this - > objectivesWithNoUpperTimeBound . empty ( )  | |  ( this - > lraObjectives . empty ( )  & &  ! storm : : utility : : vector : : hasNonZeroEntry ( weightedRewardVector ) ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    this - > weightedResult  =  std : : vector < ValueType > ( transitionMatrix . getRowGroupCount ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Get an arbitrary scheduler that yields finite reward for all objectives
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    this - > optimalChoices  =  computeSchedulerFinitelyOften ( transitionMatrix ,  transitionMatrix . transpose ( true ) ,  ~ actionsWithoutRewardInUnboundedPhase ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -293,7 +339,30 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                updateEcQuotient ( weightedRewardVector ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Set up the choice values
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : utility : : vector : : selectVectorValues ( ecQuotient - > auxChoiceValues ,  ecQuotient - > ecqToOriginalChoiceMapping ,  weightedRewardVector ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( ! lraObjectives . empty ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // We also need to assign a value for each ecQuotientChoice that corresponds to "staying" in the eliminated EC. (at this point these choices should all have a value of zero).
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Since each of the eliminated ECs has to contain *at least* one LRA EC, we need to find the largest value among the contained LRA ECs
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    storm : : storage : : BitVector  foundEcqChoices ( ecQuotient - > matrix . getRowCount ( ) ,  false ) ;  // keeps track of choices we have already seen before
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    for  ( uint64_t  mecIndex  =  0 ;  mecIndex  <  lraMecDecomposition - > mecs . size ( ) ;  + + mecIndex )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        auto  const &  mec  =  lraMecDecomposition - > mecs [ mecIndex ] ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        auto  const &  mecValue  =  lraMecDecomposition - > auxMecValues [ mecIndex ] ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        uint64_t  ecqState  =  ecQuotient - > originalToEcqStateMapping [ mec . begin ( ) - > first ] ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        uint64_t  ecqChoice  =  ecQuotient - > ecqStayInEcChoices . getNextSetIndex ( ecQuotient - > matrix . getRowGroupIndices ( ) [ ecqState ] ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        STORM_LOG_ASSERT ( ecqChoice  <  ecQuotient - > matrix . getRowGroupIndices ( ) [ ecqState  +  1 ] ,  " Unable to find choice that represents staying inside the (eliminated) ec. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        auto &  ecqChoiceValue  =  ecQuotient - > auxChoiceValues [ ecqChoice ] ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        if  ( foundEcqChoices . get ( ecqChoice ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            ecqChoiceValue  =  std : : max ( ecqChoiceValue ,  mecValue ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            STORM_LOG_ASSERT ( storm : : utility : : isZero ( ecqChoiceValue ) ,  " Expected a total reward of zero for choices that represent staying in an EC for ever. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            ecqChoiceValue  =  mecValue ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            foundEcqChoices . set ( ecqChoice ,  true ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // TODO: Continue to integrate LRA here (solver bounds need to be set correctly)
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : solver : : GeneralMinMaxLinearEquationSolverFactory < ValueType >  solverFactory ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : unique_ptr < storm : : solver : : MinMaxLinearEquationSolver < ValueType > >  solver  =  solverFactory . create ( env ,  ecQuotient - > matrix ) ;  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -420,20 +489,32 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            template  < class  SparseModelType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            void  StandardPcaaWeightVectorChecker < SparseModelType > : : updateEcQuotient ( std : : vector < ValueType >  const &  weightedRewardVector )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Check whether we need to update the currently cached ecElimResult
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : storage : : BitVector  newReward0Choices  =  storm : : utility : : vector : : filterZero ( weightedRewardVector ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : storage : : BitVector  newTotalReward0Choices  =  storm : : utility : : vector : : filterZero ( weightedRewardVector ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : storage : : BitVector  zeroLraRewardChoices ( weightedRewardVector . size ( ) ,  true ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( lraMecDecomposition )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    for  ( uint64_t  mecIndex  =  0 ;  mecIndex  <  lraMecDecomposition - > mecs . size ( ) ;  + + mecIndex )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        if  ( ! storm : : utility : : isZero ( lraMecDecomposition - > auxMecValues [ mecIndex ] ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            // The mec has a non-zero value, so flag all its choices as non-zero
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            auto  const &  mec  =  lraMecDecomposition - > mecs [ mecIndex ] ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            for  ( auto  const &  stateChoices  :  mec )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                for  ( auto  const &  choice  :  stateChoices . second )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                    zeroLraRewardChoices . set ( choice ,  false ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : storage : : BitVector  newReward0Choices  =  newTotalReward0Choices  &  zeroLraRewardChoices ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( ! ecQuotient  | |  ecQuotient - > origReward0Choices  ! =  newReward0Choices )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                     
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // It is sufficient to consider the states from which a transition with non-zero reward is reachable. (The remaining states always have reward zero).
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    storm : : storage : : BitVector  nonZeroRewardStates ( transitionMatrix . getRowGroupCount ( ) ,  false ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    for  ( uint_fast64_t  state  =  0 ;  state  <  transitionMatrix . getRowGroupCount ( ) ;  + + state ) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        if  ( newReward0Choices . getNextUnsetIndex ( transitionMatrix . getRowGroupIndices ( ) [ state ] )  <  transitionMatrix . getRowGroupIndices ( ) [ state + 1 ] )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            nonZeroRewardStates . set ( state ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    auto  nonZeroRewardStates  =  transitionMatrix . getRowGroupFilter ( newReward0Choices ,  true ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    nonZeroRewardStates . complement ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    storm : : storage : : BitVector  subsystemStates  =  storm : : utility : : graph : : performProbGreater0E ( transitionMatrix . transpose ( true ) ,  storm : : storage : : BitVector ( transitionMatrix . getRowGroupCount ( ) ,  true ) ,  nonZeroRewardStates ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Remove neutral end components, i.e., ECs in which no reward is earned.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    auto  ecElimResult  =  storm : : transformer : : EndComponentEliminator < ValueType > : : transform ( transitionMatrix ,  subsystemStates ,  ecChoicesHint  &  newReward0Choices ,  reward0EStates ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Remove neutral end components, i.e., ECs in which no total reward is earned.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Note that such ECs contain one (or maybe more) LRA ECs.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    auto  ecElimResult  =  storm : : transformer : : EndComponentEliminator < ValueType > : : transform ( transitionMatrix ,  subsystemStates ,  ecChoicesHint  &  newTotalReward0Choices ,  totalReward0EStates ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                     
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    storm : : storage : : BitVector  rowsWithSumLessOne ( ecElimResult . matrix . getRowCount ( ) ,  false ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    for  ( uint64_t  row  =  0 ;  row  <  rowsWithSumLessOne . size ( ) ;  + + row )  {  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -453,11 +534,10 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    ecQuotient - > matrix  =  std : : move ( ecElimResult . matrix ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    ecQuotient - > ecqToOriginalChoiceMapping  =  std : : move ( ecElimResult . newToOldRowMapping ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    ecQuotient - > originalToEcqStateMapping  =  std : : move ( ecElimResult . oldToNewStateMapping ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    ecQuotient - > ecqStayInEcChoices  =  std : : move ( ecElimResult . sinkRows ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    ecQuotient - > origReward0Choices  =  std : : move ( newReward0Choices ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    ecQuotient - > rowsWithSumLessOne  =  std : : move ( rowsWithSumLessOne ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    ecQuotient - > auxStateValues . reserve ( transitionMatrix . getRowGroupCount ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    ecQuotient - > auxStateValues . resize ( ecQuotient - > matrix . getRowGroupCount ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    ecQuotient - > auxChoiceValues . reserve ( transitionMatrix . getRowCount ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    ecQuotient - > auxChoiceValues . resize ( ecQuotient - > matrix . getRowCount ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }