Browse Source

Initial MathSat integration.

Expression adapter, solving, unsat assumptions implemented
cmake and tests missing
allsat and interpolation not yet implemented


Former-commit-id: 5177775fbe
tempestpy_adaptions
David_Korzeniewski 10 years ago
parent
commit
56edf1e126
  1. 370
      src/adapters/MathSatExpressionAdapter.h
  2. 321
      src/solver/MathSatSmtSolver.cpp
  3. 84
      src/solver/MathSatSmtSolver.h

370
src/adapters/MathSatExpressionAdapter.h

@ -0,0 +1,370 @@
/*
* MathSatExpressionAdapter.h
*
* Author: David Korzeniewski
*/
#ifndef STORM_ADAPTERS_MATHSATEXPRESSIONADAPTER_H_
#define STORM_ADAPTERS_MATHSATEXPRESSIONADAPTER_H_
#include "storm-config.h"
#include <stack>
#include "mathsat.h"
#include "storage/expressions/Expressions.h"
#include "storage/expressions/ExpressionVisitor.h"
#include "src/exceptions/ExceptionMacros.h"
#include "src/exceptions/ExpressionEvaluationException.h"
#include "src/exceptions/InvalidTypeException.h"
#include "src/exceptions/NotImplementedException.h"
namespace storm {
namespace adapters {
class MathSatExpressionAdapter : public storm::expressions::ExpressionVisitor {
public:
/*!
* Creates a MathSatExpressionAdapter over the given MathSAT enviroment.
*
* @param context A reference to the MathSAT enviroment over which to build the expressions. Be careful to guarantee
* the lifetime of the context as long as the instance of this adapter is used.
* @param variableToDeclMap A mapping from variable names to their corresponding MathSAT Declarations.
*/
MathSatExpressionAdapter(msat_env& env, std::map<std::string, msat_decl> const& variableToDeclMap) : env(env), stack(), variableToDeclMap(variableToDeclMap) {
// Intentionally left empty.
}
/*!
* Translates the given expression to an equivalent term for MathSAT.
*
* @param expression The expression to translate.
* @param createMathSatVariables If set to true a solver variable is created for each variable in expression that is not
* yet known to the adapter. (i.e. values from the variableToExpressionMap passed to the constructor
* are not overwritten)
* @return An equivalent term for MathSAT.
*/
msat_term translateExpression(storm::expressions::Expression const& expression, bool createMathSatVariables = false) {
//LOG4CPLUS_TRACE(logger, "Translating expression:\n" << expression->toString());
expression.accept(this);
msat_term result = stack.top();
stack.pop();
if (MSAT_ERROR_TERM(result)) {
//LOG4CPLUS_WARN(logger, "Translating term to MathSAT returned an error!");
}
char* repr = msat_term_repr(result);
//LOG4CPLUS_TRACE(logger, "Result is:\n" << repr);
msat_free(repr);
return result;
}
virtual void visit(expressions::BinaryBooleanFunctionExpression const* expression) override {
expression->getFirstOperand()->accept(this);
expression->getSecondOperand()->accept(this);
msat_term rightResult = stack.top();
stack.pop();
msat_term leftResult = stack.top();
stack.pop();
//char* repr = msat_term_repr(leftResult);
//LOG4CPLUS_TRACE(logger, "LHS: "<<repr);
//msat_free(repr);
//repr = msat_term_repr(rightResult);
//LOG4CPLUS_TRACE(logger, "RHS: "<<repr);
//msat_free(repr);
switch (expression->getOperatorType()) {
case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::And:
stack.push(msat_make_and(env, leftResult, rightResult));
break;
case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Or:
stack.push(msat_make_or(env, leftResult, rightResult));
break;
case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Iff:
stack.push(msat_make_iff(env, leftResult, rightResult));
break;
default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
<< "Unknown boolean binary operator: '" << expression->getOperatorType() << "' in expression " << expression << ".";
}
}
virtual void visit(expressions::BinaryNumericalFunctionExpression const* expression) override {
expression->getFirstOperand()->accept(this);
expression->getSecondOperand()->accept(this);
msat_term rightResult = stack.top();
stack.pop();
msat_term leftResult = stack.top();
stack.pop();
switch (expression->getOperatorType()) {
case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Plus:
stack.push(msat_make_plus(env, leftResult, rightResult));
break;
case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Minus:
stack.push(msat_make_plus(env, leftResult, msat_make_times(env, msat_make_number(env, "-1"), rightResult)));
break;
case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Times:
stack.push(msat_make_times(env, leftResult, rightResult));
break;
case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Divide:
throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
<< "Unsupported numerical binary operator: '/' (division) in expression " << expression << ".";
break;
case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Min:
stack.push(msat_make_term_ite(env, msat_make_leq(env, leftResult, rightResult), leftResult, rightResult));
break;
case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Max:
stack.push(msat_make_term_ite(env, msat_make_leq(env, leftResult, rightResult), rightResult, leftResult));
break;
default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
<< "Unknown numerical binary operator: '" << expression->getOperatorType() << "' in expression " << expression << ".";
}
}
virtual void visit(expressions::BinaryRelationExpression const* expression) override {
expression->getFirstOperand()->accept(this);
expression->getSecondOperand()->accept(this);
msat_term rightResult = stack.top();
stack.pop();
msat_term leftResult = stack.top();
stack.pop();
switch (expression->getRelationType()) {
case storm::expressions::BinaryRelationExpression::RelationType::Equal:
if (expression->getFirstOperand()->getReturnType() == storm::expressions::ExpressionReturnType::Bool && expression->getSecondOperand()->getReturnType() == storm::expressions::ExpressionReturnType::Bool) {
stack.push(msat_make_iff(env, leftResult, rightResult));
} else {
stack.push(msat_make_equal(env, leftResult, rightResult));
}
break;
case storm::expressions::BinaryRelationExpression::RelationType::NotEqual:
if (expression->getFirstOperand()->getReturnType() == storm::expressions::ExpressionReturnType::Bool && expression->getSecondOperand()->getReturnType() == storm::expressions::ExpressionReturnType::Bool) {
stack.push(msat_make_not(env, msat_make_iff(env, leftResult, rightResult)));
} else {
stack.push(msat_make_not(env, msat_make_equal(env, leftResult, rightResult)));
}
break;
case storm::expressions::BinaryRelationExpression::RelationType::Less:
stack.push(msat_make_and(env, msat_make_not(env, msat_make_equal(env, leftResult, rightResult)), msat_make_leq(env, leftResult, rightResult)));
break;
case storm::expressions::BinaryRelationExpression::RelationType::LessOrEqual:
stack.push(msat_make_leq(env, leftResult, rightResult));
break;
case storm::expressions::BinaryRelationExpression::RelationType::Greater:
stack.push(msat_make_not(env, msat_make_leq(env, leftResult, rightResult)));
break;
case storm::expressions::BinaryRelationExpression::RelationType::GreaterOrEqual:
stack.push(msat_make_or(env, msat_make_equal(env, leftResult, rightResult), msat_make_not(env, msat_make_leq(env, leftResult, rightResult))));
break;
default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
<< "Unknown boolean binary operator: '" << expression->getRelationType() << "' in expression " << expression << ".";
}
}
virtual void visit(storm::expressions::IfThenElseExpression const* expression) override {
expression->getCondition()->accept(this);
expression->getThenExpression()->accept(this);
expression->getElseExpression()->accept(this);
msat_term conditionResult = stack.top();
stack.pop();
msat_term thenResult = stack.top();
stack.pop();
msat_term elseResult = stack.top();
stack.pop();
stack.push(msat_make_term_ite(env, conditionResult, thenResult, elseResult));
}
virtual void visit(expressions::BooleanLiteralExpression const* expression) override {
stack.push(expression->evaluateAsBool(nullptr) ? msat_make_true(env) : msat_make_false(env));
}
virtual void visit(expressions::DoubleLiteralExpression const* expression) override {
stack.push(msat_make_number(env, std::to_string(expression->evaluateAsDouble(nullptr)).c_str()));
}
virtual void visit(expressions::IntegerLiteralExpression const* expression) override {
stack.push(msat_make_number(env, std::to_string(static_cast<int>(expression->evaluateAsInt(nullptr))).c_str()));
}
virtual void visit(expressions::UnaryBooleanFunctionExpression const* expression) override {
expression->getOperand()->accept(this);
msat_term childResult = stack.top();
stack.pop();
switch (expression->getOperatorType()) {
case storm::expressions::UnaryBooleanFunctionExpression::OperatorType::Not:
stack.push(msat_make_not(env, childResult));
break;
default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
<< "Unknown boolean binary operator: '" << expression->getOperatorType() << "' in expression " << expression << ".";
}
}
virtual void visit(expressions::UnaryNumericalFunctionExpression const* expression) override {
expression->getOperand()->accept(this);
msat_term childResult = stack.top();
stack.pop();
switch (expression->getOperatorType()) {
case storm::expressions::UnaryNumericalFunctionExpression::OperatorType::Minus:
stack.push(msat_make_times(env, msat_make_number(env, "-1"), childResult));
break;
default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
<< "Unknown numerical unary operator: '" << expression->getOperatorType() << "'.";
}
}
virtual void visit(expressions::VariableExpression const* expression) override {
if (variableToDeclMap.count(expression->getVariableName()) == 0) {
LOG4CPLUS_ERROR(logger, "Variable " << expression->getVariableName() << " is unknown!");
}
//LOG4CPLUS_TRACE(logger, "Variable "<<expression->getVariableName());
//char* repr = msat_decl_repr(variableToDeclMap.at(expression->getVariableName()));
//LOG4CPLUS_TRACE(logger, "Decl: "<<repr);
//msat_free(repr);
if (MSAT_ERROR_DECL(variableToDeclMap.at(expression->getVariableName()))) {
LOG4CPLUS_WARN(logger, "Encountered an invalid MathSAT declaration");
}
stack.push(msat_make_constant(env, variableToDeclMap.at(expression->getVariableName())));
}
storm::expressions::Expression translateTerm(msat_term term) {
this->processTerm(term);
storm::expressions::Expression result = std::move(expression_stack.top());
expression_stack.pop();
return result;
}
void processTerm(msat_term term) {
if (msat_term_is_and(env, term)) {
this->processTerm(msat_term_get_arg(term, 0));
this->processTerm(msat_term_get_arg(term, 1));
storm::expressions::Expression rightResult = std::move(expression_stack.top());
expression_stack.pop();
storm::expressions::Expression leftResult = std::move(expression_stack.top());
expression_stack.pop();
expression_stack.push(leftResult &&rightResult);
} else if (msat_term_is_or(env, term)) {
this->processTerm(msat_term_get_arg(term, 0));
this->processTerm(msat_term_get_arg(term, 1));
storm::expressions::Expression rightResult = std::move(expression_stack.top());
expression_stack.pop();
storm::expressions::Expression leftResult = std::move(expression_stack.top());
expression_stack.pop();
expression_stack.push(leftResult && rightResult);
} else if (msat_term_is_iff(env, term)) {
this->processTerm(msat_term_get_arg(term, 0));
this->processTerm(msat_term_get_arg(term, 1));
storm::expressions::Expression rightResult = std::move(expression_stack.top());
expression_stack.pop();
storm::expressions::Expression leftResult = std::move(expression_stack.top());
expression_stack.pop();
expression_stack.push(leftResult.iff(rightResult));
} else if (msat_term_is_not(env, term)) {
this->processTerm(msat_term_get_arg(term, 0));
storm::expressions::Expression childResult = std::move(expression_stack.top());
expression_stack.pop();
expression_stack.push(!childResult);
} else if (msat_term_is_plus(env, term)) {
this->processTerm(msat_term_get_arg(term, 0));
this->processTerm(msat_term_get_arg(term, 1));
storm::expressions::Expression rightResult = std::move(expression_stack.top());
expression_stack.pop();
storm::expressions::Expression leftResult = std::move(expression_stack.top());
expression_stack.pop();
expression_stack.push(leftResult+rightResult);
} else if (msat_term_is_times(env, term)) {
this->processTerm(msat_term_get_arg(term, 0));
this->processTerm(msat_term_get_arg(term, 1));
storm::expressions::Expression rightResult = std::move(expression_stack.top());
expression_stack.pop();
storm::expressions::Expression leftResult = std::move(expression_stack.top());
expression_stack.pop();
expression_stack.push(leftResult * rightResult);
} else if (msat_term_is_equal(env, term)) {
this->processTerm(msat_term_get_arg(term, 0));
this->processTerm(msat_term_get_arg(term, 1));
storm::expressions::Expression rightResult = std::move(expression_stack.top());
expression_stack.pop();
storm::expressions::Expression leftResult = std::move(expression_stack.top());
expression_stack.pop();
expression_stack.push(leftResult == rightResult);
} else if (msat_term_is_leq(env, term)) {
this->processTerm(msat_term_get_arg(term, 0));
this->processTerm(msat_term_get_arg(term, 1));
storm::expressions::Expression rightResult = std::move(expression_stack.top());
expression_stack.pop();
storm::expressions::Expression leftResult = std::move(expression_stack.top());
expression_stack.pop();
expression_stack.push(leftResult <= rightResult);
} else if (msat_term_is_true(env, term)) {
expression_stack.push(expressions::Expression::createTrue());
} else if (msat_term_is_false(env, term)) {
expression_stack.push(expressions::Expression::createFalse());
} else if (msat_term_is_boolean_constant(env, term)) {
char* name = msat_decl_get_name(msat_term_get_decl(term));
std::string name_str(name);
expression_stack.push(expressions::Expression::createBooleanVariable(name_str.substr(0, name_str.find('/'))));
msat_free(name);
} else if (msat_term_is_constant(env, term)) {
char* name = msat_decl_get_name(msat_term_get_decl(term));
std::string name_str(name);
if (msat_is_integer_type(env, msat_term_get_type(term))) {
expression_stack.push(expressions::Expression::createIntegerVariable(name_str.substr(0, name_str.find('/'))));
} else if (msat_is_rational_type(env, msat_term_get_type(term))) {
expression_stack.push(expressions::Expression::createDoubleVariable(name_str.substr(0, name_str.find('/'))));
}
msat_free(name);
} else if (msat_term_is_number(env, term)) {
if (msat_is_integer_type(env, msat_term_get_type(term))) {
expression_stack.push(expressions::Expression::createIntegerLiteral(std::stoll(msat_term_repr(term))));
} else if (msat_is_rational_type(env, msat_term_get_type(term))) {
expression_stack.push(expressions::Expression::createDoubleLiteral(std::stod(msat_term_repr(term))));
}
} else {
char* term_cstr = msat_term_repr(term);
std::string term_str(term_cstr);
msat_free(term_cstr);
throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
<< "Unknown term: '" << term_str << "'.";
}
}
private:
msat_env& env;
std::stack<msat_term> stack;
std::stack<expressions::Expression> expression_stack;
std::map<std::string, msat_decl> variableToDeclMap;
};
} // namespace adapters
} // namespace storm
#endif /* STORM_ADAPTERS_MATHSATEXPRESSIONADAPTER_H_ */

