@ -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,24 +229,42 @@ 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 ) ;
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 ] } ) ) ;
}
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 ] } ) ) ;
// 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 < < " ' " ;
}