@ -10,6 +10,7 @@ 
			
		 
		
	
		
			
				 
				 
				# include  "storm/modelchecker/multiobjective/MultiObjectivePostprocessing.h" 
  
				 
				 
				# include  "storm/modelchecker/multiobjective/MultiObjectivePostprocessing.h" 
  
			
		 
		
	
		
			
				 
				 
				# include  "storm/modelchecker/results/ExplicitParetoCurveCheckResult.h" 
  
				 
				 
				# include  "storm/modelchecker/results/ExplicitParetoCurveCheckResult.h" 
  
			
		 
		
	
		
			
				 
				 
				# include  "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" 
  
				 
				 
				# include  "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" 
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				# include  "storm/environment/solver/MinMaxSolverEnvironment.h" 
  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				# include  "storm/utility/export.h" 
  
				 
				 
				# include  "storm/utility/export.h" 
  
			
		 
		
	
		
			
				 
				 
				# include  "storm/utility/solver.h" 
  
				 
				 
				# include  "storm/utility/solver.h" 
  
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -441,12 +442,13 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				            template  < class  SparseModelType ,  typename  GeometryValueType >  
				 
				 
				            template  < class  SparseModelType ,  typename  GeometryValueType >  
			
		 
		
	
		
			
				 
				 
				            void  DeterministicSchedsParetoExplorer < SparseModelType ,  GeometryValueType > : : processFacet ( Environment  const &  env ,  Facet &  f )  {  
				 
				 
				            void  DeterministicSchedsParetoExplorer < SparseModelType ,  GeometryValueType > : : processFacet ( Environment  const &  env ,  Facet &  f )  {  
			
		 
		
	
		
			
				 
				 
				                if  ( optimizeAndSplitFacet ( env , f ) )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                GeometryValueType  eps  =  storm : : utility : : convertNumber < GeometryValueType > ( env . modelchecker ( ) . multi ( ) . getPrecision ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                eps  + =  eps ;  // The unknown area (box) can actually have size 2*eps
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                if  ( optimizeAndSplitFacet ( env ,  f ,  eps ) )  {  
			
		 
		
	
		
			
				 
				 
				                    return ;  
				 
				 
				                    return ;  
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                GeometryValueType  eps  =  storm : : utility : : convertNumber < GeometryValueType > ( env . modelchecker ( ) . multi ( ) . getPrecision ( ) ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                eps  + =  eps ;  // The unknown area (box) can actually have size 2*eps
  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                storm : : storage : : geometry : : PolytopeTree < GeometryValueType >  polytopeTree ( f . getInducedPolytope ( pointset ,  getReferenceCoordinates ( env ) ) ) ;  
				 
				 
				                storm : : storage : : geometry : : PolytopeTree < GeometryValueType >  polytopeTree ( f . getInducedPolytope ( pointset ,  getReferenceCoordinates ( env ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				                for  ( auto  const &  point  :  pointset )  {  
				 
				 
				                for  ( auto  const &  point  :  pointset )  {  
			
		 
		
	
		
			
				 
				 
				                    polytopeTree . substractDownwardClosure ( point . second . get ( ) ,  eps ) ;  
				 
				 
				                    polytopeTree . substractDownwardClosure ( point . second . get ( ) ,  eps ) ;  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -466,8 +468,18 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				            }  
				 
				 
				            }  
			
		 
		
	
		
			
				 
				 
				             
				 
				 
				             
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				            template  < typename  GeometryValueType >  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				            bool  closePoints ( std : : vector < GeometryValueType >  const &  first ,  std : : vector < GeometryValueType >  const &  second ,  GeometryValueType  const &  maxDistance )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                for  ( uint64_t  i  =  0 ;  i  <  first . size ( ) ;  + + i )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    if  ( storm : : utility : : abs < GeometryValueType > ( first [ i ]  -  second [ i ] )  >  maxDistance )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        return  false ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                return  true ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				            }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				             
			
		 
		
	
		
			
				 
				 
				            template  < class  SparseModelType ,  typename  GeometryValueType >  
				 
				 
				            template  < class  SparseModelType ,  typename  GeometryValueType >  
			
		 
		
	
		
			
				 
				 
				            bool  DeterministicSchedsParetoExplorer < SparseModelType ,  GeometryValueType > : : optimizeAndSplitFacet ( Environment  const &  env ,  Facet &  f )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				            bool  DeterministicSchedsParetoExplorer < SparseModelType ,  GeometryValueType > : : optimizeAndSplitFacet ( Environment  const &  env ,  Facet &  f ,  GeometryValueType  const &  eps )  {  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                // Invoke optimization and insert the explored points
  
				 
				 
				                // Invoke optimization and insert the explored points
  
			
		 
		
	
		
			
				 
				 
				                boost : : optional < PointId >  optPointId ;  
				 
				 
				                boost : : optional < PointId >  optPointId ;  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -489,17 +501,27 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                // Potentially generate new facets
  
				 
				 
				                // Potentially generate new facets
  
			
		 
		
	
		
			
				 
				 
				                if  ( optPointId )  {  
				 
				 
				                if  ( optPointId )  {  
			
		 
		
	
		
			
				 
				 
				                    auto  const &  optPoint  =  pointset . getPoint ( * optPointId ) ;  
				 
				 
				                    auto  const &  optPoint  =  pointset . getPoint ( * optPointId ) ;  
			
		 
		
	
		
			
				 
				 
				                    // TODO: this check might suffer from numerical errors. Check how much this would hurt us.
  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    if  ( f . getHalfspace ( ) . contains ( optPoint . get ( ) ) )  {  
				 
				 
				                    if  ( f . getHalfspace ( ) . contains ( optPoint . get ( ) ) )  {  
			
		 
		
	
		
			
				 
				 
				                        // The point is contained in the halfspace which means that no more splitting is possible.
  
				 
				 
				                        // The point is contained in the halfspace which means that no more splitting is possible.
  
			
		 
		
	
		
			
				 
				 
				                        return  false ;  
				 
				 
				                        return  false ;  
			
		 
		
	
		
			
				 
				 
				                    }  else  {  
				 
				 
				                    }  else  {  
			
		 
		
	
		
			
				 
				 
				                        // Found a new Pareto optimal point -> generate new facets
  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        // Collect the new point with its neighbors.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        // Also check whether the remamining area is already sufficiently small.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        storm : : storage : : geometry : : PolytopeTree < GeometryValueType >  remainingArea ( overApproximation - > intersection ( f . getHalfspace ( ) . invert ( ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				                        std : : vector < std : : vector < GeometryValueType > >  vertices ;  
				 
				 
				                        std : : vector < std : : vector < GeometryValueType > >  vertices ;  
			
		 
		
	
		
			
				 
				 
				                        vertices . push_back ( optPoint . get ( ) ) ;  
				 
				 
				                        vertices . push_back ( optPoint . get ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        auto  minmaxPrec  =  storm : : utility : : convertNumber < GeometryValueType > ( env . solver ( ) . minMax ( ) . getPrecision ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        minmaxPrec  + =  minmaxPrec ;  
			
		 
		
	
		
			
				 
				 
				                        for  ( auto  const &  pId  :  f . getPoints ( ) )  {  
				 
				 
				                        for  ( auto  const &  pId  :  f . getPoints ( ) )  {  
			
		 
		
	
		
			
				 
				 
				                            vertices . push_back ( pointset . getPoint ( pId ) . get ( ) ) ;  
				 
				 
				                            vertices . push_back ( pointset . getPoint ( pId ) . get ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            remainingArea . substractDownwardClosure ( vertices . back ( ) ,  eps ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            STORM_LOG_WARN_COND ( ( std : : is_same < ModelValueType ,  storm : : RationalNumber > : : value )  | |  ! closePoints ( vertices . front ( ) ,  vertices . back ( ) ,  minmaxPrec ) ,  " Found Pareto optimal points that are close to each other. This can be due to numerical issues. Maybe try exact mode? " ) ;  
			
		 
		
	
		
			
				 
				 
				                        }  
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        if  ( remainingArea . isEmpty ( ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            return  false ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                         
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        // We need to generate new facets
  
			
		 
		
	
		
			
				 
				 
				                        auto  newHalfspaceCandidates  =  storm : : storage : : geometry : : Polytope < GeometryValueType > : : createSelectiveDownwardClosure ( vertices ,  storm : : utility : : vector : : filterZero ( f . getHalfspace ( ) . normalVector ( ) ) ) - > getHalfspaces ( ) ;  
				 
				 
				                        auto  newHalfspaceCandidates  =  storm : : storage : : geometry : : Polytope < GeometryValueType > : : createSelectiveDownwardClosure ( vertices ,  storm : : utility : : vector : : filterZero ( f . getHalfspace ( ) . normalVector ( ) ) ) - > getHalfspaces ( ) ;  
			
		 
		
	
		
			
				 
				 
				                        for  ( auto &  h  :  newHalfspaceCandidates )  {  
				 
				 
				                        for  ( auto &  h  :  newHalfspaceCandidates )  {  
			
		 
		
	
		
			
				 
				 
				                            if  ( ! storm : : utility : : vector : : hasNegativeEntry ( h . normalVector ( ) ) )  {  
				 
				 
				                            if  ( ! storm : : utility : : vector : : hasNegativeEntry ( h . normalVector ( ) ) )  {