321
src/solver/MathSatSmtSolver.cpp

@ -0,0 +1,321 @@
#include "src/solver/MathSatSmtSolver.h"
#include <vector>
namespace storm {
namespace solver {
#ifdef STORM_HAVE_MSAT
MathSatSmtSolver::MathSatModelReference::Z3ModelReference(z3::model &m, storm::adapters::Z3ExpressionAdapter &adapter) : m_model(m), m_adapter(adapter) {
}
#endif
bool MathSatSmtSolver::Z3ModelReference::getBooleanValue(std::string const& name) const {
#ifdef STORM_HAVE_MSAT
z3::expr z3Expr = this->m_adapter.translateExpression(storm::expressions::Expression::createBooleanVariable(name));
z3::expr z3ExprValuation = m_model.eval(z3Expr, true);
return this->m_adapter.translateExpression(z3ExprValuation).evaluateAsBool();
#else
LOG_THROW(false, storm::exceptions::NotImplementedException, "StoRM is compiled without MathSat support.");
#endif
}
int_fast64_t MathSatSmtSolver::Z3ModelReference::getIntegerValue(std::string const& name) const {
#ifdef STORM_HAVE_MSAT
z3::expr z3Expr = this->m_adapter.translateExpression(storm::expressions::Expression::createIntegerVariable(name));
z3::expr z3ExprValuation = m_model.eval(z3Expr, true);
return this->m_adapter.translateExpression(z3ExprValuation).evaluateAsInt();
#else
LOG_THROW(false, storm::exceptions::NotImplementedException, "StoRM is compiled without MathSat support.");
#endif
}
MathSatSmtSolver::MathSatSmtSolver(Options options)
#ifdef STORM_HAVE_MSAT
: lastCheckAssumptions(false)
, lastResult(CheckResult::UNKNOWN)
#endif
{
#ifdef STORM_HAVE_MSAT
m_cfg = msat_create_config();
if (static_cast<int>(options)& static_cast<int>(Options::InterpolantComputation)) {
msat_res = msat_set_option(m_cfg, "interpolation", "true");
if (msat_res != 0) {
LOG4CPLUS_WARN(logger, "MathSAT returned an error!");
}
}
m_env = msat_create_env(m_cfg);
#endif
}
MathSatSmtSolver::~MathSatSmtSolver() {
msat_destroy_env(m_env);
msat_destroy_config(m_cfg);
};
void MathSatSmtSolver::push()
{
#ifdef STORM_HAVE_MSAT
msat_push_backtrack_point(m_env);
#else
LOG_THROW(false, storm::exceptions::NotImplementedException, "StoRM is compiled without MathSat support.");
#endif
}
void MathSatSmtSolver::pop()
{
#ifdef STORM_HAVE_MSAT
msat_pop_backtrack_point(m_env);
#else
LOG_THROW(false, storm::exceptions::NotImplementedException, "StoRM is compiled without MathSat support.");
#endif
}
void MathSatSmtSolver::pop(uint_fast64_t n)
{
#ifdef STORM_HAVE_MSAT
for (uint_fast64_t i = 0; i < n; ++i) {
this->pop();
}
#else
LOG_THROW(false, storm::exceptions::NotImplementedException, "StoRM is compiled without MathSat support.");
#endif
}
void MathSatSmtSolver::reset()
{
#ifdef STORM_HAVE_MSAT
msat_reset_env(m_env);
#else
LOG_THROW(false, storm::exceptions::NotImplementedException, "StoRM is compiled without MathSat support.");
#endif
}
void MathSatSmtSolver::assertExpression(storm::expressions::Expression const& e)
{
#ifdef STORM_HAVE_MSAT
msat_assert_formula(m_env, m_adapter.translateExpression(e, true));
#else
LOG_THROW(false, storm::exceptions::NotImplementedException, "StoRM is compiled without MathSat support.");
#endif
}
SmtSolver::CheckResult MathSatSmtSolver::check()
{
#ifdef STORM_HAVE_MSAT
lastCheckAssumptions = false;
switch (msat_solve(m_env)) {
case MSAT_SAT:
this->lastResult = SmtSolver::CheckResult::SAT;
break;
case MSAT_UNSAT:
this->lastResult = SmtSolver::CheckResult::UNSAT;
break;
default:
this->lastResult = SmtSolver::CheckResult::UNKNOWN;
break;
}
return this->lastResult;
#else
LOG_THROW(false, storm::exceptions::NotImplementedException, "StoRM is compiled without MathSat support.");
#endif
}
SmtSolver::CheckResult MathSatSmtSolver::checkWithAssumptions(std::set<storm::expressions::Expression> const& assumptions)
{
#ifdef STORM_HAVE_MSAT
lastCheckAssumptions = true;
std::vector<msat_term> mathSatAssumptions;
mathSatAssumptions.reserve(assumptions.size());
for (storm::expressions::Expression assumption : assumptions) {
mathSatAssumptions.push_back(this->m_adapter.translateExpression(assumption));
}
switch (msat_solve_with_assumptions(m_env, mathSatAssumptions.data(), mathSatAssumptions.size())) {
case MSAT_SAT:
this->lastResult = SmtSolver::CheckResult::SAT;
break;
case MSAT_UNSAT:
this->lastResult = SmtSolver::CheckResult::UNSAT;
break;
default:
this->lastResult = SmtSolver::CheckResult::UNKNOWN;
break;
}
return this->lastResult;
#else
LOG_THROW(false, storm::exceptions::NotImplementedException, "StoRM is compiled without MathSat support.");
#endif
}
SmtSolver::CheckResult MathSatSmtSolver::checkWithAssumptions(std::initializer_list<storm::expressions::Expression> assumptions)
{
#ifdef STORM_HAVE_MSAT
lastCheckAssumptions = true;
std::vector<msat_term> mathSatAssumptions;
mathSatAssumptions.reserve(assumptions.size());
for (storm::expressions::Expression assumption : assumptions) {
mathSatAssumptions.push_back(this->m_adapter.translateExpression(assumption));
}
switch (msat_solve_with_assumptions(m_env, mathSatAssumptions.data(), mathSatAssumptions.size())) {
case MSAT_SAT:
this->lastResult = SmtSolver::CheckResult::SAT;
break;
case MSAT_UNSAT:
this->lastResult = SmtSolver::CheckResult::UNSAT;
break;
default:
this->lastResult = SmtSolver::CheckResult::UNKNOWN;
break;
}
return this->lastResult;
#else
LOG_THROW(false, storm::exceptions::NotImplementedException, "StoRM is compiled without MathSat support.");
#endif
}
storm::expressions::SimpleValuation MathSatSmtSolver::getModel()
{
#ifdef STORM_HAVE_MSAT
LOG_THROW(this->lastResult == SmtSolver::CheckResult::SAT, storm::exceptions::InvalidStateException, "Requested Model but last check result was not SAT.");
return this->MathSatModelToStorm();
#else
LOG_THROW(false, storm::exceptions::NotImplementedException, "StoRM is compiled without MathSat support.");
#endif
}
#ifdef STORM_HAVE_MSAT
storm::expressions::SimpleValuation MathSatSmtSolver::MathSatModelToStorm() {
storm::expressions::SimpleValuation stormModel;
msat_model_iterator model = msat_create_model_iterator(m_env);
while (msat_model_iterator_has_next(model)) {
msat_term t, v;
msat_model_iterator_next(model, &t, &v);
storm::expressions::Expression var_i_interp = this->m_adapter.translateTerm(v);
char* name = msat_decl_get_name(msat_term_get_decl(t));
switch (var_i_interp.getReturnType()) {
case storm::expressions::ExpressionReturnType::Bool:
stormModel.addBooleanIdentifier(std::string(name), var_i_interp.evaluateAsBool());
break;
case storm::expressions::ExpressionReturnType::Int:
stormModel.addIntegerIdentifier(std::string(name), var_i_interp.evaluateAsInt());
break;
case storm::expressions::ExpressionReturnType::Double:
stormModel.addDoubleIdentifier(std::string(name), var_i_interp.evaluateAsDouble());
break;
default:
LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Variable interpretation in model is not of type bool, int or double.")
break;
}
msat_free(name);
}
return stormModel;
}
#endif
std::vector<storm::expressions::SimpleValuation> MathSatSmtSolver::allSat(std::vector<storm::expressions::Expression> const& important)
{
#ifdef STORM_HAVE_MSAT
std::vector<storm::expressions::SimpleValuation> valuations;
this->allSat(important, [&valuations](storm::expressions::SimpleValuation& valuation) -> bool {valuations.push_back(valuation); return true; });
return valuations;
#else
LOG_THROW(false, storm::exceptions::NotImplementedException, "StoRM is compiled without MathSat support.");
#endif
}
#ifdef STORM_HAVE_MSAT
struct AllsatValuationsCallbackUserData {
msat_env env;
storm::adapters::MathSatExpressionAdapter &adapter;
storm::expressions::SimpleValuation& valuation;
uint_fast64_t n;
};
int allsatValuationsCallback(msat_term *model, int size, void *user_data) {
AllsatValuationsCallbackUserData* user = reinterpret_cast<AllsatValuationsCallbackUserData*>(user_data);
++n;
for (int i = 0; i < size; ++i) {
///
}
}
#endif
uint_fast64_t MathSatSmtSolver::allSat(std::vector<storm::expressions::Expression> const& important, std::function<bool(storm::expressions::SimpleValuation&)> callback)
{
#ifdef STORM_HAVE_MSAT
for (storm::expressions::Expression e : important) {
if (!e.isVariable()) {
throw storm::exceptions::InvalidArgumentException() << "The important expressions for AllSat must be atoms, i.e. variable expressions.";
}
}
return numModels;
#else
LOG_THROW(false, storm::exceptions::NotImplementedException, "StoRM is compiled without MathSat support.");
#endif
}
uint_fast64_t MathSatSmtSolver::allSat(std::function<bool(SmtSolver::ModelReference&)> callback, std::vector<storm::expressions::Expression> const& important)
{
#ifdef STORM_HAVE_MSAT
for (storm::expressions::Expression e : important) {
if (!e.isVariable()) {
throw storm::exceptions::InvalidArgumentException() << "The important expressions for AllSat must be atoms, i.e. variable expressions.";
}
}
return numModels;
#else
LOG_THROW(false, storm::exceptions::NotImplementedException, "StoRM is compiled without MathSat support.");
#endif
}
std::vector<storm::expressions::Expression> MathSatSmtSolver::getUnsatAssumptions() {
#ifdef STORM_HAVE_MSAT
if (lastResult != SmtSolver::CheckResult::UNSAT) {
throw storm::exceptions::InvalidStateException() << "Unsat Assumptions was called but last state is not unsat.";
}
if (!lastCheckAssumptions) {
throw storm::exceptions::InvalidStateException() << "Unsat Assumptions was called but last check had no assumptions.";
}
size_t numUnsatAssumpations;
msat_term* msatUnsatAssumptions = msat_get_unsat_assumptions(m_env, &numUnsatAssumpations);
std::vector<storm::expressions::Expression> unsatAssumptions;
unsatAssumptions.reserve(numUnsatAssumpations);
for (unsigned int i = 0; i < numUnsatAssumpations; ++i) {
unsatAssumptions.push_back(this->m_adapter.translateTerm(msatUnsatAssumptions[i]));
}
return unsatAssumptions;
#else
LOG_THROW(false, storm::exceptions::NotImplementedException, "StoRM is compiled without MathSat support.");
#endif
}
}
}

