@ -1,3 +1,4 @@ 
			
		
	
		
			
				
					# include  <utility/graph.h> 
  
			
		
	
		
			
				
					# include  "SparseSmgRpatlHelper.h" 
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# include  "storm/environment/Environment.h" 
  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -5,9 +6,8 @@ 
			
		
	
		
			
				
					# include  "storm/environment/solver/MinMaxSolverEnvironment.h" 
  
			
		
	
		
			
				
					# include  "storm/solver/MinMaxLinearEquationSolver.h" 
  
			
		
	
		
			
				
					# include  "storm/utility/vector.h" 
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# include  "storm/utility/graph.h" 
  
			
		
	
		
			
				
					# include  "storm/modelchecker/rpatl/helper/internal/GameViHelper.h" 
  
			
		
	
		
			
				
					# include  "storm/modelchecker/rpatl/helper/internal/BoundedGloballyGameViHelper.h" 
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					namespace  storm  {  
			
		
	
		
			
				
					    namespace  modelchecker  {  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -19,44 +19,56 @@ namespace storm { 
			
		
	
		
			
				
					                auto  solverEnv  =  env ;  
			
		
	
		
			
				
					                solverEnv . solver ( ) . minMax ( ) . setMethod ( storm : : solver : : MinMaxMethod : : ValueIteration ,  false ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                // Initialize the solution vector.
  
			
		
	
		
			
				
					                std : : vector < ValueType >  x  =  std : : vector < ValueType > ( transitionMatrix . getRowGroupCount ( )  -  psiStates . getNumberOfSetBits ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                // Relevant states are those states which are phiStates and not PsiStates.
  
			
		
	
		
			
				
					                storm : : storage : : BitVector  relevantStates  =  phiStates  &  ~ psiStates ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                // TODO: check if relevantStates should be used for the size of x
  
			
		
	
		
			
				
					                // Initialize the x vector and solution vector result.
  
			
		
	
		
			
				
					                //std::vector<ValueType> x = std::vector<ValueType>(transitionMatrix.getRowGroupCount() - psiStates.getNumberOfSetBits(), storm::utility::zero<ValueType>());
  
			
		
	
		
			
				
					                std : : vector < ValueType >  x  =  std : : vector < ValueType > ( relevantStates . getNumberOfSetBits ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                std : : vector < ValueType >  result  =  std : : vector < ValueType > ( transitionMatrix . getRowGroupCount ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                std : : vector < ValueType >  b  =  transitionMatrix . getConstrainedRowGroupSumVector ( relevantStates ,  psiStates ) ;  
			
		
	
		
			
				
					                std : : vector < ValueType >  constrainedChoiceValues  =  std : : vector < ValueType > ( b . size ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                std : : unique_ptr < storm : : storage : : Scheduler < ValueType > >  scheduler ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                STORM_LOG_DEBUG ( " statesOfCoalition:  "  < <  statesOfCoalition ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                storm : : storage : : BitVector  clippedStatesOfCoalition ( relevantStates . getNumberOfSetBits ( ) ) ;  
			
		
	
		
			
				
					                clippedStatesOfCoalition . setClippedStatesOfCoalition ( relevantStates ,  statesOfCoalition ) ;  
			
		
	
		
			
				
					                clippedStatesOfCoalition . complement ( ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                storm : : modelchecker : : helper : : internal : : GameViHelper < ValueType >  viHelper ( transitionMatrix ,  clippedStatesOfCoalition ) ;  
			
		
	
		
			
				
					                STORM_LOG_DEBUG ( " clippedStatesOfCoalition "  < <  clippedStatesOfCoalition ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                //clippedStatesOfCoalition.complement();
  
			
		
	
		
			
				
					                //STORM_LOG_DEBUG("clippedStatesOfCoalition" << clippedStatesOfCoalition);
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                if ( ! relevantStates . empty ( ) )  {  
			
		
	
		
			
				
					                    // Reduce the matrix to relevant states.
  
			
		
	
		
			
				
					                    storm : : storage : : SparseMatrix < ValueType >  submatrix  =  transitionMatrix . getSubmatrix ( true ,  relevantStates ,  relevantStates ,  false ) ;  
			
		
	
		
			
				
					                    // Update the GameViHelper.
  
			
		
	
		
			
				
					                    viHelper  =  storm : : modelchecker : : helper : : internal : : GameViHelper < ValueType > ( submatrix ,  clippedStatesOfCoalition ) ;  
			
		
	
		
			
				
					                    // Create GameViHelper for computations .
  
			
		
	
		
			
				
					                    storm : : modelchecker : : helper : : internal : : GameViHelper < ValueType >  viHelper  ( submatrix ,  clippedStatesOfCoalition ) ;  
			
		
	
		
			
				
					                    if  ( produceScheduler )  {  
			
		
	
		
			
				
					                        viHelper . setProduceScheduler ( true ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    // Perform value iteration.
  
			
		
	
		
			
				
					                    viHelper . performValueIteration ( env ,  x ,  b ,  goal . direction ( ) ) ;  
			
		
	
		
			
				
					                    if ( goal . isShieldingTask ( ) )  {  
			
		
	
		
			
				
					                        viHelper . getChoiceValues ( env ,  x ,  constrainedChoiceValues ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                // Fill up the result x with 0s and 1s for not relevant states.
  
			
		
	
		
			
				
					                viHelper . fillResultVector ( x ,  relevantStates ,  psiStates ) ;  
			
		
	
		
			
				
					                // Fill up the constrainedChoice Values to full size.
  
			
		
	
		
			
				
					                viHelper . fillChoiceValuesVector ( constrainedChoiceValues ,  relevantStates ,  transitionMatrix . getRowGroupIndices ( ) ) ;  
			
		
	
		
			
				
					                    // Fill up the constrainedChoice Values to full size.
  
			
		
	
		
			
				
					                    viHelper . fillChoiceValuesVector ( constrainedChoiceValues ,  relevantStates ,  transitionMatrix . getRowGroupIndices ( ) ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                std : : unique_ptr < storm : : storage : : Scheduler < ValueType > >  scheduler ;  
			
		
	
		
			
				
					                if  ( produceScheduler )  {  
			
		
	
		
			
				
					                    scheduler  =  std : : make_unique < storm : : storage : : Scheduler < ValueType > > ( expandScheduler ( viHelper . extractScheduler ( ) ,  psiStates ,  ~ phiStates ) ) ;  
			
		
	
		
			
				
					                    if  ( produceScheduler )  {  
			
		
	
		
			
				
					                        scheduler  =  std : : make_unique < storm : : storage : : Scheduler < ValueType > > ( expandScheduler ( viHelper . extractScheduler ( ) ,  psiStates ,  ~ phiStates ) ) ;   
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                return  SMGSparseModelCheckingHelperReturnType < ValueType > ( std : : move ( x ) ,  std : : move ( relevantStates ) ,  std : : move ( scheduler ) ,  std : : move ( constrainedChoiceValues ) ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                // Fill up the result vector with the values of x for the relevant states, with 1s for psi states (0 is default)
  
			
		
	
		
			
				
					                storm : : utility : : vector : : setVectorValues ( result ,  relevantStates ,  x ) ;  
			
		
	
		
			
				
					                storm : : utility : : vector : : setVectorValues ( result ,  psiStates ,  storm : : utility : : one < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                STORM_LOG_DEBUG ( result ) ;  
			
		
	
		
			
				
					                return  SMGSparseModelCheckingHelperReturnType < ValueType > ( std : : move ( result ) ,  std : : move ( relevantStates ) ,  std : : move ( scheduler ) ,  std : : move ( constrainedChoiceValues ) ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					            template < typename  ValueType >  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -85,6 +97,8 @@ namespace storm { 
			
		
	
		
			
				
					                // The psiStates are flipped, then the true U part is calculated, at the end the result is flipped again.
  
			
		
	
		
			
				
					                storm : : storage : : BitVector  notPsiStates  =  ~ psiStates ;  
			
		
	
		
			
				
					                statesOfCoalition . complement ( ) ;  
			
		
	
		
			
				
					                STORM_LOG_DEBUG ( statesOfCoalition ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                auto  result  =  computeUntilProbabilities ( env ,  std : : move ( goal ) ,  transitionMatrix ,  backwardTransitions ,  storm : : storage : : BitVector ( transitionMatrix . getRowGroupCount ( ) ,  true ) ,  notPsiStates ,  qualitative ,  statesOfCoalition ,  produceScheduler ,  hint ) ;  
			
		
	
		
			
				
					                for  ( auto &  element  :  result . values )  {  
			
		
	
		
			
				
					                    element  =  storm : : utility : : one < ValueType > ( )  -  element ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -92,27 +106,31 @@ namespace storm { 
			
		
	
		
			
				
					                for  ( auto &  element  :  result . choiceValues )  {  
			
		
	
		
			
				
					                    element  =  storm : : utility : : one < ValueType > ( )  -  element ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                STORM_LOG_DEBUG ( result . values ) ;  
			
		
	
		
			
				
					                return  result ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					            template < typename  ValueType >  
			
		
	
		
			
				
					            SMGSparseModelCheckingHelperReturnType < ValueType >  SparseSmgRpatlHelper < ValueType > : : computeNextProbabilities ( Environment  const &  env ,  storm : : solver : : SolveGoal < ValueType > & &  goal ,  storm : : storage : : SparseMatrix < ValueType >  const &  transitionMatrix ,  storm : : storage : : SparseMatrix < ValueType >  const &  backwardTransitions ,  storm : : storage : : BitVector  const &  psiStates ,  bool  qualitative ,  storm : : storage : : BitVector  statesOfCoalition ,  bool  produceScheduler ,  ModelCheckerHint  const &  hint )  {  
			
		
	
		
			
				
					                // Create vector x for  result, bitvector allStates with a true for each state and a vector b for the probability for each state to get to a psi state, choiceValues is to store choices for shielding.
  
			
		
	
		
			
				
					                std : : vector < ValueType >  x =  std : : vector < ValueType > ( transitionMatrix . getRowGroupCount ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                // Create vector result, bitvector allStates with a true for each state and a vector b for the probability for each state to get to a psi state, choiceValues is to store choices for shielding.
  
			
		
	
		
			
				
					                std : : vector < ValueType >  result =  std : : vector < ValueType > ( transitionMatrix . getRowGroupCount ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                storm : : storage : : BitVector  allStates  =  storm : : storage : : BitVector ( transitionMatrix . getRowGroupCount ( ) ,  true ) ;  
			
		
	
		
			
				
					                std : : vector < ValueType >  b  =  transitionMatrix . getConstrainedRowGroupSumVector ( allStates ,  psiStates ) ;  
			
		
	
		
			
				
					                std : : vector < ValueType >  choiceValues  =  std : : vector < ValueType > ( transitionMatrix . getRowCount ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                statesOfCoalition . complement ( ) ;  
			
		
	
		
			
				
					                STORM_LOG_DEBUG ( statesOfCoalition ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                if  ( produceScheduler )  {  
			
		
	
		
			
				
					                    STORM_LOG_WARN ( " Next formula does not expect that produceScheduler is set to true. " ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                // Create a multiplier for reduction.
  
			
		
	
		
			
				
					                auto  multiplier  =  storm : : solver : : MultiplierFactory < ValueType > ( ) . create ( env ,  transitionMatrix ) ;  
			
		
	
		
			
				
					                multiplier - > reduce ( env ,  goal . direction ( ) ,  b ,  transitionMatrix . getRowGroupIndices ( ) ,  x ,  & statesOfCoalition ) ;  
			
		
	
		
			
				
					                multiplier - > reduce ( env ,  goal . direction ( ) ,  b ,  transitionMatrix . getRowGroupIndices ( ) ,  result ,  & statesOfCoalition ) ;  
			
		
	
		
			
				
					                if  ( goal . isShieldingTask ( ) )  {  
			
		
	
		
			
				
					                    choiceValues  =  b ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                return  SMGSparseModelCheckingHelperReturnType < ValueType > ( std : : move ( x ) ,  std : : move ( allStates ) ,  nullptr ,  std : : move ( choiceValues ) ) ;  
			
		
	
		
			
				
					                STORM_LOG_DEBUG ( result ) ;  
			
		
	
		
			
				
					                return  SMGSparseModelCheckingHelperReturnType < ValueType > ( std : : move ( result ) ,  std : : move ( allStates ) ,  nullptr ,  std : : move ( choiceValues ) ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					            template < typename  ValueType >  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -123,35 +141,148 @@ namespace storm { 
			
		
	
		
			
				
					                // Relevant states are safe states - the psiStates.
  
			
		
	
		
			
				
					                storm : : storage : : BitVector  relevantStates  =  psiStates ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                // Initialize the solution vector .
  
			
		
	
		
			
				
					                // Initializations .
  
			
		
	
		
			
				
					                std : : vector < ValueType >  x  =  std : : vector < ValueType > ( relevantStates . getNumberOfSetBits ( ) ,  storm : : utility : : one < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                std : : vector < ValueType >  b  =  std : : vector < ValueType > ( transitionMatrix . getConstrainedRowGroupSumVector ( relevantStates ,  psiStates ) . size ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                std : : vector < ValueType >  result  =  std : : vector < ValueType > ( transitionMatrix . getRowGroupCount ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                std : : vector < ValueType >  constrainedChoiceValues  =  std : : vector < ValueType > ( transitionMatrix . getConstrainedRowGroupSumVector ( relevantStates ,  psiStates ) . size ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                std : : unique_ptr < storm : : storage : : Scheduler < ValueType > >  scheduler ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                storm : : storage : : BitVector  clippedStatesOfCoalition ( relevantStates . getNumberOfSetBits ( ) ) ;  
			
		
	
		
			
				
					                clippedStatesOfCoalition . setClippedStatesOfCoalition ( relevantStates ,  statesOfCoalition ) ;  
			
		
	
		
			
				
					                clippedStatesOfCoalition . complement ( ) ;  
			
		
	
		
			
				
					                //clippedStatesOfCoalition.complement();
  
			
		
	
		
			
				
					                STORM_LOG_DEBUG ( clippedStatesOfCoalition ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                // Use the bounded globally game vi helper.
  
			
		
	
		
			
				
					                storm : : modelchecker : : helper : : internal : : GameViHelper < ValueType >  viHelper ( transitionMatrix ,  clippedStatesOfCoalition ) ;  
			
		
	
		
			
				
					                if ( ! relevantStates . empty ( )  & &  upperBound  >  0 )  {  
			
		
	
		
			
				
					                    // Reduce the matrix to relevant states.
  
			
		
	
		
			
				
					                    storm : : storage : : SparseMatrix < ValueType >  submatrix  =  transitionMatrix . getSubmatrix ( true ,  relevantStates ,  relevantStates ,  false ) ;  
			
		
	
		
			
				
					                    // Update the BoundedGloballyViHelper .
  
			
		
	
		
			
				
					                    // Create GameViHelper for computations .
  
			
		
	
		
			
				
					                    storm : : modelchecker : : helper : : internal : : GameViHelper < ValueType >  viHelper ( submatrix ,  clippedStatesOfCoalition ) ;  
			
		
	
		
			
				
					                    if  ( produceScheduler )  {  
			
		
	
		
			
				
					                        viHelper . setProduceScheduler ( true ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    viHelper . performValueIterationUpperBound ( env ,  x ,  goal . direction ( ) ,  upperBound ,  constrainedChoiceValues ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                    viHelper . performValueIterationUpperBound ( env ,  x ,  b ,  goal . direction ( ) ,  upperBound ,  constrainedChoiceValues ) ;  
			
		
	
		
			
				
					                    viHelper . fillChoiceValuesVector ( constrainedChoiceValues ,  relevantStates ,  transitionMatrix . getRowGroupIndices ( ) ) ;  
			
		
	
		
			
				
					                    if  ( produceScheduler )  {  
			
		
	
		
			
				
					                        scheduler  =  std : : make_unique < storm : : storage : : Scheduler < ValueType > > ( expandScheduler ( viHelper . extractScheduler ( ) ,  relevantStates ,  ~ relevantStates ) ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                viHelper . fillResultVector ( x ,  relevantStates ) ;  
			
		
	
		
			
				
					                viHelper . fillChoiceValuesVector ( constrainedChoiceValues ,  relevantStates ,  transitionMatrix . getRowGroupIndices ( ) ) ;  
			
		
	
		
			
				
					                // Fill up the result vector with the values of x for the relevant states (0 is default)
  
			
		
	
		
			
				
					                storm : : utility : : vector : : setVectorValues ( result ,  relevantStates ,  x ) ;  
			
		
	
		
			
				
					                STORM_LOG_DEBUG ( result ) ;  
			
		
	
		
			
				
					                return  SMGSparseModelCheckingHelperReturnType < ValueType > ( std : : move ( result ) ,  std : : move ( relevantStates ) ,  std : : move ( scheduler ) ,  std : : move ( constrainedChoiceValues ) ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					            template < typename  ValueType >  
			
		
	
		
			
				
					            SMGSparseModelCheckingHelperReturnType < ValueType >  SparseSmgRpatlHelper < ValueType > : : computeBoundedUntilProbabilities ( Environment  const &  env ,  storm : : solver : : SolveGoal < ValueType > & &  goal ,  storm : : storage : : SparseMatrix < ValueType >  const &  transitionMatrix ,  storm : : storage : : SparseMatrix < ValueType >  const &  backwardTransitions ,  storm : : storage : : BitVector  const &  phiStates ,  storm : : storage : : BitVector  const &  psiStates ,  bool  qualitative ,  storm : : storage : : BitVector  statesOfCoalition ,  bool  produceScheduler ,  ModelCheckerHint  const &  hint , uint64_t  lowerBound ,  uint64_t  upperBound )  {  
			
		
	
		
			
				
					                STORM_LOG_DEBUG ( " lowerBound =  "  < <  lowerBound ) ;  
			
		
	
		
			
				
					                STORM_LOG_DEBUG ( " upperBound =  "  < <  upperBound ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                auto  solverEnv  =  env ;  
			
		
	
		
			
				
					                solverEnv . solver ( ) . minMax ( ) . setMethod ( storm : : solver : : MinMaxMethod : : ValueIteration ,  false ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                // relevantStates are default all set
  
			
		
	
		
			
				
					                // if the upper bound is 0 a psiState cannot be passed between 0 and the lower bound - we can reduce the relevant states and fill the psi states in the result with 1s.
  
			
		
	
		
			
				
					                //storm::storage::BitVector relevantStates(transitionMatrix.getRowGroupCount(), true);
  
			
		
	
		
			
				
					                storm : : storage : : BitVector  relevantStates  =  phiStates  &  ~ psiStates ;  
			
		
	
		
			
				
					                storm : : storage : : BitVector  makeZeroColumns ;  
			
		
	
		
			
				
					/*                if (goal.minimize()) {
  
			
		
	
		
			
				
					                    relevantStates  =  storm : : utility : : graph : : performProbGreater0A ( transitionMatrix ,  transitionMatrix . getRowGroupIndices ( ) ,  backwardTransitions ,  phiStates ,  psiStates ,  true ,  upperBound ) ;  
			
		
	
		
			
				
					                }  else  {  
			
		
	
		
			
				
					                    relevantStates  =  storm : : utility : : graph : : performProbGreater0E ( backwardTransitions ,  phiStates ,  psiStates ,  true ,  upperBound ) ;  
			
		
	
		
			
				
					                } */  
			
		
	
		
			
				
					/*                if(lowerBound == 0) {
  
			
		
	
		
			
				
					                    STORM_LOG_DEBUG ( " LOWER BOUND = 0, relevant states are the not-psiStates " ) ;  
			
		
	
		
			
				
					                    relevantStates  =  phiStates  &  ~ psiStates ;  
			
		
	
		
			
				
					                } */  /*else {
  
			
		
	
		
			
				
					                    STORM_LOG_DEBUG ( " LOWER BOUND !=0, relevant states are all states, makeZeroColumns = psiStates " ) ;  
			
		
	
		
			
				
					                    makeZeroColumns  =  psiStates ;  
			
		
	
		
			
				
					                } */  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                STORM_LOG_DEBUG ( " relevantStates =  "  < <  relevantStates ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                // Initializations.
  
			
		
	
		
			
				
					                std : : vector < ValueType >  x  =  std : : vector < ValueType > ( relevantStates . getNumberOfSetBits ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                std : : vector < ValueType >  b  =  transitionMatrix . getConstrainedRowGroupSumVector ( relevantStates ,  psiStates ) ;  
			
		
	
		
			
				
					                std : : vector < ValueType >  result  =  std : : vector < ValueType > ( transitionMatrix . getRowGroupCount ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                std : : vector < ValueType >  constrainedChoiceValues  =  std : : vector < ValueType > ( transitionMatrix . getConstrainedRowGroupSumVector ( relevantStates ,  psiStates ) . size ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                std : : unique_ptr < storm : : storage : : Scheduler < ValueType > >  scheduler ;  
			
		
	
		
			
				
					                if  ( produceScheduler )  {  
			
		
	
		
			
				
					                    scheduler  =  std : : make_unique < storm : : storage : : Scheduler < ValueType > > ( expandScheduler ( viHelper . extractScheduler ( ) ,  relevantStates ,  ~ relevantStates ) ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                return  SMGSparseModelCheckingHelperReturnType < ValueType > ( std : : move ( x ) ,  std : : move ( relevantStates ) ,  std : : move ( scheduler ) ,  std : : move ( constrainedChoiceValues ) ) ;  
			
		
	
		
			
				
					                storm : : storage : : BitVector  clippedStatesOfCoalition ( relevantStates . getNumberOfSetBits ( ) ) ;  
			
		
	
		
			
				
					                clippedStatesOfCoalition . setClippedStatesOfCoalition ( relevantStates ,  statesOfCoalition ) ;  
			
		
	
		
			
				
					                //clippedStatesOfCoalition.complement();
  
			
		
	
		
			
				
					                STORM_LOG_DEBUG ( clippedStatesOfCoalition ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                if ( ! relevantStates . empty ( )  & &  upperBound  >  0 )  {  
			
		
	
		
			
				
					                    // Reduce the matrix to relevant states. - relevant states are all states
  
			
		
	
		
			
				
					                    storm : : storage : : SparseMatrix < ValueType >  submatrix  =  transitionMatrix . getSubmatrix ( true ,  relevantStates ,  relevantStates ,  false ,  makeZeroColumns ) ;  
			
		
	
		
			
				
					                    // Create GameViHelper for computations.
  
			
		
	
		
			
				
					                    storm : : modelchecker : : helper : : internal : : GameViHelper < ValueType >  viHelper ( submatrix ,  clippedStatesOfCoalition ) ;  
			
		
	
		
			
				
					                    if  ( produceScheduler )  {  
			
		
	
		
			
				
					                        viHelper . setProduceScheduler ( true ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    if ( lowerBound  = =  0 )  {  
			
		
	
		
			
				
					                        STORM_LOG_DEBUG ( " LOWER BOUND = 0 ... " ) ;  
			
		
	
		
			
				
					                        STORM_LOG_DEBUG ( " Just peform Value Iteration with an UPPER BOUND. " ) ;  
			
		
	
		
			
				
					                        viHelper . performValueIterationUpperBound ( env ,  x ,  b ,  goal . direction ( ) ,  upperBound ,  constrainedChoiceValues ) ;  
			
		
	
		
			
				
					                    }  else  {  
			
		
	
		
			
				
					                        STORM_LOG_DEBUG ( " LOWER BOUND != 0 ... " ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                        // TODO: change the computation: first the diff, then till the lowerBound
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                        STORM_LOG_DEBUG ( " first multiplication ... " ) ;  
			
		
	
		
			
				
					                        viHelper . performValueIterationUpperBound ( env ,  x ,  b ,  goal . direction ( ) ,  upperBound  -  lowerBound  +  1 ,  constrainedChoiceValues ) ;  
			
		
	
		
			
				
					                        STORM_LOG_DEBUG ( " x =  "  < <  x ) ;  
			
		
	
		
			
				
					                        STORM_LOG_DEBUG ( " b =  "  < <  b ) ;  
			
		
	
		
			
				
					                        STORM_LOG_DEBUG ( " constrainedChoiceValues =  "  < <  constrainedChoiceValues ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                        STORM_LOG_DEBUG ( " Reduction for ~phiStates ... " ) ;  
			
		
	
		
			
				
					 /*                       for(uint rowGroupIndex = 0; rowGroupIndex < submatrix.getRowGroupCount(); rowGroupIndex++) {
  
			
		
	
		
			
				
					                            for ( uint  rowIndex  =  0 ;  rowIndex  <  submatrix . getRowGroupSize ( rowGroupIndex ) ;  rowIndex + + )  {  
			
		
	
		
			
				
					                                if ( ! phiStates . get ( rowGroupIndex ) )  {  
			
		
	
		
			
				
					                                    constrainedChoiceValues . at ( rowGroupIndex )  =  storm : : utility : : zero < ValueType > ( ) ;  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                        } */  
			
		
	
		
			
				
					                        STORM_LOG_DEBUG ( " constrainedChoiceValues =  "  < <  constrainedChoiceValues ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                        //storm::storage::BitVector newRelevantStates(x.size(), false);
  
			
		
	
		
			
				
					                        //storm::utility::vector::setNonzeroIndices(x, newRelevantStates);
  
			
		
	
		
			
				
					                        //storm::utility::vector::setVectorValues(x, ~phiStates, storm::utility::zero<ValueType>());
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                        STORM_LOG_DEBUG ( " reset x ... " ) ;  
			
		
	
		
			
				
					                        x  =  std : : vector < ValueType > ( x . size ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                        STORM_LOG_DEBUG ( " x =  "  < <  x ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                        STORM_LOG_DEBUG ( " second multiplication ... " ) ;  
			
		
	
		
			
				
					                        viHelper . performValueIterationUpperBound ( env ,  x ,  constrainedChoiceValues ,  goal . direction ( ) ,  lowerBound ,  constrainedChoiceValues ) ;  
			
		
	
		
			
				
					                        STORM_LOG_DEBUG ( " x =  "  < <  x ) ;  
			
		
	
		
			
				
					                        STORM_LOG_DEBUG ( " b =  "  < <  b ) ;  
			
		
	
		
			
				
					                        STORM_LOG_DEBUG ( " constrainedChoiceValues =  "  < <  constrainedChoiceValues ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/*
  
			
		
	
		
			
				
					                        viHelper . performValueIterationUpperBound ( env ,  x ,  b ,  goal . direction ( ) ,  upperBound  -  lowerBound  +  1 ,  constrainedChoiceValues ) ;  
			
		
	
		
			
				
					                        submatrix  =  transitionMatrix . getSubmatrix ( true ,  relevantStates ,  relevantStates ,  false ) ;  
			
		
	
		
			
				
					                        viHelper . updateTransitionMatrix ( submatrix ) ;  
			
		
	
		
			
				
					                        b  =  std : : vector < ValueType > ( b . size ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                        viHelper . performValueIterationUpperBound ( env ,  x ,  b ,  goal . direction ( ) ,  lowerBound  -  1 ,  constrainedChoiceValues ) ;  
			
		
	
		
			
				
					*/  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    viHelper . fillChoiceValuesVector ( constrainedChoiceValues ,  relevantStates ,  transitionMatrix . getRowGroupIndices ( ) ) ;  
			
		
	
		
			
				
					                    if  ( produceScheduler )  {  
			
		
	
		
			
				
					                        scheduler  =  std : : make_unique < storm : : storage : : Scheduler < ValueType > > ( expandScheduler ( viHelper . extractScheduler ( ) ,  relevantStates ,  ~ relevantStates ) ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    storm : : utility : : vector : : setVectorValues ( result ,  relevantStates ,  x ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                if ( lowerBound  = =  0 )  {  
			
		
	
		
			
				
					                    storm : : utility : : vector : : setVectorValues ( result ,  psiStates ,  storm : : utility : : one < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                STORM_LOG_DEBUG ( result ) ;  
			
		
	
		
			
				
					                return  SMGSparseModelCheckingHelperReturnType < ValueType > ( std : : move ( result ) ,  std : : move ( relevantStates ) ,  std : : move ( scheduler ) ,  std : : move ( constrainedChoiceValues ) ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					            template  class  SparseSmgRpatlHelper < double > ;