16#ifdef STORM_HAVE_MATHSAT
18bool operator==(msat_decl decl1, msat_decl decl2) {
19 return decl1.repr == decl2.repr;
25MathsatExpressionAdapter::MathsatExpressionAdapter(storm::expressions::ExpressionManager& manager, msat_env& env)
31 additionalConstraints.clear();
33 if (MSAT_ERROR_TERM(result)) {
34 std::string errorMessage(msat_last_error_message(env));
35 STORM_LOG_THROW(!MSAT_ERROR_TERM(result), storm::exceptions::ExpressionEvaluationException,
36 "Could not translate expression to MathSAT's format. (Message: " << errorMessage <<
").");
45 auto const& variableExpressionPair = variableToDeclarationMapping.find(variable);
46 if (variableExpressionPair == variableToDeclarationMapping.end()) {
47 return msat_make_constant(env, createVariable(variable));
49 return msat_make_constant(env, variableExpressionPair->second);
52bool MathsatExpressionAdapter::hasAdditionalConstraints()
const {
53 return !additionalConstraints.empty();
56std::vector<msat_term>
const& MathsatExpressionAdapter::getAdditionalConstraints()
const {
57 return additionalConstraints;
61 auto const& declarationVariablePair = declarationToVariableMapping.find(msatVariableDeclaration);
62 STORM_LOG_ASSERT(declarationVariablePair != declarationToVariableMapping.end(),
"Unknown variable declaration.");
63 return declarationVariablePair->second;
66std::unordered_map<storm::expressions::Variable, msat_decl>
const& MathsatExpressionAdapter::getAllDeclaredVariables()
const {
67 return variableToDeclarationMapping;
71 msat_term leftResult = boost::any_cast<msat_term>(expression.
getFirstOperand()->accept(*
this, data));
72 msat_term rightResult = boost::any_cast<msat_term>(expression.
getSecondOperand()->accept(*
this, data));
76 return msat_make_and(env, leftResult, rightResult);
78 return msat_make_or(env, leftResult, rightResult);
80 return msat_make_iff(env, leftResult, rightResult);
82 return msat_make_or(env, msat_make_not(env, leftResult), rightResult);
84 STORM_LOG_THROW(
false, storm::exceptions::ExpressionEvaluationException,
85 "Cannot evaluate expression: unknown boolean binary operator '" <<
static_cast<uint_fast64_t
>(expression.
getOperatorType())
86 <<
"' in expression " << expression <<
".");
91 msat_term leftResult = boost::any_cast<msat_term>(expression.
getFirstOperand()->accept(*
this, data));
92 msat_term rightResult = boost::any_cast<msat_term>(expression.
getSecondOperand()->accept(*
this, data));
94 msat_term result = leftResult;
95 int_fast64_t exponent;
98 msat_term modVariable;
104 return msat_make_plus(env, leftResult, rightResult);
106 return msat_make_plus(env, leftResult, msat_make_times(env, msat_make_number(env,
"-1"), rightResult));
108 return msat_make_times(env, leftResult, rightResult);
110 return msat_make_divide(env, leftResult, rightResult);
112 return msat_make_term_ite(env, msat_make_leq(env, leftResult, rightResult), leftResult, rightResult);
114 return msat_make_term_ite(env, msat_make_leq(env, leftResult, rightResult), rightResult, leftResult);
117 STORM_LOG_THROW(exponent >= 0, storm::exceptions::ExpressionEvaluationException,
"Cannot evaluate expression with negative exponent.");
120 for (; exponent > 0; --exponent) {
121 result = msat_make_times(env, result, leftResult);
127 STORM_LOG_THROW(modulus > 0, storm::exceptions::ExpressionEvaluationException,
"Cannot evaluate expression with negative modulus.");
129 freshAuxiliaryVariable =
manager.declareFreshVariable(
manager.getIntegerType(),
true);
130 modVariable = msat_make_constant(env, createVariable(freshAuxiliaryVariable));
135 additionalConstraints.push_back(msat_make_int_modular_congruence(env, gmpModulus.get_mpz_t(), modVariable, leftResult));
138 lower = msat_make_number(env,
"-1");
139 upper = msat_make_number(env, std::to_string(modulus - 1).c_str());
140 additionalConstraints.push_back(
141 msat_make_and(env, msat_make_not(env, msat_make_leq(env, modVariable, lower)), msat_make_leq(env, modVariable, upper)));
144 STORM_LOG_THROW(
false, storm::exceptions::ExpressionEvaluationException,
145 "Cannot evaluate expression: unknown numerical binary operator '" <<
static_cast<uint_fast64_t
>(expression.
getOperatorType())
146 <<
"' in expression " << expression <<
".");
151 msat_term leftResult = boost::any_cast<msat_term>(expression.
getFirstOperand()->accept(*
this, data));
152 msat_term rightResult = boost::any_cast<msat_term>(expression.
getSecondOperand()->accept(*
this, data));
157 return msat_make_iff(env, leftResult, rightResult);
159 return msat_make_equal(env, leftResult, rightResult);
163 return msat_make_not(env, msat_make_iff(env, leftResult, rightResult));
165 return msat_make_not(env, msat_make_equal(env, leftResult, rightResult));
168 return msat_make_and(env, msat_make_not(env, msat_make_equal(env, leftResult, rightResult)), msat_make_leq(env, leftResult, rightResult));
170 return msat_make_leq(env, leftResult, rightResult);
172 return msat_make_not(env, msat_make_leq(env, leftResult, rightResult));
174 return msat_make_or(env, msat_make_equal(env, leftResult, rightResult), msat_make_not(env, msat_make_leq(env, leftResult, rightResult)));
176 STORM_LOG_THROW(
false, storm::exceptions::ExpressionEvaluationException,
177 "Cannot evaluate expression: unknown boolean binary operator '" <<
static_cast<uint_fast64_t
>(expression.
getRelationType())
178 <<
"' in expression " << expression <<
".");
183 msat_term conditionResult = boost::any_cast<msat_term>(expression.
getCondition()->accept(*
this, data));
184 msat_term thenResult = boost::any_cast<msat_term>(expression.
getThenExpression()->accept(*
this, data));
185 msat_term elseResult = boost::any_cast<msat_term>(expression.
getElseExpression()->accept(*
this, data));
189 return msat_make_and(env, msat_make_or(env, msat_make_not(env, conditionResult), thenResult), msat_make_or(env, conditionResult, elseResult));
191 return msat_make_term_ite(env, conditionResult, thenResult, elseResult);
196 return expression.
getValue() ? msat_make_true(env) : msat_make_false(env);
200 std::stringstream fractionStream;
201 fractionStream << expression.
getValue();
202 return msat_make_number(env, fractionStream.str().c_str());
206 return msat_make_number(env, std::to_string(
static_cast<int>(expression.
getValue())).c_str());
210 msat_term childResult = boost::any_cast<msat_term>(expression.
getOperand()->accept(*
this, data));
214 return msat_make_not(env, childResult);
217 STORM_LOG_THROW(
false, storm::exceptions::ExpressionEvaluationException,
218 "Cannot evaluate expression: unknown boolean unary operator: '" <<
static_cast<uint_fast64_t
>(expression.
getOperatorType())
219 <<
"' in expression " << expression <<
".");
224 msat_term childResult = boost::any_cast<msat_term>(expression.
getOperand()->accept(*
this, data));
228 return msat_make_times(env, msat_make_number(env,
"-1"), childResult);
230 return msat_make_floor(env, childResult);
233 return msat_make_times(env, msat_make_number(env,
"-1"), msat_make_floor(env, msat_make_times(env, msat_make_number(env,
"-1"), childResult)));
235 STORM_LOG_THROW(
false, storm::exceptions::ExpressionEvaluationException,
236 "Cannot evaluate expression: unknown numerical unary operator: '" <<
static_cast<uint_fast64_t
>(expression.
getOperatorType())
237 <<
"' in expression " << expression <<
".");
242 return translateExpression(expression.
getVariable());
246 if (msat_term_is_and(env, term)) {
247 return translateExpression(msat_term_get_arg(term, 0)) && translateExpression(msat_term_get_arg(term, 1));
248 }
else if (msat_term_is_or(env, term)) {
249 return translateExpression(msat_term_get_arg(term, 0)) || translateExpression(msat_term_get_arg(term, 1));
250 }
else if (msat_term_is_iff(env, term)) {
251 return storm::expressions::iff(translateExpression(msat_term_get_arg(term, 0)), translateExpression(msat_term_get_arg(term, 1)));
252 }
else if (msat_term_is_not(env, term)) {
253 return !translateExpression(msat_term_get_arg(term, 0));
254 }
else if (msat_term_is_plus(env, term)) {
255 return translateExpression(msat_term_get_arg(term, 0)) + translateExpression(msat_term_get_arg(term, 1));
256 }
else if (msat_term_is_times(env, term)) {
257 return translateExpression(msat_term_get_arg(term, 0)) * translateExpression(msat_term_get_arg(term, 1));
258 }
else if (msat_term_is_equal(env, term)) {
259 return translateExpression(msat_term_get_arg(term, 0)) == translateExpression(msat_term_get_arg(term, 1));
260 }
else if (msat_term_is_leq(env, term)) {
261 return translateExpression(msat_term_get_arg(term, 0)) <= translateExpression(msat_term_get_arg(term, 1));
262 }
else if (msat_term_is_true(env, term)) {
264 }
else if (msat_term_is_false(env, term)) {
266 }
else if (msat_term_is_constant(env, term)) {
267 char* name = msat_decl_get_name(msat_term_get_decl(term));
268 std::string nameString(name);
272 }
else if (msat_term_is_number(env, term)) {
273 char* termAsCString = msat_term_repr(term);
274 std::string termString(termAsCString);
275 msat_free(termAsCString);
276 if (msat_is_integer_type(env, msat_term_get_type(term))) {
277 return manager.integer(std::stoll(msat_term_repr(term)));
278 }
else if (msat_is_rational_type(env, msat_term_get_type(term))) {
281 }
else if (msat_term_is_term_ite(env, term)) {
282 return storm::expressions::ite(translateExpression(msat_term_get_arg(term, 0)), translateExpression(msat_term_get_arg(term, 1)),
283 translateExpression(msat_term_get_arg(term, 2)));
287 char* termAsCString = msat_term_repr(term);
288 std::string termString(termAsCString);
289 msat_free(termAsCString);
290 STORM_LOG_THROW(
false, storm::exceptions::ExpressionEvaluationException,
"Cannot translate expression: unknown term: '" << termString <<
"'.");
294 msat_decl msatDeclaration;
296 msatDeclaration = msat_declare_function(env, variable.
getName().c_str(), msat_get_bool_type(env));
298 msatDeclaration = msat_declare_function(env, variable.
getName().c_str(), msat_get_integer_type(env));
300 msatDeclaration = msat_declare_function(env, variable.
getName().c_str(), msat_get_bv_type(env, variable.
getType().
getWidth()));
302 msatDeclaration = msat_declare_function(env, variable.
getName().c_str(), msat_get_rational_type(env));
305 "Encountered variable '" << variable.
getName() <<
"' with unknown type while trying to create solver variables.");
307 variableToDeclarationMapping.insert(std::make_pair(variable, msatDeclaration));
308 declarationToVariableMapping.insert(std::make_pair(msatDeclaration, variable));
309 return msatDeclaration;
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.
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.
TargetType convertNumber(SourceType const &number)