@ -7,6 +7,7 @@ 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm/exceptions/InvalidArgumentException.h" 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm/exceptions/NotSupportedException.h" 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm/exceptions/InvalidOperationException.h" 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm-config.h" 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm/adapters/RationalFunctionAdapter.h" 
  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -75,7 +76,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        Bdd < LibraryType >  DdManager < LibraryType > : : getEncoding ( storm : : expressions : : Variable  const &  variable ,  int_fast64_t  value ,  bool  mostSignificantBitAtTop )  const  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            DdMetaVariable < LibraryType >  const &  metaVariable  =  this - > getMetaVariable ( variable ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_THROW ( value  > =  metaVariable . getLow ( )  & &  value  < =  metaVariable . getHigh ( ) ,  storm : : exceptions : : InvalidArgumentException ,  " Illegal value  "  < <  value  < <  "  for meta variable ' "  < <  variable . getName ( )  < <  " '. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_THROW ( metaVariable . canRepresent ( value ) ,  storm : : exceptions : : InvalidArgumentException ,  " Illegal value  "  < <  value  < <  "  for meta variable ' "  < <  variable . getName ( )  < <  " '. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Now compute the encoding relative to the low value of the meta variable.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            value  - =  metaVariable . getLow ( ) ;  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -121,6 +122,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < DdType  LibraryType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        Bdd < LibraryType >  DdManager < LibraryType > : : getRange ( storm : : expressions : : Variable  const &  variable )  const  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            storm : : dd : : DdMetaVariable < LibraryType >  const &  metaVariable  =  this - > getMetaVariable ( variable ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_THROW ( metaVariable . hasHigh ( ) ,  storm : : exceptions : : InvalidOperationException ,  " Cannot create range for meta variable. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            Bdd < LibraryType >  result  =  this - > getBddZero ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -135,6 +137,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        Add < LibraryType ,  ValueType >  DdManager < LibraryType > : : getIdentity ( storm : : expressions : : Variable  const &  variable )  const  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            storm : : dd : : DdMetaVariable < LibraryType >  const &  metaVariable  =  this - > getMetaVariable ( variable ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_THROW ( metaVariable . hasHigh ( ) ,  storm : : exceptions : : InvalidOperationException ,  " Cannot create identity for meta variable. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            Add < LibraryType ,  ValueType >  result  =  this - > getAddZero < ValueType > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( int_fast64_t  value  =  metaVariable . getLow ( ) ;  value  < =  metaVariable . getHigh ( ) ;  + + value )  {  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -158,6 +161,20 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  result ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < DdType  LibraryType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        std : : vector < storm : : expressions : : Variable >  DdManager < LibraryType > : : cloneVariable ( storm : : expressions : : Variable  const &  variable ,  std : : string  const &  newMetaVariableName ,  boost : : optional < uint64_t >  const &  numberOfLayers )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < storm : : expressions : : Variable >  newMetaVariables ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            auto  const &  ddMetaVariable  =  this - > getMetaVariable ( variable ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( ddMetaVariable . getType ( )  = =  storm : : dd : : MetaVariableType : : Bool )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                newMetaVariables  =  this - > addMetaVariable ( newMetaVariableName ,  3 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  else  if  ( ddMetaVariable . getType ( )  = =  storm : : dd : : MetaVariableType : : Int )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                newMetaVariables  =  this - > addMetaVariable ( newMetaVariableName ,  ddMetaVariable . getLow ( ) ,  ddMetaVariable . getHigh ( ) ,  3 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  else  if  ( ddMetaVariable . getType ( )  = =  storm : : dd : : MetaVariableType : : BitVector )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                newMetaVariables  =  this - > addBitVectorMetaVariable ( newMetaVariableName ,  ddMetaVariable . getNumberOfDdVariables ( ) ,  3 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  newMetaVariables ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < DdType  LibraryType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        std : : pair < storm : : expressions : : Variable ,  storm : : expressions : : Variable >  DdManager < LibraryType > : : addMetaVariable ( std : : string  const &  name ,  int_fast64_t  low ,  int_fast64_t  high ,  boost : : optional < std : : pair < MetaVariablePosition ,  storm : : expressions : : Variable > >  const &  position )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < storm : : expressions : : Variable >  result  =  addMetaVariable ( name ,  low ,  high ,  2 ,  position ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -166,87 +183,33 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < DdType  LibraryType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        std : : vector < storm : : expressions : : Variable >  DdManager < LibraryType > : : addMetaVariable ( std : : string  const &  name ,  int_fast64_t  low ,  int_fast64_t  high ,  uint64_t  numberOfLayers ,  boost : : optional < std : : pair < MetaVariablePosition ,  storm : : expressions : : Variable > >  const &  position )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Check whether number of layers is legal.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_THROW ( numberOfLayers  > =  1 ,  storm : : exceptions : : InvalidArgumentException ,  " Layers must be at least 1. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Check whether the variable name is legal.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_THROW ( name  ! =  " "  & &  name . back ( )  ! =  ' \' ' ,  storm : : exceptions : : InvalidArgumentException ,  " Illegal name of meta variable: ' "  < <  name  < <  " '. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Check whether a meta variable already exists.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_THROW ( ! this - > hasMetaVariable ( name ) ,  storm : : exceptions : : InvalidArgumentException ,  " A meta variable ' "  < <  name  < <  " ' already exists. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Check that the range is legal.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_THROW ( high  > =  low ,  storm : : exceptions : : InvalidArgumentException ,  " Illegal empty range for meta variable. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : size_t  numberOfBits  =  static_cast < std : : size_t > ( std : : ceil ( std : : log2 ( high  -  low  +  1 ) ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // If a specific position was requested, we compute it now.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            boost : : optional < uint_fast64_t >  level ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( position )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : dd : : DdMetaVariable < LibraryType >  beforeVariable  =  this - > getMetaVariable ( position . get ( ) . second ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                level  =  position . get ( ) . first  = =  MetaVariablePosition : : Above  ?  std : : numeric_limits < uint_fast64_t > : : max ( )  :  std : : numeric_limits < uint_fast64_t > : : min ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( auto  const &  ddVariable  :  beforeVariable . getDdVariables ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    level  =  position . get ( ) . first  = =  MetaVariablePosition : : Above  ?  std : : min ( level . get ( ) ,  ddVariable . getLevel ( ) )  :  std : : max ( level . get ( ) ,  ddVariable . getLevel ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( position . get ( ) . first  = =  MetaVariablePosition : : Below )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    + + level . get ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // For the case where low and high coincide, we need to have a single bit.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( numberOfBits  = =  0 )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                + + numberOfBits ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_TRACE ( " Creating meta variable with  "  < <  numberOfBits  < <  "  bit(s) and  "  < <  numberOfLayers  < <  "  layer(s). " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : stringstream  tmp1 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < storm : : expressions : : Variable >  result ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( uint64  layer  =  0 ;  layer  <  numberOfLayers ;  + + layer )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                result . emplace_back ( manager - > declareBitVectorVariable ( name  +  tmp1 . str ( ) ,  numberOfBits ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                tmp1  < <  " ' " ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < std : : vector < Bdd < LibraryType > > >  variables ( numberOfLayers ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( std : : size_t  i  =  0 ;  i  <  numberOfBits ;  + + i )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : vector < InternalBdd < LibraryType > >  ddVariables  =  internalDdManager . createDdVariables ( numberOfLayers ,  level ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( uint64  layer  =  0 ;  layer  <  numberOfLayers ;  + + layer )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    variables [ layer ] . emplace_back ( Bdd < LibraryType > ( * this ,  ddVariables [ layer ] ,  { result [ layer ] } ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // If we are inserting the variable at a specific level, we need to prepare the level for the next pair
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // of variables.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( level )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    level . get ( )  + =  numberOfLayers ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : stringstream  tmp2 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( uint64_t  layer  =  0 ;  layer  <  numberOfLayers ;  + + layer )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                metaVariableMap . emplace ( result [ layer ] ,  DdMetaVariable < LibraryType > ( name  +  tmp2 . str ( ) ,  low ,  high ,  variables [ layer ] ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                tmp2  < <  " ' " ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  result ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  this - > addMetaVariableHelper ( MetaVariableType : : Int ,  name ,  std : : max ( static_cast < uint64_t > ( std : : ceil ( std : : log2 ( high  -  low  +  1 ) ) ) ,  1ull ) ,  numberOfLayers ,  position ,  std : : make_pair ( low ,  high ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < DdType  LibraryType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        std : : vector < storm : : expressions : : Variable >  DdManager < LibraryType > : : addBitVectorMetaVariable ( std : : string  const &  variableName ,  uint64_t  bits ,  uint64_t  numberOfLayers ,  boost : : optional < std : : pair < MetaVariablePosition ,  storm : : expressions : : Variable > >  const &  position )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  this - > addMetaVariable ( variableName ,  0 ,  ( 1ull  < <  bits )  -  1 ,  numberOfLayers ,  position ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  this - > addMetaVariableHelper ( MetaVariableType : : BitVector ,  variableName ,  bits ,  numberOfLayers ,  position ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < DdType  LibraryType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        std : : pair < storm : : expressions : : Variable ,  storm : : expressions : : Variable >  DdManager < LibraryType > : : addMetaVariable ( std : : string  const &  name ,  boost : : optional < std : : pair < MetaVariablePosition ,  storm : : expressions : : Variable > >  const &  position )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < storm : : expressions : : Variable >  result  =  addMetaVariable ( name ,  2 ,  position ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < storm : : expressions : : Variable >  result  =  this - > addMetaVariableHelper ( MetaVariableType : : Bool ,  name ,  1 ,  2 ,  position ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  std : : make_pair ( result [ 0 ] ,  result [ 1 ] ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < DdType  LibraryType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        std : : vector < storm : : expressions : : Variable >  DdManager < LibraryType > : : addMetaVariable ( std : : string  const &  name ,  uint64_t  numberOfLayers ,  boost : : optional < std : : pair < MetaVariablePosition ,  storm : : expressions : : Variable > >  const &  position )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  this - > addMetaVariableHelper ( MetaVariableType : : Bool ,  name ,  1 ,  numberOfLayers ,  position ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < DdType  LibraryType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        std : : vector < storm : : expressions : : Variable >  DdManager < LibraryType > : : addMetaVariableHelper ( MetaVariableType  const &  type ,  std : : string  const &  name ,  uint64_t  numberOfDdVariables ,  uint64_t  numberOfLayers ,  boost : : optional < std : : pair < MetaVariablePosition ,  storm : : expressions : : Variable > >  const &  position ,  boost : : optional < std : : pair < int_fast64_t ,  int_fast64_t > >  const &  bounds )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Check whether number of layers is legal.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_THROW ( numberOfLayers  > =  1 ,  storm : : exceptions : : InvalidArgumentException ,  " Layers must be at least 1. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Check that the number of DD variables is legal.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_THROW ( numberOfDdVariables  > =  1 ,  storm : : exceptions : : InvalidArgumentException ,  " Illegal number of DD variables. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Check whether the variable name is legal.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_THROW ( name  ! =  " "  & &  name . back ( )  ! =  ' \' ' ,  storm : : exceptions : : InvalidArgumentException ,  " Illegal name of meta variable: ' "  < <  name  < <  " '. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -256,7 +219,6 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // If a specific position was requested, we compute it now.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            boost : : optional < uint_fast64_t >  level ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( position )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_THROW ( this - > supportsOrderedInsertion ( ) ,  storm : : exceptions : : NotSupportedException ,  " Cannot add meta variable at position, because the manager does not support ordered insertion. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : dd : : DdMetaVariable < LibraryType >  beforeVariable  =  this - > getMetaVariable ( position . get ( ) . second ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                level  =  position . get ( ) . first  = =  MetaVariablePosition : : Above  ?  std : : numeric_limits < uint_fast64_t > : : max ( )  :  std : : numeric_limits < uint_fast64_t > : : min ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( auto  const &  ddVariable  :  beforeVariable . getDdVariables ( ) )  {  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -267,27 +229,45 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_TRACE ( " Creating meta variable with  "  < <  numberOfDdVariables  < <  "  bit(s) and  "  < <  numberOfLayers  < <  "  layer(s). " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : stringstream  tmp1 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < storm : : expressions : : Variable >  result ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( uint64  layer  =  0 ;  layer  <  numberOfLayers ;  + + layer )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                result . emplace_back ( manager - > declareBooleanVariable ( name  +  tmp1 . str ( ) ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( type  = =  MetaVariableType : : Int )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    result . emplace_back ( manager - > declareIntegerVariable ( name  +  tmp1 . str ( ) ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  else  if  ( type  = =  MetaVariableType : : Bool )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    result . emplace_back ( manager - > declareBooleanVariable ( name  +  tmp1 . str ( ) ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  else  if  ( type  = =  MetaVariableType : : BitVector )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    result . emplace_back ( manager - > declareBitVectorVariable ( name  +  tmp1 . str ( ) ,  numberOfDdVariables ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                tmp1  < <  " ' " ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < std : : vector < Bdd < LibraryType > > >  variables ( numberOfLayers ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < InternalBdd < LibraryType > >  ddVariables  =  internalDdManager . createDdVariables ( numberOfLayers ,  level ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( uint64_t  layer  =  0 ;  layer  <  numberOfLayers ;  + + layer )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                variables [ layer ] . emplace_back ( Bdd < LibraryType > ( * this ,  ddVariables [ layer ] ,  { result [ layer ] } ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( std : : size_t  i  =  0 ;  i  <  numberOfDdVariables ;  + + i )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : vector < InternalBdd < LibraryType > >  ddVariables  =  internalDdManager . createDdVariables ( numberOfLayers ,  level ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( uint64  layer  =  0 ;  layer  <  numberOfLayers ;  + + layer )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    variables [ layer ] . emplace_back ( Bdd < LibraryType > ( * this ,  ddVariables [ layer ] ,  { result [ layer ] } ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // If we are inserting the variable at a specific level, we need to prepare the level for the next pair
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // of variables.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( level )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    level . get ( )  + =  numberOfLayers ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : stringstream  tmp2 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( uint64_t  layer  =  0 ;  layer  <  numberOfLayers ;  + + layer )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                metaVariableMap . emplace ( result [ layer ] ,  DdMetaVariable < LibraryType > ( name  +  tmp2 . str ( ) ,  variables [ layer ] ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( bounds )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    metaVariableMap . emplace ( result [ layer ] ,  DdMetaVariable < LibraryType > ( name  +  tmp2 . str ( ) ,  bounds . get ( ) . first ,  bounds . get ( ) . second ,  variables [ layer ] ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    metaVariableMap . emplace ( result [ layer ] ,  DdMetaVariable < LibraryType > ( type ,  name  +  tmp2 . str ( ) ,  variables [ layer ] ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                tmp2  < <  " ' " ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					              
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  result ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }