@ -47,35 +47,47 @@ namespace storm { 
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            template  < typename  ValueType >  
			
		
	
		
			
				
					            std : : shared_ptr < Polytope < ValueType > >  Polytope < ValueType > : : createDownwardClosure ( std : : vector < Point >  const &  points )  {  
			
		
	
		
			
				
					                if ( points . empty ( ) )  {  
			
		
	
		
			
				
					                if   ( points . empty ( ) )  {  
			
		
	
		
			
				
					                    // In this case, the downwardclosure is empty
  
			
		
	
		
			
				
					                    return  createEmptyPolytope ( ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                uint_fast64_t  const  dimensions  =  points . front ( ) . size ( ) ;  
			
		
	
		
			
				
					                // Reduce this call to a more general method
  
			
		
	
		
			
				
					                storm : : storage : : BitVector  dimensions ( points . front ( ) . size ( ) ,  true ) ;  
			
		
	
		
			
				
					                return  createSelectiveDownwardClosure ( points ,  dimensions ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            template  < typename  ValueType >  
			
		
	
		
			
				
					            std : : shared_ptr < Polytope < ValueType > >  Polytope < ValueType > : : createSelectiveDownwardClosure ( std : : vector < Point >  const &  points ,  storm : : storage : : BitVector  const &  selectedDimensions )  {  
			
		
	
		
			
				
					                if  ( points . empty ( ) )  {  
			
		
	
		
			
				
					                    // In this case, the downwardclosure is empty
  
			
		
	
		
			
				
					                    return  createEmptyPolytope ( ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                if  ( selectedDimensions . empty ( ) )  {  
			
		
	
		
			
				
					                    return  create ( points ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                assert ( points . front ( ) . size ( )  = =  selectedDimensions . size ( ) ) ;  
			
		
	
		
			
				
					                uint64_t  dimensions  =  selectedDimensions . size ( ) ;  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                std : : vector < Halfspace < ValueType > >  halfspaces ;  
			
		
	
		
			
				
					                // We build the convex hull of the given points.
  
			
		
	
		
			
				
					                // However, auxiliary points (that will always be in the downward closure) are added.
  
			
		
	
		
			
				
					                // However, auxiliary points (that will always be in the selective  downward closure) are added.
  
			
		
	
		
			
				
					                // Then, the halfspaces of the resulting polytope are a superset of the halfspaces of the downward closure.
  
			
		
	
		
			
				
					                std : : vector < Point >  auxiliaryPoints  =  points ;  
			
		
	
		
			
				
					                auxiliaryPoints . reserve ( auxiliaryPoints . size ( ) * ( 1 + dimensions ) ) ;  
			
		
	
		
			
				
					                for ( auto  const &  point  :  points )  {  
			
		
	
		
			
				
					                    for ( uint_fast64_t  dim = 0 ;  dim < dimensions ;  + + dim )  {  
			
		
	
		
			
				
					                auxiliaryPoints . reserve ( auxiliaryPoints . size ( )   *   ( 1   +   selecte dD imensions. getNumberOfSetBits ( ) ) ) ;  
			
		
	
		
			
				
					                for   ( auto  const &  point  :  points )  {  
			
		
	
		
			
				
					                    for  ( auto  const &  dim  :  selectedDimensions  )  {  
			
		
	
		
			
				
					                        auxiliaryPoints . push_back ( point ) ;  
			
		
	
		
			
				
					                        auxiliaryPoints . back ( ) [ dim ]  - =  storm : : utility : : one < ValueType > ( ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                std : : vector < Halfspace < ValueType > >  auxiliaryHalfspaces  =  create ( auxiliaryPoints ) - > getHalfspaces ( ) ;  
			
		
	
		
			
				
					                // The downward closure is obtained by selecting the halfspaces for which the normal vector is non-negative (coordinate wise).
  
			
		
	
		
			
				
					                // Note that due to the auxiliary points, the polytope is never degenerated and thus there is always one unique halfspace-representation which is necessary:
  
			
		
	
		
			
				
					                // Consider, e.g., the convex hull of two points (1,0,0) and (0,1,1).
  
			
		
	
		
			
				
					                // There are multiple halfspace-representations for this set. In particular, there is one where all but one normalVectors have negative entries.
  
			
		
	
		
			
				
					                // However, the downward closure of this set can only be represented with 5 halfspaces.
  
			
		
	
		
			
				
					                for ( auto &  h  :  auxiliaryHalfspaces ) {  
			
		
	
		
			
				
					                    bool  allGreaterZero  =  true ;  
			
		
	
		
			
				
					                    for ( auto  const &  value  :  h . normalVector ( ) )  {  
			
		
	
		
			
				
					                        allGreaterZero  & =  ( value  > =  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                // The downward closure is obtained by erasing the halfspaces for which the normal vector is negative for one of the selected dimensions.
  
			
		
	
		
			
				
					                for  ( auto &  h  :  auxiliaryHalfspaces )  {  
			
		
	
		
			
				
					                    bool  allGreaterEqZero  =  true ;  
			
		
	
		
			
				
					                    for  ( auto  const &  dim  :  selectedDimensions )  {  
			
		
	
		
			
				
					                        allGreaterEqZero  & =  ( h . normalVector ( ) [ dim ]  > =  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    if ( allGreaterZero ) {  
			
		
	
		
			
				
					                    if  ( allGreaterEqZero ) {  
			
		
	
		
			
				
					                        halfspaces . push_back ( std : : move ( h ) ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                }  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -155,11 +167,55 @@ namespace storm { 
			
		
	
		
			
				
					                return  std : : vector < Point > ( ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					            template  < typename  ValueType >  
			
		
	
		
			
				
					            std : : shared_ptr < Polytope < ValueType > >  Polytope < ValueType > : : shift ( Point  const &  b )  const  {  
			
		
	
		
			
				
					                // perform an affine transformation with identity matrix
  
			
		
	
		
			
				
					                std : : vector < Point >  idMatrix ( b . size ( ) ,  Point ( b . size ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ) ;  
			
		
	
		
			
				
					                for  ( uint64_t  i  =  0 ;  i  <  b . size ( ) ;  + + i )  {  
			
		
	
		
			
				
					                    idMatrix [ i ] [ i ]  =  storm : : utility : : one < ValueType > ( ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                return  affineTransformation ( idMatrix ,  b ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            template  < typename  ValueType >  
			
		
	
		
			
				
					            std : : vector < std : : shared_ptr < Polytope < ValueType > > >  Polytope < ValueType > : : setMinus ( std : : shared_ptr < Polytope < ValueType > >  const &  rhs )  const  {  
			
		
	
		
			
				
					                std : : vector < std : : shared_ptr < Polytope < ValueType > > >  result ;  
			
		
	
		
			
				
					                auto  rhsHalfspaces  =  rhs - > getHalfspaces ( ) ;  
			
		
	
		
			
				
					                std : : shared_ptr < Polytope < ValueType > >  remaining  =  nullptr ;  
			
		
	
		
			
				
					                for  ( auto  const &  h  :  rhsHalfspaces )  {  
			
		
	
		
			
				
					                    Polytope < ValueType >  const &  ref  =  ( remaining  = =  nullptr )  ?  * this  :  * remaining ;  
			
		
	
		
			
				
					                    auto  next  =  ref . intersection ( h . invert ( ) ) ;  
			
		
	
		
			
				
					                    if  ( ! next - > isEmpty ( ) )  {  
			
		
	
		
			
				
					                        result . push_back ( next ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    remaining  =  ref . intersection ( h ) ;  
			
		
	
		
			
				
					                    if  ( remaining - > isEmpty ( ) )  {  
			
		
	
		
			
				
					                        break ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                return  result ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					            template  < typename  ValueType >  
			
		
	
		
			
				
					            std : : shared_ptr < Polytope < ValueType > >  Polytope < ValueType > : : downwardClosure ( )  const  {  
			
		
	
		
			
				
					                return  createDownwardClosure ( this - > getVertices ( ) ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            template  < typename  ValueType >  
			
		
	
		
			
				
					            std : : vector < storm : : expressions : : Variable >  Polytope < ValueType > : : declareVariables ( storm : : expressions : : ExpressionManager &  manager ,  std : : string  const &  namePrefix )  const  {  
			
		
	
		
			
				
					                STORM_LOG_THROW ( false ,  storm : : exceptions : : NotImplementedException ,  " Functionality not implemented for this polytope implementation. " ) ;  
			
		
	
		
			
				
					                std : : vector < storm : : expressions : : Variable >  result ;  
			
		
	
		
			
				
					                return  result ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					            template  < typename  ValueType >  
			
		
	
		
			
				
					            std : : vector < storm : : expressions : : Expression >  Polytope < ValueType > : : getConstraints ( storm : : expressions : : ExpressionManager  const &  manager ,  std : : vector < storm : : expressions : : Variable >  const &  variables )  const  {  
			
		
	
		
			
				
					                STORM_LOG_THROW ( false ,  storm : : exceptions : : NotImplementedException ,  " Functionality not implemented for this polytope implementation. " ) ;  
			
		
	
		
			
				
					                std : : vector < storm : : expressions : : Expression >  result ;  
			
		
	
		
			
				
					                return  result ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            template  < typename  ValueType >  
			
		
	
		
			
				
					            template  < typename  TargetType >  
			
		
	
		
			
				
					            std : : shared_ptr < Polytope < TargetType > >  Polytope < ValueType > : : convertNumberRepresentation ( )  const  {  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -197,6 +253,12 @@ namespace storm { 
			
		
	
		
			
				
					                return  false ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            template  < typename  ValueType >  
			
		
	
		
			
				
					            std : : shared_ptr < Polytope < ValueType > >  Polytope < ValueType > : : clean ( )  {  
			
		
	
		
			
				
					                STORM_LOG_THROW ( false ,  storm : : exceptions : : NotImplementedException ,  " functionality not implemented for this polytope type. " ) ;  
			
		
	
		
			
				
					                return  nullptr ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					            template  class  Polytope < double > ;  
			
		
	
		
			
				
					            template  std : : shared_ptr < Polytope < double > >  Polytope < double > : : convertNumberRepresentation ( )  const ;