1#ifndef STORM_ADAPTERS_MATHSATEXPRESSIONADAPTER_H_
2#define STORM_ADAPTERS_MATHSATEXPRESSIONADAPTER_H_
4#include "storm-config.h"
26struct hash<msat_decl> {
27 size_t operator()(msat_decl
const& declaration)
const {
28 return hash<void*>()(declaration.repr);
34bool operator==(msat_decl decl1, msat_decl decl2);
61 additionalConstraints.clear();
63 if (MSAT_ERROR_TERM(result)) {
64 std::string errorMessage(msat_last_error_message(env));
65 STORM_LOG_THROW(!MSAT_ERROR_TERM(result), storm::exceptions::ExpressionEvaluationException,
66 "Could not translate expression to MathSAT's format. (Message: " << errorMessage <<
")");
81 auto const& variableExpressionPair = variableToDeclarationMapping.find(variable);
82 if (variableExpressionPair == variableToDeclarationMapping.end()) {
83 return msat_make_constant(env, createVariable(variable));
85 return msat_make_constant(env, variableExpressionPair->second);
88 bool hasAdditionalConstraints()
const {
89 return !additionalConstraints.empty();
95 std::vector<msat_term>
const& getAdditionalConstraints()
const {
96 return additionalConstraints;
106 auto const& declarationVariablePair = declarationToVariableMapping.find(msatVariableDeclaration);
107 STORM_LOG_ASSERT(declarationVariablePair != declarationToVariableMapping.end(),
"Unknown variable declaration.");
108 return declarationVariablePair->second;
111 std::unordered_map<storm::expressions::Variable, msat_decl>
const& getAllDeclaredVariables()
const {
112 return variableToDeclarationMapping;
116 msat_term leftResult = boost::any_cast<msat_term>(expression.
getFirstOperand()->accept(*
this, data));
117 msat_term rightResult = boost::any_cast<msat_term>(expression.
getSecondOperand()->accept(*
this, data));
121 return msat_make_and(env, leftResult, rightResult);
123 return msat_make_or(env, leftResult, rightResult);
125 return msat_make_iff(env, leftResult, rightResult);
127 return msat_make_or(env, msat_make_not(env, leftResult), rightResult);
129 STORM_LOG_THROW(
false, storm::exceptions::ExpressionEvaluationException,
130 "Cannot evaluate expression: unknown boolean binary operator '" <<
static_cast<uint_fast64_t
>(expression.
getOperatorType())
131 <<
"' in expression " << expression <<
".");
136 msat_term leftResult = boost::any_cast<msat_term>(expression.
getFirstOperand()->accept(*
this, data));
137 msat_term rightResult = boost::any_cast<msat_term>(expression.
getSecondOperand()->accept(*
this, data));
139 msat_term result = leftResult;
140 int_fast64_t exponent;
141 int_fast64_t modulus;
143 msat_term modVariable;
149 return msat_make_plus(env, leftResult, rightResult);
151 return msat_make_plus(env, leftResult, msat_make_times(env, msat_make_number(env,
"-1"), rightResult));
153 return msat_make_times(env, leftResult, rightResult);
155 return msat_make_divide(env, leftResult, rightResult);
157 return msat_make_term_ite(env, msat_make_leq(env, leftResult, rightResult), leftResult, rightResult);
159 return msat_make_term_ite(env, msat_make_leq(env, leftResult, rightResult), rightResult, leftResult);
162 STORM_LOG_THROW(exponent >= 0, storm::exceptions::ExpressionEvaluationException,
"Cannot evaluate expression with negative exponent.");
165 for (; exponent > 0; --exponent) {
166 result = msat_make_times(env, result, leftResult);
172 STORM_LOG_THROW(modulus > 0, storm::exceptions::ExpressionEvaluationException,
"Cannot evaluate expression with negative modulus.");
174 freshAuxiliaryVariable =
manager.declareFreshVariable(
manager.getIntegerType(),
true);
175 modVariable = msat_make_constant(env, createVariable(freshAuxiliaryVariable));
180 additionalConstraints.push_back(msat_make_int_modular_congruence(env, gmpModulus.get_mpz_t(), modVariable, leftResult));
183 lower = msat_make_number(env,
"-1");
184 upper = msat_make_number(env, std::to_string(modulus - 1).c_str());
185 additionalConstraints.push_back(
186 msat_make_and(env, msat_make_not(env, msat_make_leq(env, modVariable, lower)), msat_make_leq(env, modVariable, upper)));
189 STORM_LOG_THROW(
false, storm::exceptions::ExpressionEvaluationException,
190 "Cannot evaluate expression: unknown numerical binary operator '" <<
static_cast<uint_fast64_t
>(expression.
getOperatorType())
191 <<
"' in expression " << expression <<
".");
196 msat_term leftResult = boost::any_cast<msat_term>(expression.
getFirstOperand()->accept(*
this, data));
197 msat_term rightResult = boost::any_cast<msat_term>(expression.
getSecondOperand()->accept(*
this, data));
202 return msat_make_iff(env, leftResult, rightResult);
204 return msat_make_equal(env, leftResult, rightResult);
208 return msat_make_not(env, msat_make_iff(env, leftResult, rightResult));
210 return msat_make_not(env, msat_make_equal(env, leftResult, rightResult));
213 return msat_make_and(env, msat_make_not(env, msat_make_equal(env, leftResult, rightResult)), msat_make_leq(env, leftResult, rightResult));
215 return msat_make_leq(env, leftResult, rightResult);
217 return msat_make_not(env, msat_make_leq(env, leftResult, rightResult));
219 return msat_make_or(env, msat_make_equal(env, leftResult, rightResult), msat_make_not(env, msat_make_leq(env, leftResult, rightResult)));
221 STORM_LOG_THROW(
false, storm::exceptions::ExpressionEvaluationException,
222 "Cannot evaluate expression: unknown boolean binary operator '" <<
static_cast<uint_fast64_t
>(expression.
getRelationType())
223 <<
"' in expression " << expression <<
".");
228 msat_term conditionResult = boost::any_cast<msat_term>(expression.
getCondition()->accept(*
this, data));
229 msat_term thenResult = boost::any_cast<msat_term>(expression.
getThenExpression()->accept(*
this, data));
230 msat_term elseResult = boost::any_cast<msat_term>(expression.
getElseExpression()->accept(*
this, data));
234 return msat_make_and(env, msat_make_or(env, msat_make_not(env, conditionResult), thenResult), msat_make_or(env, conditionResult, elseResult));
236 return msat_make_term_ite(env, conditionResult, thenResult, elseResult);
241 return expression.
getValue() ? msat_make_true(env) : msat_make_false(env);
245 std::stringstream fractionStream;
246 fractionStream << expression.
getValue();
247 return msat_make_number(env, fractionStream.str().c_str());
251 return msat_make_number(env, std::to_string(
static_cast<int>(expression.
getValue())).c_str());
255 msat_term childResult = boost::any_cast<msat_term>(expression.
getOperand()->accept(*
this, data));
259 return msat_make_not(env, childResult);
262 STORM_LOG_THROW(
false, storm::exceptions::ExpressionEvaluationException,
263 "Cannot evaluate expression: unknown boolean unary operator: '" <<
static_cast<uint_fast64_t
>(expression.
getOperatorType())
264 <<
"' in expression " << expression <<
".");
269 msat_term childResult = boost::any_cast<msat_term>(expression.
getOperand()->accept(*
this, data));
273 return msat_make_times(env, msat_make_number(env,
"-1"), childResult);
275 return msat_make_floor(env, childResult);
278 return msat_make_times(env, msat_make_number(env,
"-1"), msat_make_floor(env, msat_make_times(env, msat_make_number(env,
"-1"), childResult)));
280 STORM_LOG_THROW(
false, storm::exceptions::ExpressionEvaluationException,
281 "Cannot evaluate expression: unknown numerical unary operator: '" <<
static_cast<uint_fast64_t
>(expression.
getOperatorType())
282 <<
"' in expression " << expression <<
".");
287 return translateExpression(expression.
getVariable());
291 if (msat_term_is_and(env, term)) {
292 return translateExpression(msat_term_get_arg(term, 0)) && translateExpression(msat_term_get_arg(term, 1));
293 }
else if (msat_term_is_or(env, term)) {
294 return translateExpression(msat_term_get_arg(term, 0)) || translateExpression(msat_term_get_arg(term, 1));
295 }
else if (msat_term_is_iff(env, term)) {
296 return storm::expressions::iff(translateExpression(msat_term_get_arg(term, 0)), translateExpression(msat_term_get_arg(term, 1)));
297 }
else if (msat_term_is_not(env, term)) {
298 return !translateExpression(msat_term_get_arg(term, 0));
299 }
else if (msat_term_is_plus(env, term)) {
300 return translateExpression(msat_term_get_arg(term, 0)) + translateExpression(msat_term_get_arg(term, 1));
301 }
else if (msat_term_is_times(env, term)) {
302 return translateExpression(msat_term_get_arg(term, 0)) * translateExpression(msat_term_get_arg(term, 1));
303 }
else if (msat_term_is_equal(env, term)) {
304 return translateExpression(msat_term_get_arg(term, 0)) == translateExpression(msat_term_get_arg(term, 1));
305 }
else if (msat_term_is_leq(env, term)) {
306 return translateExpression(msat_term_get_arg(term, 0)) <= translateExpression(msat_term_get_arg(term, 1));
307 }
else if (msat_term_is_true(env, term)) {
309 }
else if (msat_term_is_false(env, term)) {
311 }
else if (msat_term_is_constant(env, term)) {
312 char* name = msat_decl_get_name(msat_term_get_decl(term));
313 std::string nameString(name);
317 }
else if (msat_term_is_number(env, term)) {
318 char* termAsCString = msat_term_repr(term);
319 std::string termString(termAsCString);
320 msat_free(termAsCString);
321 if (msat_is_integer_type(env, msat_term_get_type(term))) {
322 return manager.integer(std::stoll(msat_term_repr(term)));
323 }
else if (msat_is_rational_type(env, msat_term_get_type(term))) {
324 return manager.rational(storm::utility::convertNumber<storm::RationalNumber>(termString));
326 }
else if (msat_term_is_term_ite(env, term)) {
327 return storm::expressions::ite(translateExpression(msat_term_get_arg(term, 0)), translateExpression(msat_term_get_arg(term, 1)),
328 translateExpression(msat_term_get_arg(term, 2)));
332 char* termAsCString = msat_term_repr(term);
333 std::string termString(termAsCString);
334 msat_free(termAsCString);
335 STORM_LOG_THROW(
false, storm::exceptions::ExpressionEvaluationException,
"Cannot translate expression: unknown term: '" << termString <<
"'.");
345 msat_decl msatDeclaration;
347 msatDeclaration = msat_declare_function(env, variable.
getName().c_str(), msat_get_bool_type(env));
349 msatDeclaration = msat_declare_function(env, variable.
getName().c_str(), msat_get_integer_type(env));
351 msatDeclaration = msat_declare_function(env, variable.
getName().c_str(), msat_get_bv_type(env, variable.
getType().
getWidth()));
353 msatDeclaration = msat_declare_function(env, variable.
getName().c_str(), msat_get_rational_type(env));
356 "Encountered variable '" << variable.
getName() <<
"' with unknown type while trying to create solver variables.");
358 variableToDeclarationMapping.insert(std::make_pair(variable, msatDeclaration));
359 declarationToVariableMapping.insert(std::make_pair(msatDeclaration, variable));
360 return msatDeclaration;
371 std::vector<msat_term> additionalConstraints;
374 std::unordered_map<storm::expressions::Variable, msat_decl> variableToDeclarationMapping;
377 std::unordered_map<msat_decl, storm::expressions::Variable> declarationToVariableMapping;
virtual boost::any accept(ExpressionVisitor &visitor, boost::any const &data) const =0
Accepts the given visitor by calling its visit method.
OperatorType getOperatorType() const
Retrieves the operator associated with the expression.
std::shared_ptr< BaseExpression const > const & getSecondOperand() const
Retrieves the second operand of the expression.
std::shared_ptr< BaseExpression const > const & getFirstOperand() const
Retrieves the first operand of the expression.
OperatorType getOperatorType() const
Retrieves the operator associated with the expression.
RelationType getRelationType() const
Retrieves the relation associated with the expression.
bool getValue() const
Retrieves the value of the boolean literal.
BaseExpression const & getBaseExpression() const
Retrieves the base expression underlying this expression object.
This class is responsible for managing a set of typed variables and all expressions using these varia...
std::shared_ptr< BaseExpression const > getElseExpression() const
Retrieves the else expression of the if-then-else expression.
std::shared_ptr< BaseExpression const > getCondition() const
Retrieves the condition expression of the if-then-else expression.
std::shared_ptr< BaseExpression const > getThenExpression() const
Retrieves the then expression of the if-then-else expression.
int_fast64_t getValue() const
Retrieves the value of the integer literal.
storm::RationalNumber getValue() const
Retrieves the value of the double literal.
bool isBooleanType() const
Checks whether this type is a boolean type.
std::size_t getWidth() const
Retrieves the bit width of the type, provided that it is a bitvector type.
bool isIntegerType() const
Checks whether this type is an integral type.
bool isRationalType() const
Checks whether this type is a rational type.
bool isBitVectorType() const
Checks whether this type is a bitvector type.
OperatorType getOperatorType() const
Retrieves the operator associated with this expression.
virtual std::shared_ptr< BaseExpression const > getOperand(uint_fast64_t operandIndex) const override
Retrieves the given operand from the expression.
OperatorType getOperatorType() const
Retrieves the operator associated with this expression.
Variable const & getVariable() const
Retrieves the variable associated with this expression.
ExpressionManager const & getManager() const
Retrieves the manager responsible for this variable.
Type const & getType() const
Retrieves the type of the variable.
std::string const & getName() const
Retrieves the name of the variable.
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
bool operator==(BEColourClass< ValueType > const &lhs, BEColourClass< ValueType > const &rhs)
Expression ite(Expression const &condition, Expression const &thenExpression, Expression const &elseExpression)
Expression iff(Expression const &first, Expression const &second)
SettingsManager const & manager()
Retrieves the settings manager.