@ -9,6 +9,7 @@
# include "storm/utility/macros.h"
# include "storm/utility/macros.h"
# include "storm/utility/constants.h"
# include "storm/utility/constants.h"
# include "storm/utility/file.h"
# include "storm/storage/expressions/Expression.h"
# include "storm/storage/expressions/Expression.h"
# include "storm/storage/expressions/ExpressionManager.h"
# include "storm/storage/expressions/ExpressionManager.h"
@ -31,7 +32,6 @@ namespace storm {
context = std : : unique_ptr < z3 : : context > ( new z3 : : context ( config ) ) ;
context = std : : unique_ptr < z3 : : context > ( new z3 : : context ( config ) ) ;
solver = std : : unique_ptr < z3 : : optimize > ( new z3 : : optimize ( * context ) ) ;
solver = std : : unique_ptr < z3 : : optimize > ( new z3 : : optimize ( * context ) ) ;
expressionAdapter = std : : unique_ptr < storm : : adapters : : Z3ExpressionAdapter > ( new storm : : adapters : : Z3ExpressionAdapter ( * this - > manager , * context ) ) ;
expressionAdapter = std : : unique_ptr < storm : : adapters : : Z3ExpressionAdapter > ( new storm : : adapters : : Z3ExpressionAdapter ( * this - > manager , * context ) ) ;
optimizationFunction = this - > getManager ( ) . rational ( storm : : utility : : zero < storm : : RationalNumber > ( ) ) ;
}
}
template < typename ValueType >
template < typename ValueType >
@ -71,7 +71,9 @@ namespace storm {
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getRationalType ( ) ) ;
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getRationalType ( ) ) ;
}
}
solver - > add ( expressionAdapter - > translateExpression ( ( newVariable . getExpression ( ) > = this - > manager - > rational ( lowerBound ) ) & & ( newVariable . getExpression ( ) < = this - > manager - > rational ( upperBound ) ) ) ) ;
solver - > add ( expressionAdapter - > translateExpression ( ( newVariable . getExpression ( ) > = this - > manager - > rational ( lowerBound ) ) & & ( newVariable . getExpression ( ) < = this - > manager - > rational ( upperBound ) ) ) ) ;
optimizationFunction = optimizationFunction + this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ;
if ( ! storm : : utility : : isZero ( objectiveFunctionCoefficient ) ) {
optimizationSummands . push_back ( this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ) ;
}
return newVariable ;
return newVariable ;
}
}
@ -84,7 +86,9 @@ namespace storm {
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getRationalType ( ) ) ;
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getRationalType ( ) ) ;
}
}
solver - > add ( expressionAdapter - > translateExpression ( newVariable . getExpression ( ) > = this - > manager - > rational ( lowerBound ) ) ) ;
solver - > add ( expressionAdapter - > translateExpression ( newVariable . getExpression ( ) > = this - > manager - > rational ( lowerBound ) ) ) ;
optimizationFunction = optimizationFunction + this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ;
if ( ! storm : : utility : : isZero ( objectiveFunctionCoefficient ) ) {
optimizationSummands . push_back ( this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ) ;
}
return newVariable ;
return newVariable ;
}
}
@ -97,7 +101,9 @@ namespace storm {
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getRationalType ( ) ) ;
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getRationalType ( ) ) ;
}
}
solver - > add ( expressionAdapter - > translateExpression ( newVariable . getExpression ( ) < = this - > manager - > rational ( upperBound ) ) ) ;
solver - > add ( expressionAdapter - > translateExpression ( newVariable . getExpression ( ) < = this - > manager - > rational ( upperBound ) ) ) ;
optimizationFunction = optimizationFunction + this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ;
if ( ! storm : : utility : : isZero ( objectiveFunctionCoefficient ) ) {
optimizationSummands . push_back ( this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ) ;
}
return newVariable ;
return newVariable ;
}
}
@ -109,7 +115,9 @@ namespace storm {
} else {
} else {
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getRationalType ( ) ) ;
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getRationalType ( ) ) ;
}
}
optimizationFunction = optimizationFunction + this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ;
if ( ! storm : : utility : : isZero ( objectiveFunctionCoefficient ) ) {
optimizationSummands . push_back ( this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ) ;
}
return newVariable ;
return newVariable ;
}
}
@ -122,7 +130,9 @@ namespace storm {
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getIntegerType ( ) ) ;
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getIntegerType ( ) ) ;
}
}
solver - > add ( expressionAdapter - > translateExpression ( ( newVariable . getExpression ( ) > = this - > manager - > rational ( lowerBound ) ) & & ( newVariable . getExpression ( ) < = this - > manager - > rational ( upperBound ) ) ) ) ;
solver - > add ( expressionAdapter - > translateExpression ( ( newVariable . getExpression ( ) > = this - > manager - > rational ( lowerBound ) ) & & ( newVariable . getExpression ( ) < = this - > manager - > rational ( upperBound ) ) ) ) ;
optimizationFunction = optimizationFunction + this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ;
if ( ! storm : : utility : : isZero ( objectiveFunctionCoefficient ) ) {
optimizationSummands . push_back ( this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ) ;
}
return newVariable ;
return newVariable ;
}
}
@ -135,7 +145,9 @@ namespace storm {
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getIntegerType ( ) ) ;
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getIntegerType ( ) ) ;
}
}
solver - > add ( expressionAdapter - > translateExpression ( newVariable . getExpression ( ) > = this - > manager - > rational ( lowerBound ) ) ) ;
solver - > add ( expressionAdapter - > translateExpression ( newVariable . getExpression ( ) > = this - > manager - > rational ( lowerBound ) ) ) ;
optimizationFunction = optimizationFunction + this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ;
if ( ! storm : : utility : : isZero ( objectiveFunctionCoefficient ) ) {
optimizationSummands . push_back ( this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ) ;
}
return newVariable ;
return newVariable ;
}
}
@ -148,7 +160,9 @@ namespace storm {
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getIntegerType ( ) ) ;
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getIntegerType ( ) ) ;
}
}
solver - > add ( expressionAdapter - > translateExpression ( newVariable . getExpression ( ) < = this - > manager - > rational ( upperBound ) ) ) ;
solver - > add ( expressionAdapter - > translateExpression ( newVariable . getExpression ( ) < = this - > manager - > rational ( upperBound ) ) ) ;
optimizationFunction = optimizationFunction + this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ;
if ( ! storm : : utility : : isZero ( objectiveFunctionCoefficient ) ) {
optimizationSummands . push_back ( this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ) ;
}
return newVariable ;
return newVariable ;
}
}
@ -160,7 +174,9 @@ namespace storm {
} else {
} else {
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getIntegerType ( ) ) ;
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getIntegerType ( ) ) ;
}
}
optimizationFunction = optimizationFunction + this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ;
if ( ! storm : : utility : : isZero ( objectiveFunctionCoefficient ) ) {
optimizationSummands . push_back ( this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ) ;
}
return newVariable ;
return newVariable ;
}
}
@ -173,7 +189,9 @@ namespace storm {
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getIntegerType ( ) ) ;
newVariable = this - > manager - > declareVariable ( name , this - > manager - > getIntegerType ( ) ) ;
}
}
solver - > add ( expressionAdapter - > translateExpression ( ( newVariable . getExpression ( ) > = this - > manager - > rational ( storm : : utility : : zero < storm : : RationalNumber > ( ) ) ) & & ( newVariable . getExpression ( ) < = this - > manager - > rational ( storm : : utility : : one < storm : : RationalNumber > ( ) ) ) ) ) ;
solver - > add ( expressionAdapter - > translateExpression ( ( newVariable . getExpression ( ) > = this - > manager - > rational ( storm : : utility : : zero < storm : : RationalNumber > ( ) ) ) & & ( newVariable . getExpression ( ) < = this - > manager - > rational ( storm : : utility : : one < storm : : RationalNumber > ( ) ) ) ) ) ;
optimizationFunction = optimizationFunction + this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ;
if ( ! storm : : utility : : isZero ( objectiveFunctionCoefficient ) ) {
optimizationSummands . push_back ( this - > manager - > rational ( objectiveFunctionCoefficient ) * newVariable ) ;
}
return newVariable ;
return newVariable ;
}
}
@ -193,6 +211,7 @@ namespace storm {
solver - > push ( ) ;
solver - > push ( ) ;
// Solve the optimization problem depending on the optimization direction
// Solve the optimization problem depending on the optimization direction
storm : : expressions : : Expression optimizationFunction = storm : : expressions : : sum ( optimizationSummands ) ;
z3 : : optimize : : handle optFuncHandle = this - > getOptimizationDirection ( ) = = OptimizationDirection : : Minimize ? solver - > minimize ( expressionAdapter - > translateExpression ( optimizationFunction ) ) : solver - > maximize ( expressionAdapter - > translateExpression ( optimizationFunction ) ) ;
z3 : : optimize : : handle optFuncHandle = this - > getOptimizationDirection ( ) = = OptimizationDirection : : Minimize ? solver - > minimize ( expressionAdapter - > translateExpression ( optimizationFunction ) ) : solver - > maximize ( expressionAdapter - > translateExpression ( optimizationFunction ) ) ;
z3 : : check_result chkRes = solver - > check ( ) ;
z3 : : check_result chkRes = solver - > check ( ) ;
STORM_LOG_THROW ( chkRes ! = z3 : : unknown , storm : : exceptions : : InvalidStateException , " Unable to solve LP problem with Z3: Check result is unknown. " ) ;
STORM_LOG_THROW ( chkRes ! = z3 : : unknown , storm : : exceptions : : InvalidStateException , " Unable to solve LP problem with Z3: Check result is unknown. " ) ;
@ -300,20 +319,40 @@ namespace storm {
template < typename ValueType >
template < typename ValueType >
void Z3LpSolver < ValueType > : : writeModelToFile ( std : : string const & filename ) const {
void Z3LpSolver < ValueType > : : writeModelToFile ( std : : string const & filename ) const {
std : : ofstream stream ;
storm : : utility : : openFile ( filename , stream ) ;
stream < < Z3_optimize_to_string ( * context , * solver ) ;
storm : : utility : : closeFile ( stream ) ;
STORM_LOG_THROW ( false , storm : : exceptions : : NotImplementedException , " Exporting LP Problems to a file is not implemented for z3. " ) ;
STORM_LOG_THROW ( false , storm : : exceptions : : NotImplementedException , " Exporting LP Problems to a file is not implemented for z3. " ) ;
}
}
template < typename ValueType >
template < typename ValueType >
void Z3LpSolver < ValueType > : : push ( ) {
void Z3LpSolver < ValueType > : : push ( ) {
incrementaOptimizationSummandIndicators . push_back ( optimizationSummands . size ( ) ) ;
solver - > push ( ) ;
solver - > push ( ) ;
}
}
template < typename ValueType >
template < typename ValueType >
void Z3LpSolver < ValueType > : : pop ( ) {
void Z3LpSolver < ValueType > : : pop ( ) {
STORM_LOG_ASSERT ( ! incrementaOptimizationSummandIndicators . empty ( ) , " Tried to pop() without push()ing first. " ) ;
solver - > pop ( ) ;
solver - > pop ( ) ;
// Delete summands of the optimization function that have been added since the last call to push()
optimizationSummands . resize ( incrementaOptimizationSummandIndicators . back ( ) ) ;
incrementaOptimizationSummandIndicators . pop_back ( ) ;
isIncremental = true ;
isIncremental = true ;
}
}
template < typename ValueType >
void Z3LpSolver < ValueType > : : setMaximalMILPGap ( ValueType const & , bool ) {
// Since the solver is always exact, setting a gap has no effect.
// Intentionally left empty.
}
template < typename ValueType >
ValueType Z3LpSolver < ValueType > : : getMILPGap ( bool relative ) const {
// Since the solver is precise, the milp gap is always zero.
return storm : : utility : : zero < ValueType > ( ) ;
}
# else
# else
template < typename ValueType >
template < typename ValueType >
Z3LpSolver < ValueType > : : Z3LpSolver ( std : : string const & , OptimizationDirection const & ) {
Z3LpSolver < ValueType > : : Z3LpSolver ( std : : string const & , OptimizationDirection const & ) {
@ -453,6 +492,16 @@ namespace storm {
void Z3LpSolver < ValueType > : : pop ( ) {
void Z3LpSolver < ValueType > : : pop ( ) {
throw storm : : exceptions : : NotImplementedException ( ) < < " This version of storm was compiled without Z3 or the version of Z3 does not support optimization. Yet, a method was called that requires this support. " ;
throw storm : : exceptions : : NotImplementedException ( ) < < " This version of storm was compiled without Z3 or the version of Z3 does not support optimization. Yet, a method was called that requires this support. " ;
}
}
template < typename ValueType >
void Z3LpSolver < ValueType > : : setMaximalMILPGap ( ValueType const & gap , bool relative ) {
throw storm : : exceptions : : NotImplementedException ( ) < < " This version of storm was compiled without Z3 or the version of Z3 does not support optimization. Yet, a method was called that requires this support. " ;
}
template < typename ValueType >
ValueType Z3LpSolver < ValueType > : : getMILPGap ( bool relative ) const {
throw storm : : exceptions : : NotImplementedException ( ) < < " This version of storm was compiled without Z3 or the version of Z3 does not support optimization. Yet, a method was called that requires this support. " ;
}
# endif
# endif
template class Z3LpSolver < double > ;
template class Z3LpSolver < double > ;