diff --git a/src/adapters/Z3ExpressionAdapter.cpp b/src/adapters/Z3ExpressionAdapter.cpp new file mode 100644 index 000000000..60b4e8e1c --- /dev/null +++ b/src/adapters/Z3ExpressionAdapter.cpp @@ -0,0 +1,288 @@ + +#include "Z3ExpressionAdapter.h" +#include "src/storage/expressions/Expressions.h" +#include "src/storage/expressions/ExpressionManager.h" +#include "src/utility/macros.h" +#include "src/exceptions/ExpressionEvaluationException.h" +#include "src/exceptions/InvalidTypeException.h" +#include "src/exceptions/NotImplementedException.h" +namespace storm { + namespace adapters { + +#ifdef STORM_HAVE_Z3 + Z3ExpressionAdapter::Z3ExpressionAdapter(storm::expressions::ExpressionManager& manager, z3::context& context) : manager(manager), context(context), additionalAssertions(), variableToExpressionMapping() { + // Intentionally left empty. + } + + z3::expr Z3ExpressionAdapter::translateExpression(storm::expressions::Expression const& expression) { + STORM_LOG_ASSERT(expression.getManager() == this->manager, "Invalid expression for solver."); + z3::expr result = boost::any_cast(expression.getBaseExpression().accept(*this)); + + for (z3::expr const& assertion : additionalAssertions) { + result = result && assertion; + } + additionalAssertions.clear(); + + return result; + } + + z3::expr Z3ExpressionAdapter::translateExpression(storm::expressions::Variable const& variable) { + STORM_LOG_ASSERT(variable.getManager() == this->manager, "Invalid expression for solver."); + + auto const& variableExpressionPair = variableToExpressionMapping.find(variable); + if (variableExpressionPair == variableToExpressionMapping.end()) { + return createVariable(variable); + } + + return variableExpressionPair->second; + } + + storm::expressions::Variable const& Z3ExpressionAdapter::getVariable(z3::func_decl z3Declaration) { + auto const& declarationVariablePair = declarationToVariableMapping.find(z3Declaration); + STORM_LOG_ASSERT(declarationVariablePair != declarationToVariableMapping.end(), "Unable to find declaration."); + return declarationVariablePair->second; + } + + storm::expressions::Expression Z3ExpressionAdapter::translateExpression(z3::expr const& expr) { + if (expr.is_app()) { + switch (expr.decl().decl_kind()) { + case Z3_OP_TRUE: + return manager.boolean(true); + case Z3_OP_FALSE: + return manager.boolean(false); + case Z3_OP_EQ: + return this->translateExpression(expr.arg(0)) == this->translateExpression(expr.arg(1)); + case Z3_OP_ITE: + return storm::expressions::ite(this->translateExpression(expr.arg(0)), this->translateExpression(expr.arg(1)), this->translateExpression(expr.arg(2))); + case Z3_OP_AND: { + unsigned args = expr.num_args(); + STORM_LOG_THROW(args != 0, storm::exceptions::ExpressionEvaluationException, "Failed to convert Z3 expression. 0-ary AND is assumed to be an error."); + if (args == 1) { + return this->translateExpression(expr.arg(0)); + } else { + storm::expressions::Expression retVal = this->translateExpression(expr.arg(0)); + for (unsigned i = 1; i < args; i++) { + retVal = retVal && this->translateExpression(expr.arg(i)); + } + return retVal; + } + } + case Z3_OP_OR: { + unsigned args = expr.num_args(); + STORM_LOG_THROW(args != 0, storm::exceptions::ExpressionEvaluationException, "Failed to convert Z3 expression. 0-ary OR is assumed to be an error."); + if (args == 1) { + return this->translateExpression(expr.arg(0)); + } else { + storm::expressions::Expression retVal = this->translateExpression(expr.arg(0)); + for (unsigned i = 1; i < args; i++) { + retVal = retVal || this->translateExpression(expr.arg(i)); + } + return retVal; + } + } + case Z3_OP_IFF: + return storm::expressions::iff(this->translateExpression(expr.arg(0)), this->translateExpression(expr.arg(1))); + case Z3_OP_XOR: + return this->translateExpression(expr.arg(0)) ^ this->translateExpression(expr.arg(1)); + case Z3_OP_NOT: + return !this->translateExpression(expr.arg(0)); + case Z3_OP_IMPLIES: + return storm::expressions::implies(this->translateExpression(expr.arg(0)), this->translateExpression(expr.arg(1))); + case Z3_OP_LE: + return this->translateExpression(expr.arg(0)) <= this->translateExpression(expr.arg(1)); + case Z3_OP_GE: + return this->translateExpression(expr.arg(0)) >= this->translateExpression(expr.arg(1)); + case Z3_OP_LT: + return this->translateExpression(expr.arg(0)) < this->translateExpression(expr.arg(1)); + case Z3_OP_GT: + return this->translateExpression(expr.arg(0)) > this->translateExpression(expr.arg(1)); + case Z3_OP_ADD: + return this->translateExpression(expr.arg(0)) + this->translateExpression(expr.arg(1)); + case Z3_OP_SUB: + return this->translateExpression(expr.arg(0)) - this->translateExpression(expr.arg(1)); + case Z3_OP_UMINUS: + return -this->translateExpression(expr.arg(0)); + case Z3_OP_MUL: + return this->translateExpression(expr.arg(0)) * this->translateExpression(expr.arg(1)); + case Z3_OP_DIV: + return this->translateExpression(expr.arg(0)) / this->translateExpression(expr.arg(1)); + case Z3_OP_IDIV: + return this->translateExpression(expr.arg(0)) / this->translateExpression(expr.arg(1)); + case Z3_OP_ANUM: + // Arithmetic numeral. + if (expr.is_int() && expr.is_const()) { + long long value; + if (Z3_get_numeral_int64(expr.ctx(), expr, &value)) { + return manager.integer(value); + } else { + STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Failed to convert Z3 expression. Expression is constant integer and value does not fit into 64-bit integer."); + } + } else if (expr.is_real() && expr.is_const()) { + long long num; + long long den; + if (Z3_get_numeral_rational_int64(expr.ctx(), expr, &num, &den)) { + return manager.rational(static_cast(num) / static_cast(den)); + } else { + STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Failed to convert Z3 expression. Expression is constant real and value does not fit into a fraction with 64-bit integer numerator and denominator."); + } + } + case Z3_OP_UNINTERPRETED: + // Currently, we only support uninterpreted constant functions. + STORM_LOG_THROW(expr.is_const(), storm::exceptions::ExpressionEvaluationException, "Failed to convert Z3 expression. Encountered non-constant uninterpreted function."); + return manager.getVariable(expr.decl().name().str()).getExpression(); + default: + STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Failed to convert Z3 expression. Encountered unhandled Z3_decl_kind " << expr.decl().kind() <<"."); + break; + } + } else { + STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Failed to convert Z3 expression. Encountered unknown expression type."); + } + } + + boost::any Z3ExpressionAdapter::visit(storm::expressions::BinaryBooleanFunctionExpression const& expression) { + z3::expr leftResult = boost::any_cast(expression.getFirstOperand()->accept(*this)); + z3::expr rightResult = boost::any_cast(expression.getSecondOperand()->accept(*this)); + + switch(expression.getOperatorType()) { + case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::And: + return leftResult && rightResult; + case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Or: + return leftResult || rightResult; + case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Xor: + return z3::expr(context, Z3_mk_xor(context, leftResult, rightResult)); + case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Implies: + return z3::expr(context, Z3_mk_implies(context, leftResult, rightResult)); + case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Iff: + return z3::expr(context, Z3_mk_iff(context, leftResult, rightResult)); + default: + STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Cannot evaluate expression: unknown boolean binary operator '" << static_cast(expression.getOperatorType()) << "' in expression " << expression << "."); + } + + } + + boost::any Z3ExpressionAdapter::visit(storm::expressions::BinaryNumericalFunctionExpression const& expression) { + z3::expr leftResult = boost::any_cast(expression.getFirstOperand()->accept(*this)); + z3::expr rightResult = boost::any_cast(expression.getSecondOperand()->accept(*this)); + + switch(expression.getOperatorType()) { + case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Plus: + return leftResult + rightResult; + case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Minus: + return leftResult - rightResult; + case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Times: + return leftResult * rightResult; + case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Divide: + return leftResult / rightResult; + case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Min: + return ite(leftResult <= rightResult, leftResult, rightResult); + case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Max: + return ite(leftResult >= rightResult, leftResult, rightResult); + default: + STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Cannot evaluate expression: unknown numerical binary operator '" << static_cast(expression.getOperatorType()) << "' in expression " << expression << "."); + } + } + + boost::any Z3ExpressionAdapter::visit(storm::expressions::BinaryRelationExpression const& expression) { + z3::expr leftResult = boost::any_cast(expression.getFirstOperand()->accept(*this)); + z3::expr rightResult = boost::any_cast(expression.getSecondOperand()->accept(*this)); + + switch(expression.getRelationType()) { + case storm::expressions::BinaryRelationExpression::RelationType::Equal: + return leftResult == rightResult; + case storm::expressions::BinaryRelationExpression::RelationType::NotEqual: + return leftResult != rightResult; + case storm::expressions::BinaryRelationExpression::RelationType::Less: + return leftResult < rightResult; + case storm::expressions::BinaryRelationExpression::RelationType::LessOrEqual: + return leftResult <= rightResult; + case storm::expressions::BinaryRelationExpression::RelationType::Greater: + return leftResult > rightResult; + case storm::expressions::BinaryRelationExpression::RelationType::GreaterOrEqual: + return leftResult >= rightResult; + default: + STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Cannot evaluate expression: unknown boolean binary operator '" << static_cast(expression.getRelationType()) << "' in expression " << expression << "."); + } + } + + boost::any Z3ExpressionAdapter::visit(storm::expressions::BooleanLiteralExpression const& expression) { + return context.bool_val(expression.getValue()); + } + + boost::any Z3ExpressionAdapter::visit(storm::expressions::DoubleLiteralExpression const& expression) { + std::stringstream fractionStream; + fractionStream << expression.getValue(); + return context.real_val(fractionStream.str().c_str()); + } + + boost::any Z3ExpressionAdapter::visit(storm::expressions::IntegerLiteralExpression const& expression) { + return context.int_val(static_cast(expression.getValue())); + } + + boost::any Z3ExpressionAdapter::visit(storm::expressions::UnaryBooleanFunctionExpression const& expression) { + z3::expr childResult = boost::any_cast(expression.getOperand()->accept(*this)); + + switch (expression.getOperatorType()) { + case storm::expressions::UnaryBooleanFunctionExpression::OperatorType::Not: + return !childResult; + default: + STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Cannot evaluate expression: unknown boolean binary operator '" << static_cast(expression.getOperatorType()) << "' in expression " << expression << "."); + } + } + + boost::any Z3ExpressionAdapter::visit(storm::expressions::UnaryNumericalFunctionExpression const& expression) { + z3::expr childResult = boost::any_cast(expression.getOperand()->accept(*this)); + + switch(expression.getOperatorType()) { + case storm::expressions::UnaryNumericalFunctionExpression::OperatorType::Minus: + return 0 - childResult; + case storm::expressions::UnaryNumericalFunctionExpression::OperatorType::Floor: { + storm::expressions::Variable freshAuxiliaryVariable = manager.declareFreshVariable(manager.getIntegerType(), true); + z3::expr floorVariable = context.int_const(freshAuxiliaryVariable.getName().c_str()); + additionalAssertions.push_back(z3::expr(context, Z3_mk_int2real(context, floorVariable)) <= childResult && childResult < (z3::expr(context, Z3_mk_int2real(context, floorVariable)) + 1)); + return floorVariable; + } + case storm::expressions::UnaryNumericalFunctionExpression::OperatorType::Ceil:{ + storm::expressions::Variable freshAuxiliaryVariable = manager.declareFreshVariable(manager.getIntegerType(), true); + z3::expr ceilVariable = context.int_const(freshAuxiliaryVariable.getName().c_str()); + additionalAssertions.push_back(z3::expr(context, Z3_mk_int2real(context, ceilVariable)) - 1 <= childResult && childResult < z3::expr(context, Z3_mk_int2real(context, ceilVariable))); + return ceilVariable; + } + default: STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Cannot evaluate expression: unknown numerical unary operator '" << static_cast(expression.getOperatorType()) << "'."); + } + } + + boost::any Z3ExpressionAdapter::visit(storm::expressions::IfThenElseExpression const& expression) { + z3::expr conditionResult = boost::any_cast(expression.getCondition()->accept(*this)); + z3::expr thenResult = boost::any_cast(expression.getThenExpression()->accept(*this)); + z3::expr elseResult = boost::any_cast(expression.getElseExpression()->accept(*this)); + return z3::expr(context, Z3_mk_ite(context, conditionResult, thenResult, elseResult)); + } + + boost::any Z3ExpressionAdapter::visit(storm::expressions::VariableExpression const& expression) { + return this->translateExpression(expression.getVariable()); + } + + + z3::expr Z3ExpressionAdapter::createVariable(storm::expressions::Variable const& variable) { + z3::expr z3Variable(context); + if (variable.getType().isBooleanType()) { + z3Variable = context.bool_const(variable.getName().c_str()); + } else if (variable.getType().isIntegerType()) { + z3Variable = context.int_const(variable.getName().c_str()); + } else if (variable.getType().isBitVectorType()) { + z3Variable = context.bv_const(variable.getName().c_str(), variable.getType().getWidth()); + } else if (variable.getType().isRationalType()) { + z3Variable = context.real_const(variable.getName().c_str()); + } else { + STORM_LOG_THROW(false, storm::exceptions::InvalidTypeException, "Encountered variable '" << variable.getName() << "' with unknown type while trying to create solver variables."); + } + variableToExpressionMapping.insert(std::make_pair(variable, z3Variable)); + declarationToVariableMapping.insert(std::make_pair(z3Variable.decl(), variable)); + return z3Variable; + } + + +#endif + } // namespace adapters +} // namespace storm + diff --git a/src/adapters/Z3ExpressionAdapter.h b/src/adapters/Z3ExpressionAdapter.h index 419bab938..70180a241 100644 --- a/src/adapters/Z3ExpressionAdapter.h +++ b/src/adapters/Z3ExpressionAdapter.h @@ -2,20 +2,17 @@ #define STORM_ADAPTERS_Z3EXPRESSIONADAPTER_H_ #include +#include +#include "storm-config.h" // Include the headers of Z3 only if it is available. #ifdef STORM_HAVE_Z3 #include "z3++.h" #include "z3.h" #endif -#include "storm-config.h" -#include "src/storage/expressions/Expressions.h" -#include "src/storage/expressions/ExpressionManager.h" -#include "src/utility/macros.h" -#include "src/exceptions/ExpressionEvaluationException.h" -#include "src/exceptions/InvalidTypeException.h" -#include "src/exceptions/NotImplementedException.h" +#include "src/storage/expressions/Variable.h" +#include "src/storage/expressions/ExpressionVisitor.h" namespace storm { namespace adapters { @@ -30,275 +27,51 @@ namespace storm { * @param context A reference to the Z3 context over which to build the expressions. The lifetime of the * context needs to be guaranteed as long as the instance of this adapter is used. */ - Z3ExpressionAdapter(storm::expressions::ExpressionManager& manager, z3::context& context) : manager(manager), context(context), additionalAssertions(), variableToExpressionMapping() { - // Intentionally left empty. - } - + Z3ExpressionAdapter(storm::expressions::ExpressionManager& manager, z3::context& context); /*! * Translates the given expression to an equivalent expression for Z3. * * @param expression The expression to translate. * @return An equivalent expression for Z3. */ - z3::expr translateExpression(storm::expressions::Expression const& expression) { - STORM_LOG_ASSERT(expression.getManager() == this->manager, "Invalid expression for solver."); - z3::expr result = boost::any_cast(expression.getBaseExpression().accept(*this)); - - for (z3::expr const& assertion : additionalAssertions) { - result = result && assertion; - } - additionalAssertions.clear(); - - return result; - } - + z3::expr translateExpression(storm::expressions::Expression const& expression); /*! * Translates the given variable to an equivalent expression for Z3. * * @param variable The variable to translate. * @return An equivalent expression for Z3. */ - z3::expr translateExpression(storm::expressions::Variable const& variable) { - STORM_LOG_ASSERT(variable.getManager() == this->manager, "Invalid expression for solver."); - - auto const& variableExpressionPair = variableToExpressionMapping.find(variable); - if (variableExpressionPair == variableToExpressionMapping.end()) { - return createVariable(variable); - } - - return variableExpressionPair->second; - } + z3::expr translateExpression(storm::expressions::Variable const& variable); + + storm::expressions::Expression translateExpression(z3::expr const& expr); /*! * Finds the counterpart to the given z3 variable declaration. * * @param z3Declaration The declaration for which to find the equivalent. * @return The equivalent counterpart. */ - storm::expressions::Variable const& getVariable(z3::func_decl z3Declaration) { - auto const& declarationVariablePair = declarationToVariableMapping.find(z3Declaration); - STORM_LOG_ASSERT(declarationVariablePair != declarationToVariableMapping.end(), "Unable to find declaration."); - return declarationVariablePair->second; - } - - storm::expressions::Expression translateExpression(z3::expr const& expr) { - if (expr.is_app()) { - switch (expr.decl().decl_kind()) { - case Z3_OP_TRUE: - return manager.boolean(true); - case Z3_OP_FALSE: - return manager.boolean(false); - case Z3_OP_EQ: - return this->translateExpression(expr.arg(0)) == this->translateExpression(expr.arg(1)); - case Z3_OP_ITE: - return storm::expressions::ite(this->translateExpression(expr.arg(0)), this->translateExpression(expr.arg(1)), this->translateExpression(expr.arg(2))); - case Z3_OP_AND: { - unsigned args = expr.num_args(); - STORM_LOG_THROW(args != 0, storm::exceptions::ExpressionEvaluationException, "Failed to convert Z3 expression. 0-ary AND is assumed to be an error."); - if (args == 1) { - return this->translateExpression(expr.arg(0)); - } else { - storm::expressions::Expression retVal = this->translateExpression(expr.arg(0)); - for (unsigned i = 1; i < args; i++) { - retVal = retVal && this->translateExpression(expr.arg(i)); - } - return retVal; - } - } - case Z3_OP_OR: { - unsigned args = expr.num_args(); - STORM_LOG_THROW(args != 0, storm::exceptions::ExpressionEvaluationException, "Failed to convert Z3 expression. 0-ary OR is assumed to be an error."); - if (args == 1) { - return this->translateExpression(expr.arg(0)); - } else { - storm::expressions::Expression retVal = this->translateExpression(expr.arg(0)); - for (unsigned i = 1; i < args; i++) { - retVal = retVal || this->translateExpression(expr.arg(i)); - } - return retVal; - } - } - case Z3_OP_IFF: - return storm::expressions::iff(this->translateExpression(expr.arg(0)), this->translateExpression(expr.arg(1))); - case Z3_OP_XOR: - return this->translateExpression(expr.arg(0)) ^ this->translateExpression(expr.arg(1)); - case Z3_OP_NOT: - return !this->translateExpression(expr.arg(0)); - case Z3_OP_IMPLIES: - return storm::expressions::implies(this->translateExpression(expr.arg(0)), this->translateExpression(expr.arg(1))); - case Z3_OP_LE: - return this->translateExpression(expr.arg(0)) <= this->translateExpression(expr.arg(1)); - case Z3_OP_GE: - return this->translateExpression(expr.arg(0)) >= this->translateExpression(expr.arg(1)); - case Z3_OP_LT: - return this->translateExpression(expr.arg(0)) < this->translateExpression(expr.arg(1)); - case Z3_OP_GT: - return this->translateExpression(expr.arg(0)) > this->translateExpression(expr.arg(1)); - case Z3_OP_ADD: - return this->translateExpression(expr.arg(0)) + this->translateExpression(expr.arg(1)); - case Z3_OP_SUB: - return this->translateExpression(expr.arg(0)) - this->translateExpression(expr.arg(1)); - case Z3_OP_UMINUS: - return -this->translateExpression(expr.arg(0)); - case Z3_OP_MUL: - return this->translateExpression(expr.arg(0)) * this->translateExpression(expr.arg(1)); - case Z3_OP_DIV: - return this->translateExpression(expr.arg(0)) / this->translateExpression(expr.arg(1)); - case Z3_OP_IDIV: - return this->translateExpression(expr.arg(0)) / this->translateExpression(expr.arg(1)); - case Z3_OP_ANUM: - // Arithmetic numeral. - if (expr.is_int() && expr.is_const()) { - long long value; - if (Z3_get_numeral_int64(expr.ctx(), expr, &value)) { - return manager.integer(value); - } else { - STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Failed to convert Z3 expression. Expression is constant integer and value does not fit into 64-bit integer."); - } - } else if (expr.is_real() && expr.is_const()) { - long long num; - long long den; - if (Z3_get_numeral_rational_int64(expr.ctx(), expr, &num, &den)) { - return manager.rational(static_cast(num) / static_cast(den)); - } else { - STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Failed to convert Z3 expression. Expression is constant real and value does not fit into a fraction with 64-bit integer numerator and denominator."); - } - } - case Z3_OP_UNINTERPRETED: - // Currently, we only support uninterpreted constant functions. - STORM_LOG_THROW(expr.is_const(), storm::exceptions::ExpressionEvaluationException, "Failed to convert Z3 expression. Encountered non-constant uninterpreted function."); - return manager.getVariable(expr.decl().name().str()).getExpression(); - default: - STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Failed to convert Z3 expression. Encountered unhandled Z3_decl_kind " << expr.decl().kind() <<"."); - break; - } - } else { - STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Failed to convert Z3 expression. Encountered unknown expression type."); - } - } + storm::expressions::Variable const& getVariable(z3::func_decl z3Declaration); - virtual boost::any visit(storm::expressions::BinaryBooleanFunctionExpression const& expression) override { - z3::expr leftResult = boost::any_cast(expression.getFirstOperand()->accept(*this)); - z3::expr rightResult = boost::any_cast(expression.getSecondOperand()->accept(*this)); - - switch(expression.getOperatorType()) { - case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::And: - return leftResult && rightResult; - case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Or: - return leftResult || rightResult; - case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Xor: - return z3::expr(context, Z3_mk_xor(context, leftResult, rightResult)); - case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Implies: - return z3::expr(context, Z3_mk_implies(context, leftResult, rightResult)); - case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Iff: - return z3::expr(context, Z3_mk_iff(context, leftResult, rightResult)); - default: - STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Cannot evaluate expression: unknown boolean binary operator '" << static_cast(expression.getOperatorType()) << "' in expression " << expression << "."); - } - - } + virtual boost::any visit(storm::expressions::BinaryBooleanFunctionExpression const& expression) override; - virtual boost::any visit(storm::expressions::BinaryNumericalFunctionExpression const& expression) override { - z3::expr leftResult = boost::any_cast(expression.getFirstOperand()->accept(*this)); - z3::expr rightResult = boost::any_cast(expression.getSecondOperand()->accept(*this)); - - switch(expression.getOperatorType()) { - case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Plus: - return leftResult + rightResult; - case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Minus: - return leftResult - rightResult; - case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Times: - return leftResult * rightResult; - case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Divide: - return leftResult / rightResult; - case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Min: - return ite(leftResult <= rightResult, leftResult, rightResult); - case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Max: - return ite(leftResult >= rightResult, leftResult, rightResult); - default: - STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Cannot evaluate expression: unknown numerical binary operator '" << static_cast(expression.getOperatorType()) << "' in expression " << expression << "."); - } - } + virtual boost::any visit(storm::expressions::BinaryNumericalFunctionExpression const& expression) override; - virtual boost::any visit(storm::expressions::BinaryRelationExpression const& expression) override { - z3::expr leftResult = boost::any_cast(expression.getFirstOperand()->accept(*this)); - z3::expr rightResult = boost::any_cast(expression.getSecondOperand()->accept(*this)); - - switch(expression.getRelationType()) { - case storm::expressions::BinaryRelationExpression::RelationType::Equal: - return leftResult == rightResult; - case storm::expressions::BinaryRelationExpression::RelationType::NotEqual: - return leftResult != rightResult; - case storm::expressions::BinaryRelationExpression::RelationType::Less: - return leftResult < rightResult; - case storm::expressions::BinaryRelationExpression::RelationType::LessOrEqual: - return leftResult <= rightResult; - case storm::expressions::BinaryRelationExpression::RelationType::Greater: - return leftResult > rightResult; - case storm::expressions::BinaryRelationExpression::RelationType::GreaterOrEqual: - return leftResult >= rightResult; - default: - STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Cannot evaluate expression: unknown boolean binary operator '" << static_cast(expression.getRelationType()) << "' in expression " << expression << "."); - } - } + virtual boost::any visit(storm::expressions::BinaryRelationExpression const& expression) override; - virtual boost::any visit(storm::expressions::BooleanLiteralExpression const& expression) override { - return context.bool_val(expression.getValue()); - } + virtual boost::any visit(storm::expressions::BooleanLiteralExpression const& expression) override; - virtual boost::any visit(storm::expressions::DoubleLiteralExpression const& expression) override { - std::stringstream fractionStream; - fractionStream << expression.getValue(); - return context.real_val(fractionStream.str().c_str()); - } + virtual boost::any visit(storm::expressions::DoubleLiteralExpression const& expression) override; - virtual boost::any visit(storm::expressions::IntegerLiteralExpression const& expression) override { - return context.int_val(static_cast(expression.getValue())); - } + virtual boost::any visit(storm::expressions::IntegerLiteralExpression const& expression) override; - virtual boost::any visit(storm::expressions::UnaryBooleanFunctionExpression const& expression) override { - z3::expr childResult = boost::any_cast(expression.getOperand()->accept(*this)); - - switch (expression.getOperatorType()) { - case storm::expressions::UnaryBooleanFunctionExpression::OperatorType::Not: - return !childResult; - default: - STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Cannot evaluate expression: unknown boolean binary operator '" << static_cast(expression.getOperatorType()) << "' in expression " << expression << "."); - } - } + virtual boost::any visit(storm::expressions::UnaryBooleanFunctionExpression const& expression) override; - virtual boost::any visit(storm::expressions::UnaryNumericalFunctionExpression const& expression) override { - z3::expr childResult = boost::any_cast(expression.getOperand()->accept(*this)); - - switch(expression.getOperatorType()) { - case storm::expressions::UnaryNumericalFunctionExpression::OperatorType::Minus: - return 0 - childResult; - case storm::expressions::UnaryNumericalFunctionExpression::OperatorType::Floor: { - storm::expressions::Variable freshAuxiliaryVariable = manager.declareFreshVariable(manager.getIntegerType(), true); - z3::expr floorVariable = context.int_const(freshAuxiliaryVariable.getName().c_str()); - additionalAssertions.push_back(z3::expr(context, Z3_mk_int2real(context, floorVariable)) <= childResult && childResult < (z3::expr(context, Z3_mk_int2real(context, floorVariable)) + 1)); - return floorVariable; - } - case storm::expressions::UnaryNumericalFunctionExpression::OperatorType::Ceil:{ - storm::expressions::Variable freshAuxiliaryVariable = manager.declareFreshVariable(manager.getIntegerType(), true); - z3::expr ceilVariable = context.int_const(freshAuxiliaryVariable.getName().c_str()); - additionalAssertions.push_back(z3::expr(context, Z3_mk_int2real(context, ceilVariable)) - 1 <= childResult && childResult < z3::expr(context, Z3_mk_int2real(context, ceilVariable))); - return ceilVariable; - } - default: STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Cannot evaluate expression: unknown numerical unary operator '" << static_cast(expression.getOperatorType()) << "'."); - } - } + virtual boost::any visit(storm::expressions::UnaryNumericalFunctionExpression const& expression) override; - virtual boost::any visit(storm::expressions::IfThenElseExpression const& expression) override { - z3::expr conditionResult = boost::any_cast(expression.getCondition()->accept(*this)); - z3::expr thenResult = boost::any_cast(expression.getThenExpression()->accept(*this)); - z3::expr elseResult = boost::any_cast(expression.getElseExpression()->accept(*this)); - return z3::expr(context, Z3_mk_ite(context, conditionResult, thenResult, elseResult)); - } + virtual boost::any visit(storm::expressions::IfThenElseExpression const& expression) override; - virtual boost::any visit(storm::expressions::VariableExpression const& expression) override { - return this->translateExpression(expression.getVariable()); - } + virtual boost::any visit(storm::expressions::VariableExpression const& expression) override; private: /*! @@ -306,25 +79,7 @@ namespace storm { * * @param variable The variable for which to create a Z3 counterpart. */ - z3::expr createVariable(storm::expressions::Variable const& variable) { - z3::expr z3Variable(context); - if (variable.getType().isBooleanType()) { - z3Variable = context.bool_const(variable.getName().c_str()); - } else if (variable.getType().isIntegerType()) { - z3Variable = context.int_const(variable.getName().c_str()); - } else if (variable.getType().isBitVectorType()) { - z3Variable = context.bv_const(variable.getName().c_str(), variable.getType().getWidth()); - } else if (variable.getType().isRationalType()) { - z3Variable = context.real_const(variable.getName().c_str()); - } else { - STORM_LOG_THROW(false, storm::exceptions::InvalidTypeException, "Encountered variable '" << variable.getName() << "' with unknown type while trying to create solver variables."); - } - variableToExpressionMapping.insert(std::make_pair(variable, z3Variable)); - declarationToVariableMapping.insert(std::make_pair(z3Variable.decl(), variable)); - return z3Variable; - } - - + z3::expr createVariable(storm::expressions::Variable const& variable); // The manager that can be used to build expressions. storm::expressions::ExpressionManager& manager; @@ -333,7 +88,7 @@ namespace storm { // A vector of assertions that need to be kept separate, because they were only implicitly part of an // assertion that was added. - std::vector additionalAssertions; + std::vector additionalAssertions; // A mapping from variables to their Z3 equivalent. std::unordered_map variableToExpressionMapping; diff --git a/src/models/sparse/Model.h b/src/models/sparse/Model.h index 4d1901d1f..83173ab63 100644 --- a/src/models/sparse/Model.h +++ b/src/models/sparse/Model.h @@ -11,6 +11,8 @@ #include "src/storage/BitVector.h" #include "src/storage/SparseMatrix.h" #include "src/utility/OsDetection.h" +// Forward declarations + namespace storm { namespace models { @@ -19,6 +21,7 @@ namespace storm { // The type used for storing a set of labels. typedef boost::container::flat_set LabelSet; + /*! * Base class for all sparse models. */ diff --git a/src/models/sparse/StateLabeling.cpp b/src/models/sparse/StateLabeling.cpp index e23fd7b4c..3f1504496 100644 --- a/src/models/sparse/StateLabeling.cpp +++ b/src/models/sparse/StateLabeling.cpp @@ -1,4 +1,8 @@ #include "src/models/sparse/StateLabeling.h" +#include "src/storage/BitVector.h" +#include "src/exceptions/OutOfRangeException.h" +#include "src/exceptions/InvalidArgumentException.h" + namespace storm { namespace models { diff --git a/src/models/sparse/StateLabeling.h b/src/models/sparse/StateLabeling.h index 072c8ed3d..c7b3411a7 100644 --- a/src/models/sparse/StateLabeling.h +++ b/src/models/sparse/StateLabeling.h @@ -6,17 +6,16 @@ #include #include "src/storage/sparse/StateType.h" -#include "src/storage/BitVector.h" -#include "src/exceptions/OutOfRangeException.h" -#include "src/exceptions/InvalidArgumentException.h" +#include "src/storage/BitVector.h" #include "src/utility/macros.h" #include "src/utility/OsDetection.h" + namespace storm { namespace models { namespace sparse { - + /*! * This class manages the labeling of the state space with a number of (atomic) labels. */ diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h index 8d6c10ac0..22510b4af 100644 --- a/src/parser/PrismParser.h +++ b/src/parser/PrismParser.h @@ -9,12 +9,17 @@ #include "src/parser/SpiritParserDefinitions.h" #include "src/parser/ExpressionParser.h" #include "src/storage/prism/Program.h" -#include "src/storage/expressions/ExpressionManager.h" #include "src/storage/expressions/Expression.h" #include "src/storage/expressions/Expressions.h" #include "src/utility/macros.h" #include "src/exceptions/WrongFormatException.h" +namespace storm { + namespace expressions { + class ExpressionManager; + } +} + namespace storm { namespace parser { // A class that stores information about the parsed program. diff --git a/src/solver/GlpkLpSolver.cpp b/src/solver/GlpkLpSolver.cpp index d88fdb407..fd36a0bff 100644 --- a/src/solver/GlpkLpSolver.cpp +++ b/src/solver/GlpkLpSolver.cpp @@ -8,6 +8,9 @@ #include "src/settings/SettingsManager.h" #include "src/utility/macros.h" +#include "src/storage/expressions/Expression.h" +#include "src/storage/expressions/ExpressionManager.h" + #include "src/exceptions/InvalidAccessException.h" #include "src/exceptions/InvalidStateException.h" diff --git a/src/solver/GlpkLpSolver.h b/src/solver/GlpkLpSolver.h index 130d59a9b..4717b5d97 100644 --- a/src/solver/GlpkLpSolver.h +++ b/src/solver/GlpkLpSolver.h @@ -1,6 +1,7 @@ #ifndef STORM_SOLVER_GLPKLPSOLVER_H_ #define STORM_SOLVER_GLPKLPSOLVER_H_ +#include #include "src/solver/LpSolver.h" #include "src/exceptions/NotImplementedException.h" diff --git a/src/solver/GurobiLpSolver.cpp b/src/solver/GurobiLpSolver.cpp index 50e36b809..b6c0202f7 100644 --- a/src/solver/GurobiLpSolver.cpp +++ b/src/solver/GurobiLpSolver.cpp @@ -7,6 +7,9 @@ #include "src/settings/SettingsManager.h" #include "src/utility/macros.h" +#include "src/storage/expressions/Expression.h" +#include "src/storage/expressions/ExpressionManager.h" + #include "src/exceptions/InvalidStateException.h" #include "src/exceptions/InvalidAccessException.h" diff --git a/src/solver/GurobiLpSolver.h b/src/solver/GurobiLpSolver.h index 21e4e9e53..186715922 100644 --- a/src/solver/GurobiLpSolver.h +++ b/src/solver/GurobiLpSolver.h @@ -1,6 +1,7 @@ #ifndef STORM_SOLVER_GUROBILPSOLVER #define STORM_SOLVER_GUROBILPSOLVER +#include #include "src/solver/LpSolver.h" #include "src/exceptions/NotImplementedException.h" diff --git a/src/solver/LpSolver.cpp b/src/solver/LpSolver.cpp new file mode 100644 index 000000000..29840ac85 --- /dev/null +++ b/src/solver/LpSolver.cpp @@ -0,0 +1,23 @@ + +#include "LpSolver.h" + +#include "src/storage/expressions/Expression.h" +#include "src/storage/expressions/ExpressionManager.h" + + + +namespace storm { + namespace solver { + LpSolver::LpSolver() : manager(new storm::expressions::ExpressionManager()), currentModelHasBeenOptimized(false), modelSense(ModelSense::Minimize) { + // Intentionally left empty. + } + + LpSolver::LpSolver(ModelSense const& modelSense) : manager(new storm::expressions::ExpressionManager()), currentModelHasBeenOptimized(false), modelSense(modelSense) { + // Intentionally left empty. + } + + storm::expressions::Expression LpSolver::getConstant(double value) const { + return manager->rational(value); + } + } +} \ No newline at end of file diff --git a/src/solver/LpSolver.h b/src/solver/LpSolver.h index 50a1be39e..2ea06af2c 100644 --- a/src/solver/LpSolver.h +++ b/src/solver/LpSolver.h @@ -4,11 +4,13 @@ #include #include #include - -#include "src/storage/expressions/Expression.h" -#include "src/storage/expressions/ExpressionManager.h" - namespace storm { + namespace expressions { + class ExpressionManager; + class Variable; + class Expression; + } + namespace solver { /*! * An interface that captures the functionality of an LP solver. @@ -24,19 +26,14 @@ namespace storm { /*! * Creates an empty LP solver. By default the objective function is assumed to be minimized. */ - LpSolver() : manager(new storm::expressions::ExpressionManager()), currentModelHasBeenOptimized(false), modelSense(ModelSense::Minimize) { - // Intentionally left empty. - } - + LpSolver(); /*! * Creates an empty LP solver with the given model sense. * * @param modelSense A value indicating whether the objective function of this model is to be minimized or * maximized. */ - LpSolver(ModelSense const& modelSense) : manager(new storm::expressions::ExpressionManager()), currentModelHasBeenOptimized(false), modelSense(modelSense) { - // Intentionally left empty. - } + LpSolver(ModelSense const& modelSense); /*! * Registers an upper- and lower-bounded continuous variable, i.e. a variable that may take all real values @@ -139,9 +136,7 @@ namespace storm { * @param value The value of the constant. * @return The resulting expression. */ - storm::expressions::Expression getConstant(double value) const { - return manager->rational(value); - } + storm::expressions::Expression getConstant(double value) const; /*! * Updates the model to make the variables that have been declared since the last call to update diff --git a/src/solver/SymbolicGameSolver.h b/src/solver/SymbolicGameSolver.h index ff5d64056..6abebee54 100644 --- a/src/solver/SymbolicGameSolver.h +++ b/src/solver/SymbolicGameSolver.h @@ -1,6 +1,8 @@ #ifndef STORM_SOLVER_SYMBOLICGAMESOLVER_H_ #define STORM_SOLVER_SYMBOLICGAMESOLVER_H_ +#include +#include #include "src/storage/expressions/Variable.h" #include "src/storage/dd/Bdd.h" diff --git a/src/solver/SymbolicLinearEquationSolver.h b/src/solver/SymbolicLinearEquationSolver.h index 6cd437673..7defb0b79 100644 --- a/src/solver/SymbolicLinearEquationSolver.h +++ b/src/solver/SymbolicLinearEquationSolver.h @@ -3,6 +3,7 @@ #include #include +#include #include #include "src/storage/expressions/Variable.h" diff --git a/src/solver/Z3SmtSolver.cpp b/src/solver/Z3SmtSolver.cpp index 082ab3c28..fed950c2a 100644 --- a/src/solver/Z3SmtSolver.cpp +++ b/src/solver/Z3SmtSolver.cpp @@ -2,6 +2,7 @@ #include "src/utility/macros.h" #include "src/exceptions/NotSupportedException.h" #include "src/exceptions/InvalidStateException.h" +#include "src/exceptions/InvalidArgumentException.h" namespace storm { namespace solver { diff --git a/src/solver/Z3SmtSolver.h b/src/solver/Z3SmtSolver.h index f00f67b89..00dc8d434 100644 --- a/src/solver/Z3SmtSolver.h +++ b/src/solver/Z3SmtSolver.h @@ -46,7 +46,7 @@ namespace storm { virtual void reset() override; virtual void add(storm::expressions::Expression const& assertion) override; - + virtual CheckResult check() override; virtual CheckResult checkWithAssumptions(std::set const& assumptions) override; @@ -57,7 +57,7 @@ namespace storm { virtual storm::expressions::SimpleValuation getModelAsValuation() override; - virtual std::shared_ptr getModel() override; + virtual std::shared_ptr getModel() override; virtual std::vector allSat(std::vector const& important) override; diff --git a/src/storage/dd/CuddDdForwardIterator.cpp b/src/storage/dd/CuddDdForwardIterator.cpp index 07b0a7e59..170bb5f54 100644 --- a/src/storage/dd/CuddDdForwardIterator.cpp +++ b/src/storage/dd/CuddDdForwardIterator.cpp @@ -2,6 +2,7 @@ #include "src/storage/dd/CuddDdManager.h" #include "src/storage/dd/DdMetaVariable.h" #include "src/utility/macros.h" +#include "src/storage/expressions/ExpressionManager.h" namespace storm { namespace dd { diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp index d7adf1a6c..d84f3e602 100644 --- a/src/storage/dd/CuddDdManager.cpp +++ b/src/storage/dd/CuddDdManager.cpp @@ -6,6 +6,7 @@ #include "src/utility/macros.h" #include "src/exceptions/InvalidArgumentException.h" #include "src/settings/SettingsManager.h" +#include "src/storage/expressions/ExpressionManager.h" namespace storm { namespace dd { diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h index 522be1fba..5bf1c3080 100644 --- a/src/storage/dd/CuddDdManager.h +++ b/src/storage/dd/CuddDdManager.h @@ -6,13 +6,18 @@ #include "src/storage/dd/DdManager.h" #include "src/storage/dd/CuddDdMetaVariable.h" -#include "src/storage/expressions/ExpressionManager.h" #include "src/storage/expressions/Variable.h" #include "src/utility/OsDetection.h" // Include the C++-interface of CUDD. #include "cuddObj.hh" +namespace storm { + namespace expressions { + class Variable; + } +} + namespace storm { namespace dd { template<> diff --git a/src/storage/dd/CuddDdMetaVariable.h b/src/storage/dd/CuddDdMetaVariable.h index 4f016a6ce..fea461229 100644 --- a/src/storage/dd/CuddDdMetaVariable.h +++ b/src/storage/dd/CuddDdMetaVariable.h @@ -11,7 +11,7 @@ #include "src/storage/dd/CuddAdd.h" #include "src/storage/dd/DdMetaVariable.h" #include "src/storage/dd/CuddDdForwardIterator.h" -#include "src/storage/expressions/Expression.h" + namespace storm { namespace dd { diff --git a/src/storage/expressions/BaseExpression.h b/src/storage/expressions/BaseExpression.h index 0a853c1eb..f9b2792f4 100644 --- a/src/storage/expressions/BaseExpression.h +++ b/src/storage/expressions/BaseExpression.h @@ -8,18 +8,17 @@ #include #include "src/storage/expressions/Type.h" -#include "src/storage/expressions/Valuation.h" -#include "src/storage/expressions/ExpressionVisitor.h" -#include "src/storage/expressions/OperatorType.h" -#include "src/exceptions/InvalidArgumentException.h" #include "src/utility/OsDetection.h" +#include namespace storm { namespace expressions { // Forward-declare expression manager. class ExpressionManager; class Variable; - + class Valuation; + class ExpressionVisitor; + enum struct OperatorType; /*! * The base class of all expression classes. */ diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp index 68a643329..6cb550609 100644 --- a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp +++ b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp @@ -1,6 +1,7 @@ #include "src/storage/expressions/BinaryBooleanFunctionExpression.h" #include "src/storage/expressions/BooleanLiteralExpression.h" #include "src/storage/expressions/ExpressionManager.h" +#include "src/storage/expressions/ExpressionVisitor.h" #include "src/utility/macros.h" #include "src/exceptions/InvalidTypeException.h" diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp index de02d793b..95a326de1 100644 --- a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp +++ b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp @@ -4,10 +4,12 @@ #include "src/storage/expressions/BinaryNumericalFunctionExpression.h" #include "src/storage/expressions/IntegerLiteralExpression.h" #include "src/storage/expressions/DoubleLiteralExpression.h" +#include "src/storage/expressions/ExpressionVisitor.h" #include "src/utility/macros.h" #include "src/exceptions/InvalidTypeException.h" #include "src/exceptions/InvalidStateException.h" + namespace storm { namespace expressions { BinaryNumericalFunctionExpression::BinaryNumericalFunctionExpression(ExpressionManager const& manager, Type const& type, std::shared_ptr const& firstOperand, std::shared_ptr const& secondOperand, OperatorType operatorType) : BinaryExpression(manager, type, firstOperand, secondOperand), operatorType(operatorType) { diff --git a/src/storage/expressions/BinaryRelationExpression.cpp b/src/storage/expressions/BinaryRelationExpression.cpp index e6022380e..858536d0c 100644 --- a/src/storage/expressions/BinaryRelationExpression.cpp +++ b/src/storage/expressions/BinaryRelationExpression.cpp @@ -5,6 +5,7 @@ #include "src/storage/expressions/BooleanLiteralExpression.h" #include "src/utility/macros.h" #include "src/exceptions/InvalidTypeException.h" +#include "src/storage/expressions/ExpressionVisitor.h" namespace storm { namespace expressions { diff --git a/src/storage/expressions/BooleanLiteralExpression.cpp b/src/storage/expressions/BooleanLiteralExpression.cpp index 9847e4bb3..9e4986b04 100644 --- a/src/storage/expressions/BooleanLiteralExpression.cpp +++ b/src/storage/expressions/BooleanLiteralExpression.cpp @@ -1,5 +1,6 @@ #include "src/storage/expressions/BooleanLiteralExpression.h" #include "src/storage/expressions/ExpressionManager.h" +#include "src/storage/expressions/ExpressionVisitor.h" namespace storm { namespace expressions { diff --git a/src/storage/expressions/DoubleLiteralExpression.cpp b/src/storage/expressions/DoubleLiteralExpression.cpp index be878f0b2..cab9fc31b 100644 --- a/src/storage/expressions/DoubleLiteralExpression.cpp +++ b/src/storage/expressions/DoubleLiteralExpression.cpp @@ -1,5 +1,6 @@ #include "src/storage/expressions/DoubleLiteralExpression.h" #include "src/storage/expressions/ExpressionManager.h" +#include "src/storage/expressions/ExpressionVisitor.h" namespace storm { namespace expressions { diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp index 630e17a8a..ec723eedf 100644 --- a/src/storage/expressions/Expression.cpp +++ b/src/storage/expressions/Expression.cpp @@ -7,6 +7,7 @@ #include "src/storage/expressions/LinearityCheckVisitor.h" #include "src/storage/expressions/Expressions.h" #include "src/exceptions/InvalidTypeException.h" +#include "src/exceptions/InvalidArgumentException.h" #include "src/utility/macros.h" namespace storm { diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h index afc04bf56..285a508b2 100644 --- a/src/storage/expressions/Expression.h +++ b/src/storage/expressions/Expression.h @@ -5,9 +5,7 @@ #include #include -#include "src/storage/expressions/SimpleValuation.h" #include "src/storage/expressions/BaseExpression.h" -#include "src/storage/expressions/ExpressionVisitor.h" #include "src/utility/OsDetection.h" namespace storm { @@ -15,6 +13,7 @@ namespace storm { // Foward-declare expression manager class. class ExpressionManager; class Variable; + class ExpressionVisitor; class Expression { public: @@ -71,18 +70,18 @@ namespace storm { * @return An expression in which all identifiers in the key set of the mapping are replaced by the * expression they are mapped to. */ - Expression substitute(std::map const& variableToExpressionMap) const; + Expression substitute(std::map const& variableToExpressionMap) const; - /*! - * Substitutes all occurrences of the variables according to the given map. Note that this substitution is - * done simultaneously, i.e., variables appearing in the expressions that were "plugged in" are not - * substituted. - * - * @param variableToExpressionMap A mapping from variables to the expression they are substituted with. - * @return An expression in which all identifiers in the key set of the mapping are replaced by the - * expression they are mapped to. - */ - Expression substitute(std::unordered_map const& variableToExpressionMap) const; + /*! + * Substitutes all occurrences of the variables according to the given map. Note that this substitution is + * done simultaneously, i.e., variables appearing in the expressions that were "plugged in" are not + * substituted. + * + * @param variableToExpressionMap A mapping from variables to the expression they are substituted with. + * @return An expression in which all identifiers in the key set of the mapping are replaced by the + * expression they are mapped to. + */ + Expression substitute(std::unordered_map const& variableToExpressionMap) const; /*! * Evaluates the expression under the valuation of variables given by the valuation and returns the diff --git a/src/storage/expressions/ExpressionManager.cpp b/src/storage/expressions/ExpressionManager.cpp index 2685c940c..55ef846ed 100644 --- a/src/storage/expressions/ExpressionManager.cpp +++ b/src/storage/expressions/ExpressionManager.cpp @@ -4,6 +4,7 @@ #include "src/storage/expressions/Variable.h" #include "src/utility/macros.h" #include "src/exceptions/InvalidStateException.h" +#include "src/exceptions/InvalidArgumentException.h" namespace storm { namespace expressions { diff --git a/src/storage/expressions/IfThenElseExpression.cpp b/src/storage/expressions/IfThenElseExpression.cpp index 4692675bf..adde41a2d 100644 --- a/src/storage/expressions/IfThenElseExpression.cpp +++ b/src/storage/expressions/IfThenElseExpression.cpp @@ -1,6 +1,7 @@ #include "src/storage/expressions/IfThenElseExpression.h" #include "src/utility/macros.h" +#include "ExpressionVisitor.h" #include "src/exceptions/InvalidAccessException.h" namespace storm { diff --git a/src/storage/expressions/IntegerLiteralExpression.cpp b/src/storage/expressions/IntegerLiteralExpression.cpp index f1050f70a..35ae07ee7 100644 --- a/src/storage/expressions/IntegerLiteralExpression.cpp +++ b/src/storage/expressions/IntegerLiteralExpression.cpp @@ -1,4 +1,6 @@ #include "src/storage/expressions/IntegerLiteralExpression.h" + +#include "ExpressionVisitor.h" #include "src/storage/expressions/ExpressionManager.h" namespace storm { diff --git a/src/storage/expressions/LinearCoefficientVisitor.cpp b/src/storage/expressions/LinearCoefficientVisitor.cpp index ee7d397ae..8d7f39278 100644 --- a/src/storage/expressions/LinearCoefficientVisitor.cpp +++ b/src/storage/expressions/LinearCoefficientVisitor.cpp @@ -1,6 +1,7 @@ #include "src/storage/expressions/LinearCoefficientVisitor.h" #include "src/storage/expressions/Expressions.h" + #include "src/utility/macros.h" #include "src/exceptions/InvalidArgumentException.h" diff --git a/src/storage/expressions/ToRationalFunctionVisitor.cpp b/src/storage/expressions/ToRationalFunctionVisitor.cpp index 55840c301..5740cc66d 100644 --- a/src/storage/expressions/ToRationalFunctionVisitor.cpp +++ b/src/storage/expressions/ToRationalFunctionVisitor.cpp @@ -3,6 +3,7 @@ #include #include "src/utility/macros.h" +#include "src/exceptions/InvalidArgumentException.h" #ifdef STORM_HAVE_CARL diff --git a/src/storage/expressions/UnaryBooleanFunctionExpression.cpp b/src/storage/expressions/UnaryBooleanFunctionExpression.cpp index 020d2de27..7c45e081d 100644 --- a/src/storage/expressions/UnaryBooleanFunctionExpression.cpp +++ b/src/storage/expressions/UnaryBooleanFunctionExpression.cpp @@ -1,5 +1,6 @@ #include "src/storage/expressions/UnaryBooleanFunctionExpression.h" #include "src/storage/expressions/BooleanLiteralExpression.h" +#include "ExpressionVisitor.h" #include "src/utility/macros.h" #include "src/exceptions/InvalidTypeException.h" diff --git a/src/storage/expressions/UnaryNumericalFunctionExpression.cpp b/src/storage/expressions/UnaryNumericalFunctionExpression.cpp index e0181e139..987b5b5e1 100644 --- a/src/storage/expressions/UnaryNumericalFunctionExpression.cpp +++ b/src/storage/expressions/UnaryNumericalFunctionExpression.cpp @@ -5,6 +5,7 @@ #include "src/storage/expressions/UnaryNumericalFunctionExpression.h" #include "src/storage/expressions/IntegerLiteralExpression.h" #include "src/storage/expressions/DoubleLiteralExpression.h" +#include "ExpressionVisitor.h" #include "src/utility/macros.h" #include "src/exceptions/InvalidTypeException.h" diff --git a/src/storage/expressions/Variable.cpp b/src/storage/expressions/Variable.cpp index 64c7174ca..aeb432f2a 100644 --- a/src/storage/expressions/Variable.cpp +++ b/src/storage/expressions/Variable.cpp @@ -1,5 +1,6 @@ #include "src/storage/expressions/Variable.h" #include "src/storage/expressions/ExpressionManager.h" +#include namespace storm { namespace expressions { @@ -40,6 +41,7 @@ namespace storm { } ExpressionManager const& Variable::getManager() const { + assert(manager != nullptr); return *manager; } diff --git a/src/storage/expressions/Variable.h b/src/storage/expressions/Variable.h index f3a271760..3ade039ed 100644 --- a/src/storage/expressions/Variable.h +++ b/src/storage/expressions/Variable.h @@ -3,14 +3,15 @@ #include #include +#include #include "src/utility/OsDetection.h" -#include "src/storage/expressions/Type.h" -#include "src/storage/expressions/Expression.h" namespace storm { namespace expressions { class ExpressionManager; + class Expression; + class Type; // This class captures a simple variable. class Variable { diff --git a/src/storage/expressions/VariableExpression.cpp b/src/storage/expressions/VariableExpression.cpp index 93c693515..8ac6cb8b2 100644 --- a/src/storage/expressions/VariableExpression.cpp +++ b/src/storage/expressions/VariableExpression.cpp @@ -1,4 +1,6 @@ #include "src/storage/expressions/VariableExpression.h" +#include "Valuation.h" +#include "ExpressionVisitor.h" #include "src/utility/macros.h" #include "src/exceptions/InvalidTypeException.h" diff --git a/src/storage/prism/InitialConstruct.cpp b/src/storage/prism/InitialConstruct.cpp index 9fff50a97..3c954120e 100644 --- a/src/storage/prism/InitialConstruct.cpp +++ b/src/storage/prism/InitialConstruct.cpp @@ -1,4 +1,5 @@ #include "src/storage/prism/InitialConstruct.h" +#include "src/storage/expressions/Variable.h" namespace storm { namespace prism { diff --git a/src/storage/prism/InitialConstruct.h b/src/storage/prism/InitialConstruct.h index 1bfd54d5f..5200fe805 100644 --- a/src/storage/prism/InitialConstruct.h +++ b/src/storage/prism/InitialConstruct.h @@ -2,12 +2,21 @@ #define STORM_STORAGE_PRISM_INITIALCONSTRUCT_H_ #include +#include #include "src/storage/prism/LocatedInformation.h" #include "src/storage/expressions/Expression.h" -#include "src/storage/expressions/Variable.h" #include "src/utility/OsDetection.h" + +namespace storm { + namespace expressions { + class Variable; + } +} + + + namespace storm { namespace prism { class InitialConstruct : public LocatedInformation { diff --git a/src/storage/prism/Label.cpp b/src/storage/prism/Label.cpp index dbc9d7f6f..977856dae 100644 --- a/src/storage/prism/Label.cpp +++ b/src/storage/prism/Label.cpp @@ -1,4 +1,5 @@ #include "src/storage/prism/Label.h" +#include "src/storage/expressions/Variable.h" namespace storm { namespace prism { diff --git a/src/storage/prism/Label.h b/src/storage/prism/Label.h index c0202cc04..82e10b26b 100644 --- a/src/storage/prism/Label.h +++ b/src/storage/prism/Label.h @@ -5,9 +5,16 @@ #include "src/storage/prism/LocatedInformation.h" #include "src/storage/expressions/Expression.h" -#include "src/storage/expressions/Variable.h" #include "src/utility/OsDetection.h" +namespace storm { + namespace storage { + namespace expressions { + class Variable; + } + } +} + namespace storm { namespace prism { class Label : public LocatedInformation { diff --git a/src/storage/prism/Module.h b/src/storage/prism/Module.h index 421f4b6e1..48d252576 100644 --- a/src/storage/prism/Module.h +++ b/src/storage/prism/Module.h @@ -11,7 +11,6 @@ #include "src/storage/prism/BooleanVariable.h" #include "src/storage/prism/IntegerVariable.h" #include "src/storage/prism/Command.h" -#include "src/storage/expressions/VariableExpression.h" #include "src/utility/OsDetection.h" namespace storm { diff --git a/src/storage/prism/Program.h b/src/storage/prism/Program.h index 6a124e4e0..3d0d745b7 100644 --- a/src/storage/prism/Program.h +++ b/src/storage/prism/Program.h @@ -6,7 +6,6 @@ #include #include -#include "src/storage/expressions/Expression.h" #include "src/storage/prism/Constant.h" #include "src/storage/prism/Formula.h" #include "src/storage/prism/Label.h" diff --git a/src/storage/prism/StateReward.cpp b/src/storage/prism/StateReward.cpp index adcc423ec..8310f82bc 100644 --- a/src/storage/prism/StateReward.cpp +++ b/src/storage/prism/StateReward.cpp @@ -1,4 +1,5 @@ #include "src/storage/prism/StateReward.h" +#include "src/storage/expressions/Variable.h" namespace storm { namespace prism { diff --git a/src/storage/prism/StateReward.h b/src/storage/prism/StateReward.h index 535999faf..105d9267c 100644 --- a/src/storage/prism/StateReward.h +++ b/src/storage/prism/StateReward.h @@ -5,9 +5,17 @@ #include "src/storage/prism/LocatedInformation.h" #include "src/storage/expressions/Expression.h" -#include "src/storage/expressions/Variable.h" #include "src/utility/OsDetection.h" +namespace storm { + namespace storage { + namespace expressions { + class Variable; + } + } +} + + namespace storm { namespace prism { class StateReward : public LocatedInformation { diff --git a/src/storage/prism/TransitionReward.cpp b/src/storage/prism/TransitionReward.cpp index 182fe43a1..aadaf7a90 100644 --- a/src/storage/prism/TransitionReward.cpp +++ b/src/storage/prism/TransitionReward.cpp @@ -1,4 +1,5 @@ #include "src/storage/prism/TransitionReward.h" +#include "src/storage/expressions/Variable.h" namespace storm { namespace prism { diff --git a/src/storage/prism/TransitionReward.h b/src/storage/prism/TransitionReward.h index 4d693b899..8ace7c71c 100644 --- a/src/storage/prism/TransitionReward.h +++ b/src/storage/prism/TransitionReward.h @@ -5,9 +5,18 @@ #include "src/storage/prism/LocatedInformation.h" #include "src/storage/expressions/Expression.h" -#include "src/storage/expressions/Variable.h" #include "src/utility/OsDetection.h" + +namespace storm { + namespace storage { + namespace expressions { + class Variable; + } + } +} + + namespace storm { namespace prism { class TransitionReward : public LocatedInformation { diff --git a/src/utility/prism.cpp b/src/utility/prism.cpp index 72c3c3258..b392616fe 100644 --- a/src/utility/prism.cpp +++ b/src/utility/prism.cpp @@ -1,4 +1,7 @@ #include "src/utility/prism.h" +#include "src/storage/expressions/ExpressionManager.h" +#include "src/storage/prism/Program.h" + namespace storm { namespace utility { diff --git a/src/utility/prism.h b/src/utility/prism.h index ea6057a15..87365e38d 100644 --- a/src/utility/prism.h +++ b/src/utility/prism.h @@ -2,15 +2,25 @@ #define STORM_UTILITY_PRISM_H_ #include +#include #include +#include -#include "src/storage/expressions/ExpressionManager.h" -#include "src/storage/prism/Program.h" #include "src/utility/OsDetection.h" #include "src/utility/macros.h" #include "src/exceptions/InvalidArgumentException.h" + namespace storm { + namespace expressions { + class Variable; + class Expression; + } + + namespace prism { + class Program; + } + namespace utility { namespace prism { // A structure holding information about a particular choice. diff --git a/test/functional/adapter/Z3ExpressionAdapterTest.cpp b/test/functional/adapter/Z3ExpressionAdapterTest.cpp index 763ffa3ef..4b220861b 100644 --- a/test/functional/adapter/Z3ExpressionAdapterTest.cpp +++ b/test/functional/adapter/Z3ExpressionAdapterTest.cpp @@ -148,7 +148,6 @@ TEST(Z3ExpressionAdapter, StormToZ3FloorCeil) { TEST(Z3ExpressionAdapter, Z3ToStormBasic) { z3::context ctx; - unsigned args = 2; std::shared_ptr manager(new storm::expressions::ExpressionManager()); manager->declareBooleanVariable("x"); diff --git a/test/functional/builder/die.pm b/test/functional/builder/die.pm index af0797cff..6fd3f8231 100644 --- a/test/functional/builder/die.pm +++ b/test/functional/builder/die.pm @@ -29,4 +29,4 @@ label "three" = s=7&d=3; label "four" = s=7&d=4; label "five" = s=7&d=5; label "six" = s=7&d=6; -label "done" = s=7; +label "done" = s=7; \ No newline at end of file diff --git a/test/functional/solver/GlpkLpSolverTest.cpp b/test/functional/solver/GlpkLpSolverTest.cpp index 5aeb01dc7..3c0112cf7 100644 --- a/test/functional/solver/GlpkLpSolverTest.cpp +++ b/test/functional/solver/GlpkLpSolverTest.cpp @@ -2,11 +2,14 @@ #include "storm-config.h" #ifdef STORM_HAVE_GLPK +#include "src/storage/expressions/Variable.h" #include "src/solver/GlpkLpSolver.h" #include "src/exceptions/InvalidStateException.h" #include "src/exceptions/InvalidAccessException.h" #include "src/settings/SettingsManager.h" +#include "src/storage/expressions/Expressions.h" + TEST(GlpkLpSolver, LPOptimizeMax) { storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize); storm::expressions::Variable x; diff --git a/test/functional/solver/GurobiLpSolverTest.cpp b/test/functional/solver/GurobiLpSolverTest.cpp index 6c07a1f19..7e1547333 100644 --- a/test/functional/solver/GurobiLpSolverTest.cpp +++ b/test/functional/solver/GurobiLpSolverTest.cpp @@ -6,6 +6,8 @@ #include "src/exceptions/InvalidStateException.h" #include "src/exceptions/InvalidAccessException.h" #include "src/settings/SettingsManager.h" +#include "src/storage/expressions/Variable.h" +#include "src/storage/expressions/Expressions.h" TEST(GurobiLpSolver, LPOptimizeMax) { storm::solver::GurobiLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize); diff --git a/test/functional/solver/Z3SmtSolverTest.cpp b/test/functional/solver/Z3SmtSolverTest.cpp index 4e2b1b63c..7030777be 100644 --- a/test/functional/solver/Z3SmtSolverTest.cpp +++ b/test/functional/solver/Z3SmtSolverTest.cpp @@ -162,7 +162,6 @@ TEST(Z3SmtSolver, AllSat) { std::shared_ptr manager(new storm::expressions::ExpressionManager()); storm::solver::Z3SmtSolver s(*manager); - storm::solver::SmtSolver::CheckResult result = storm::solver::SmtSolver::CheckResult::Unknown; storm::expressions::Variable a = manager->declareIntegerVariable("a"); storm::expressions::Variable b = manager->declareIntegerVariable("b"); diff --git a/test/functional/storm-functional-tests.cpp b/test/functional/storm-functional-tests.cpp index 30709a39d..5051bb659 100644 --- a/test/functional/storm-functional-tests.cpp +++ b/test/functional/storm-functional-tests.cpp @@ -8,6 +8,7 @@ #include "log4cplus/consoleappender.h" #include "log4cplus/fileappender.h" +#include "storm-config.h" #include "src/settings/SettingsManager.h" log4cplus::Logger logger;