@ -23,25 +23,20 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				    namespace  modelchecker  {  
				 
				 
				    namespace  modelchecker  {  
			
		 
		
	
		
			
				 
				 
				        namespace  multiobjective  {  
				 
				 
				        namespace  multiobjective  {  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				            bool  inOutEncoding ( )  {  // + 8
  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                bool  result  =  encodingSettings ( ) . get ( 60 ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                STORM_LOG_ERROR_COND ( ! result  | |  ! isMinNegativeEncoding ( ) ,  " inout-encoding only works without minnegative encoding. " ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                return  result ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				            }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				             
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				            bool  assertBottomStateSum ( )  {  // + 16
  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                bool  result  =  encodingSettings ( ) . get ( 59 ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                STORM_LOG_ERROR_COND ( ! result  | |  inOutEncoding ( ) ,  " Asserting bottom state sum is only relevant for in-out encoding. " ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                return  result ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				            }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				             
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				            bool  useNonOptimalSolutions ( )  {  // + 32
  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                bool  result  =  encodingSettings ( ) . get ( 58 ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                return  result ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				            }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				             
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				            template  < typename  ModelType ,  typename  GeometryValueType >  
				 
				 
				            template  < typename  ModelType ,  typename  GeometryValueType >  
			
		 
		
	
		
			
				 
				 
				            DeterministicSchedsLpChecker < ModelType ,  GeometryValueType > : : DeterministicSchedsLpChecker ( Environment  const &  env ,  ModelType  const &  model ,  std : : vector < DeterministicSchedsObjectiveHelper < ModelType > >  const &  objectiveHelper )  :  model ( model )  ,  objectiveHelper ( objectiveHelper ) ,  numLpQueries ( 0 )  {  
				 
				 
				            DeterministicSchedsLpChecker < ModelType ,  GeometryValueType > : : DeterministicSchedsLpChecker ( Environment  const &  env ,  ModelType  const &  model ,  std : : vector < DeterministicSchedsObjectiveHelper < ModelType > >  const &  objectiveHelper )  :  model ( model )  ,  objectiveHelper ( objectiveHelper ) ,  numLpQueries ( 0 )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                if  ( env . modelchecker ( ) . multi ( ) . getEncodingType ( )  = =  storm : : MultiObjectiveModelCheckerEnvironment : : EncodingType : : Auto )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    flowEncoding  =  true ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    for  ( auto  const &  helper  :  objectiveHelper )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        if  ( ! helper . isTotalRewardObjective ( ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            flowEncoding  =  false ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                }  else  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    flowEncoding  =  env . modelchecker ( ) . multi ( ) . getEncodingType ( )  = =  storm : : MultiObjectiveModelCheckerEnvironment : : EncodingType : : Flow ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                STORM_LOG_INFO_COND ( flowEncoding ,  " Using classical encoding. " ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                STORM_LOG_INFO_COND ( ! flowEncoding ,  " Using flow encoding. " ) ;  
			
		 
		
	
		
			
				 
				 
				                swAll . start ( ) ;  
				 
				 
				                swAll . start ( ) ;  
			
		 
		
	
		
			
				 
				 
				                swInit . start ( ) ;  
				 
				 
				                swInit . start ( ) ;  
			
		 
		
	
		
			
				 
				 
				                initializeLpModel ( env ) ;  
				 
				 
				                initializeLpModel ( env ) ;  
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -381,13 +376,13 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                std : : vector < std : : vector < storm : : expressions : : Expression > >  ecVars ( objectiveHelper . size ( ) ,  std : : vector < storm : : expressions : : Expression > ( model . getNumberOfStates ( ) ) ) ;  
				 
				 
				                std : : vector < std : : vector < storm : : expressions : : Expression > >  ecVars ( objectiveHelper . size ( ) ,  std : : vector < storm : : expressions : : Expression > ( model . getNumberOfStates ( ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				                bool  hasEndComponents  =  processEndComponents ( ecVars ) ;  
				 
				 
				                bool  hasEndComponents  =  processEndComponents ( ecVars ) ;  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                if  ( inOutEncoding ( ) )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                if  ( flowEncoding )  {  
			
		 
		
	
		
			
				 
				 
				                    storm : : storage : : BitVector  bottomStates ( model . getNumberOfStates ( ) ,  true ) ;  
				 
				 
				                    storm : : storage : : BitVector  bottomStates ( model . getNumberOfStates ( ) ,  true ) ;  
			
		 
		
	
		
			
				 
				 
				                    for  ( auto  const &  helper  :  objectiveHelper )  {  
				 
				 
				                    for  ( auto  const &  helper  :  objectiveHelper )  {  
			
		 
		
	
		
			
				 
				 
				                        STORM_LOG_THROW ( helper . isTotalRewardObjective ( ) ,  storm : : exceptions : : InvalidOperationException ,  " The given type of encoding is only supported if the objectives can be reduced to total reward objectives. " ) ;  
				 
				 
				                        STORM_LOG_THROW ( helper . isTotalRewardObjective ( ) ,  storm : : exceptions : : InvalidOperationException ,  " The given type of encoding is only supported if the objectives can be reduced to total reward objectives. " ) ;  
			
		 
		
	
		
			
				 
				 
				                        storm : : storage : : BitVector  objBottomStates ( model . getNumberOfStates ( ) ,  false ) ;  
				 
				 
				                        storm : : storage : : BitVector  objBottomStates ( model . getNumberOfStates ( ) ,  false ) ;  
			
		 
		
	
		
			
				 
				 
				                        for  ( auto  const &  stateVal  :  helper . getSchedulerIndependentStateValues ( ) )  {  
				 
				 
				                        for  ( auto  const &  stateVal  :  helper . getSchedulerIndependentStateValues ( ) )  {  
			
		 
		
	
		
			
				 
				 
				                            STORM_LOG_THROW ( storm : : utility : : isZero ( stateVal . second ) ,  storm : : exceptions : : InvalidOperationException ,  " Non-zero constant state-values not allowed for this type of  encoding. " ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            STORM_LOG_THROW ( storm : : utility : : isZero ( stateVal . second ) ,  storm : : exceptions : : InvalidOperationException ,  " Non-zero constant state-values not allowed for flow  encoding. " ) ;  
			
		 
		
	
		
			
				 
				 
				                            objBottomStates . set ( stateVal . first ,  true ) ;  
				 
				 
				                            objBottomStates . set ( stateVal . first ,  true ) ;  
			
		 
		
	
		
			
				 
				 
				                        }  
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				                        bottomStates  & =  objBottomStates ;  
				 
				 
				                        bottomStates  & =  objBottomStates ;  
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -449,9 +444,8 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                        lpModel - > addConstraint ( " " ,  storm : : expressions : : sum ( ins [ state ] )  = =  storm : : expressions : : sum ( outs [ state ] ) ) ;  
				 
				 
				                        lpModel - > addConstraint ( " " ,  storm : : expressions : : sum ( ins [ state ] )  = =  storm : : expressions : : sum ( outs [ state ] ) ) ;  
			
		 
		
	
		
			
				 
				 
				                         
				 
				 
				                         
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				                    if  ( assertBottomStateSum ( ) )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        lpModel - > addConstraint ( " " ,  storm : : expressions : : sum ( bottomStatesIn )  = =  one ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    // Assert the sum for the bottom states
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    lpModel - > addConstraint ( " " ,  storm : : expressions : : sum ( bottomStatesIn )  = =  one ) ;  
			
		 
		
	
		
			
				 
				 
				                     
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				                    // create initial state results for each objective
  
				 
				 
				                    // create initial state results for each objective
  
			
		 
		
	
		
			
				 
				 
				                    for  ( uint64_t  objIndex  =  0 ;  objIndex  <  objectiveHelper . size ( ) ;  + + objIndex )  {  
				 
				 
				                    for  ( uint64_t  objIndex  =  0 ;  objIndex  <  objectiveHelper . size ( ) ;  + + objIndex )  {  
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -612,43 +606,21 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                        swValidate . start ( ) ;  
				 
				 
				                        swValidate . start ( ) ;  
			
		 
		
	
		
			
				 
				 
				                        Point  newPoint  =  validateCurrentModel ( env ) ;  
				 
				 
				                        Point  newPoint  =  validateCurrentModel ( env ) ;  
			
		 
		
	
		
			
				 
				 
				                        swValidate . stop ( ) ;  
				 
				 
				                        swValidate . stop ( ) ;  
			
		 
		
	
		
			
				 
				 
				                        std : : vector < Point >  newPoints  =  { newPoint } ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        if  ( gurobiLpModel  & &  useNonOptimalSolutions ( ) )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                            // gurobi might have other good solutions.
  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                            for  ( uint64_t  solutionIndex  =  0 ;  solutionIndex  <  gurobiLpModel - > getSolutionCount ( ) ;  + +  solutionIndex )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                                Point  p ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                                bool  considerP  =  false ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                                for  ( uint64_t  objIndex  =  0 ;  objIndex  <  currentObjectiveVariables . size ( ) ;  + + objIndex )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                                    p . push_back ( storm : : utility : : convertNumber < GeometryValueType > ( gurobiLpModel - > getContinuousValue ( currentObjectiveVariables [ objIndex ] ,  solutionIndex ) ) ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                                    if  ( p . back ( )  >  newPoint [ objIndex ]  +  eps [ objIndex ]  /  storm : : utility : : convertNumber < GeometryValueType > ( 2 ) )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                                        // The other solution dominates the newPoint in this dimension and is also not too close to the newPoint.
  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                                        considerP  =  true ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                                    }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                                }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                                if  ( considerP )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                                    newPoints . push_back ( std : : move ( p ) ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                                }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                            }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        GeometryValueType  offset  =  storm : : utility : : convertNumber < GeometryValueType > ( lpModel - > getObjectiveValue ( ) ) ;  
				 
				 
				                        GeometryValueType  offset  =  storm : : utility : : convertNumber < GeometryValueType > ( lpModel - > getObjectiveValue ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				                        if  ( gurobiLpModel )  {  
				 
				 
				                        if  ( gurobiLpModel )  {  
			
		 
		
	
		
			
				 
				 
				                            // Gurobi gives us the gap between the found solution and the known bound.
  
				 
				 
				                            // Gurobi gives us the gap between the found solution and the known bound.
  
			
		 
		
	
		
			
				 
				 
				                            offset  + =  storm : : utility : : convertNumber < GeometryValueType > ( gurobiLpModel - > getMILPGap ( false ) ) ;  
				 
				 
				                            offset  + =  storm : : utility : : convertNumber < GeometryValueType > ( gurobiLpModel - > getMILPGap ( false ) ) ;  
			
		 
		
	
		
			
				 
				 
				                        }  
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				                        // we might want to shift the halfspace to guarantee that our point is included.
  
				 
				 
				                        // we might want to shift the halfspace to guarantee that our point is included.
  
			
		 
		
	
		
			
				 
				 
				                        for  ( auto  const &  p  :  newPoints )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                            offset  =  std : : max ( offset ,  storm : : utility : : vector : : dotProduct ( currentWeightVector ,  p ) ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        offset  =  std : : max ( offset ,  storm : : utility : : vector : : dotProduct ( currentWeightVector ,  newPoint ) ) ;  
			
		 
		
	
		
			
				 
				 
				                        auto  halfspace  =  storm : : storage : : geometry : : Halfspace < GeometryValueType > ( currentWeightVector ,  offset ) . invert ( ) ;  
				 
				 
				                        auto  halfspace  =  storm : : storage : : geometry : : Halfspace < GeometryValueType > ( currentWeightVector ,  offset ) . invert ( ) ;  
			
		 
		
	
		
			
				 
				 
				                        infeasableAreas . push_back ( polytopeTree . getPolytope ( ) - > intersection ( halfspace ) ) ;  
				 
				 
				                        infeasableAreas . push_back ( polytopeTree . getPolytope ( ) - > intersection ( halfspace ) ) ;  
			
		 
		
	
		
			
				 
				 
				                        if  ( infeasableAreas . back ( ) - > isEmpty ( ) )  {  
				 
				 
				                        if  ( infeasableAreas . back ( ) - > isEmpty ( ) )  {  
			
		 
		
	
		
			
				 
				 
				                            infeasableAreas . pop_back ( ) ;  
				 
				 
				                            infeasableAreas . pop_back ( ) ;  
			
		 
		
	
		
			
				 
				 
				                        }  
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				                        polytopeTree . setMinus ( storm : : storage : : geometry : : Polytope < GeometryValueType > : : create ( { halfspace } ) ) ;  
				 
				 
				                        polytopeTree . setMinus ( storm : : storage : : geometry : : Polytope < GeometryValueType > : : create ( { halfspace } ) ) ;  
			
		 
		
	
		
			
				 
				 
				                        for  ( auto  const &  p  :  newPoints )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                            foundPoints . push_back ( p ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                            polytopeTree . substractDownwardClosure ( p ,  eps ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        foundPoints . push_back ( newPoint ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        polytopeTree . substractDownwardClosure ( newPoint ,  eps ) ;  
			
		 
		
	
		
			
				 
				 
				                        if  ( ! polytopeTree . isEmpty ( ) )  {  
				 
				 
				                        if  ( ! polytopeTree . isEmpty ( ) )  {  
			
		 
		
	
		
			
				 
				 
				                            checkRecursive ( env ,  polytopeTree ,  eps ,  foundPoints ,  infeasableAreas ,  depth ) ;  
				 
				 
				                            checkRecursive ( env ,  polytopeTree ,  eps ,  foundPoints ,  infeasableAreas ,  depth ) ;  
			
		 
		
	
		
			
				 
				 
				                        }  
				 
				 
				                        }