84
src/solver/MathSatSmtSolver.h

@ -0,0 +1,84 @@
#ifndef STORM_SOLVER_MATHSATSMTSOLVER
#define STORM_SOLVER_MATHSATSMTSOLVER
#include "storm-config.h"
#include "src/solver/SmtSolver.h"
#include "src/adapters/MathSatExpressionAdapter.h"
#ifndef STORM_HAVE_MSAT
#define STORM_HAVE_MSAT
#endif
#ifdef STORM_HAVE_MSAT
#include "mathsat.h"
#endif
namespace storm {
namespace solver {
class MathSatSmtSolver : public SmtSolver {
public:
class MathSatModelReference : public SmtSolver::ModelReference {
public:
#ifdef STORM_HAVE_MSAT
MathSatModelReference(msat_env& env, storm::adapters::MathSatExpressionAdapter &adapter);
#endif
virtual bool getBooleanValue(std::string const& name) const override;
virtual int_fast64_t getIntegerValue(std::string const& name) const override;
private:
#ifdef STORM_HAVE_MSAT
msat_env& env;
storm::adapters::MathSatExpressionAdapter &m_adapter;
#endif
};
public:
MathSatSmtSolver(Options options = Options::ModelGeneration);
virtual ~MathSatSmtSolver();
virtual void push() override;
virtual void pop() override;
virtual void pop(uint_fast64_t n) override;
virtual void reset() override;
virtual void assertExpression(storm::expressions::Expression const& e) override;
virtual CheckResult check() override;
virtual CheckResult checkWithAssumptions(std::set<storm::expressions::Expression> const& assumptions) override;
virtual CheckResult checkWithAssumptions(std::initializer_list<storm::expressions::Expression> assumptions) override;
virtual storm::expressions::SimpleValuation getModel() override;
virtual std::vector<storm::expressions::SimpleValuation> allSat(std::vector<storm::expressions::Expression> const& important) override;
virtual uint_fast64_t allSat(std::vector<storm::expressions::Expression> const& important, std::function<bool(storm::expressions::SimpleValuation&)> callback) override;
virtual uint_fast64_t allSat(std::function<bool(ModelReference&)> callback, std::vector<storm::expressions::Expression> const& important) override;
virtual std::vector<storm::expressions::Expression> getUnsatAssumptions() override;
virtual void setInterpolationGroup(uint_fast64_t group) override;
virtual storm::expressions::Expression getInterpolant(std::vector<uint_fast64_t> groupsA) override;
protected:
#ifdef STORM_HAVE_MSAT
virtual storm::expressions::SimpleValuation MathSatModelToStorm();
#endif
private:
#ifdef STORM_HAVE_MSAT
msat_config m_cfg;
msat_env m_env;
storm::adapters::MathSatExpressionAdapter m_adapter;
bool lastCheckAssumptions;
CheckResult lastResult;
#endif
};
}
}
#endif // STORM_SOLVER_MATHSATSMTSOLVER
Loading…
Cancel
Save