@ -787,63 +787,79 @@ namespace storm {
}
Program Program : : substituteConstants ( ) const {
return substituteConstantsFormulas ( true , false ) ;
}
Program Program : : substituteFormulas ( ) const {
return substituteConstantsFormulas ( false , true ) ;
}
Program Program : : substituteConstantsFormulas ( bool substituteConstants , bool substituteFormulas ) const {
// We start by creating the appropriate substitution.
std : : map < storm : : expressions : : Variable , storm : : expressions : : Expression > constantSubstitution ;
std : : vector < Constant > newConstants ( this - > getConstants ( ) ) ;
for ( uint_fast64_t constantIndex = 0 ; constantIndex < newConstants . size ( ) ; + + constantIndex ) {
auto const & constant = newConstants [ constantIndex ] ;
std : : map < storm : : expressions : : Variable , storm : : expressions : : Expression > substitution ;
// Put the corresponding expression in the substitution.
if ( constant . isDefined ( ) ) {
constantSubstitution . emplace ( constant . getExpressionVariable ( ) , constant . getExpression ( ) . simplify ( ) ) ;
// Start with substituting constants. In a sane model, constant definitions do not contain formulas.
std : : vector < Constant > newConstants ;
newConstants . reserve ( this - > getNumberOfConstants ( ) ) ;
for ( auto const & oldConstant : this - > getConstants ( ) ) {
// apply the substitutions gathered so far to the constant definition *before* adding it to the substitution.
newConstants . push_back ( oldConstant . substitute ( substitution ) ) ;
// If there is at least one more constant to come, we substitute the constants we have so far.
if ( constantIndex + 1 < newConstants . size ( ) ) {
newConstants [ constantIndex + 1 ] = newConstants [ constantIndex + 1 ] . substitute ( constantSubstitution ) ;
// Put the corresponding expression in the substitution (if requested).
auto const & constant = newConstants . back ( ) ;
if ( substituteConstants & & constant . isDefined ( ) ) {
substitution . emplace ( constant . getExpressionVariable ( ) , constant . getExpression ( ) . simplify ( ) ) ;
}
}
// Secondly, handle the formulas. These might contain constants
std : : vector < Formula > newFormulas ;
newFormulas . reserve ( this - > getNumberOfFormulas ( ) ) ;
for ( auto const & oldFormula : this - > getFormulas ( ) ) {
// apply the currently gathered substitutions on the formula definition *before* adding it to the substitution.
newFormulas . emplace_back ( oldFormula . substitute ( substitution ) ) ;
// Put the corresponding expression in the substitution (if requested).
auto const & formula = newFormulas . back ( ) ;
if ( substituteFormulas ) {
substitution . emplace ( formula . getExpressionVariable ( ) , formula . getExpression ( ) . simplify ( ) ) ;
}
}
// Now we can substitute the constants in all expressions appearing in the program.
// Now we can substitute the constants/formulas in all expressions appearing in the program.
std : : vector < BooleanVariable > newBooleanVariables ;
newBooleanVariables . reserve ( this - > getNumberOfGlobalBooleanVariables ( ) ) ;
for ( auto const & booleanVariable : this - > getGlobalBooleanVariables ( ) ) {
newBooleanVariables . emplace_back ( booleanVariable . substitute ( constantSubstitution ) ) ;
newBooleanVariables . emplace_back ( booleanVariable . substitute ( substitution ) ) ;
}
std : : vector < IntegerVariable > newIntegerVariables ;
newBooleanVariables . reserve ( this - > getNumberOfGlobalIntegerVariables ( ) ) ;
for ( auto const & integerVariable : this - > getGlobalIntegerVariables ( ) ) {
newIntegerVariables . emplace_back ( integerVariable . substitute ( constantSubstitution ) ) ;
}
std : : vector < Formula > newFormulas ;
newFormulas . reserve ( this - > getNumberOfFormulas ( ) ) ;
for ( auto const & formula : this - > getFormulas ( ) ) {
newFormulas . emplace_back ( formula . substitute ( constantSubstitution ) ) ;
newIntegerVariables . emplace_back ( integerVariable . substitute ( substitution ) ) ;
}
std : : vector < Module > newModules ;
newModules . reserve ( this - > getNumberOfModules ( ) ) ;
for ( auto const & module : this - > getModules ( ) ) {
newModules . emplace_back ( module . substitute ( con stantS ubstitution) ) ;
newModules . emplace_back ( module . substitute ( substitution ) ) ;
}
std : : vector < RewardModel > newRewardModels ;
newRewardModels . reserve ( this - > getNumberOfRewardModels ( ) ) ;
for ( auto const & rewardModel : this - > getRewardModels ( ) ) {
newRewardModels . emplace_back ( rewardModel . substitute ( con stantS ubstitution) ) ;
newRewardModels . emplace_back ( rewardModel . substitute ( substitution ) ) ;
}
boost : : optional < storm : : prism : : InitialConstruct > newInitialConstruct ;
if ( this - > hasInitialConstruct ( ) ) {
newInitialConstruct = this - > getInitialConstruct ( ) . substitute ( con stantS ubstitution) ;
newInitialConstruct = this - > getInitialConstruct ( ) . substitute ( substitution ) ;
}
std : : vector < Label > newLabels ;
newLabels . reserve ( this - > getNumberOfLabels ( ) ) ;
for ( auto const & label : this - > getLabels ( ) ) {
newLabels . emplace_back ( label . substitute ( con stantS ubstitution) ) ;
newLabels . emplace_back ( label . substitute ( substitution ) ) ;
}
return Program ( this - > manager , this - > getModelType ( ) , newConstants , newBooleanVariables , newIntegerVariables , newFormulas , newModules , this - > getActionNameToIndexMapping ( ) , newRewardModels , newLabels , newInitialConstruct , this - > getOptionalSystemCompositionConstruct ( ) , prismCompatibility ) ;