11#ifdef STORM_HAVE_MATHSAT
12MathsatSmtSolver::MathsatAllsatModelReference::MathsatAllsatModelReference(
13 storm::expressions::ExpressionManager
const& manager, msat_env
const& env, msat_term* model,
14 std::unordered_map<storm::expressions::Variable, uint_fast64_t>
const& variableToSlotMapping)
15 : ModelReference(
manager), env(env), model(model), variableToSlotMapping(variableToSlotMapping) {
20 std::unordered_map<storm::expressions::Variable, uint_fast64_t>::const_iterator variableSlotPair = variableToSlotMapping.find(variable);
21 STORM_LOG_THROW(variableSlotPair != variableToSlotMapping.end(), storm::exceptions::InvalidArgumentException,
22 "Cannot retrieve value of unknown variable '" << variable.
getName() <<
"' from model.");
23 msat_term selectedTerm = model[variableSlotPair->second];
25 if (msat_term_is_not(env, selectedTerm)) {
33 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Unable to retrieve integer value from model that only contains boolean values.");
37 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Unable to retrieve double value from model that only contains boolean values.");
40std::string MathsatSmtSolver::MathsatAllsatModelReference::toString()
const {
41 std::stringstream str;
44 for (
auto const& varSlot : variableToSlotMapping) {
50 str << varSlot.first.getName() <<
"=" << std::boolalpha << getBooleanValue(varSlot.first);
57 storm::adapters::MathsatExpressionAdapter& expressionAdapter)
58 : ModelReference(
manager), env(env), expressionAdapter(expressionAdapter) {
64 msat_term msatVariable = expressionAdapter.translateExpression(variable);
65 msat_term msatValue = msat_get_model_value(env, msatVariable);
67 !MSAT_ERROR_TERM(msatValue),
68 "Unable to retrieve value of variable in model. This could be caused by calls to the solver between checking for satisfiability and model retrieval.");
75 msat_term msatVariable = expressionAdapter.translateExpression(variable);
76 msat_term msatValue = msat_get_model_value(env, msatVariable);
78 !MSAT_ERROR_TERM(msatValue),
79 "Unable to retrieve value of variable in model. This could be caused by calls to the solver between checking for satisfiability and model retrieval.");
86 msat_term msatVariable = expressionAdapter.translateExpression(variable);
87 msat_term msatValue = msat_get_model_value(env, msatVariable);
89 !MSAT_ERROR_TERM(msatValue),
90 "Unable to retrieve value of variable in model. This could be caused by calls to the solver between checking for satisfiability and model retrieval.");
95std::string MathsatSmtSolver::MathsatModelReference::toString()
const {
96 std::stringstream str;
99 for (
auto const& varDecl : expressionAdapter.getAllDeclaredVariables()) {
105 msat_term msatValue = msat_get_model_value(env, expressionAdapter.translateExpression(varDecl.first));
107 "Unable to retrieve value of variable in model. This could be caused by calls to the solver between checking for satisfiability and "
109 str << varDecl.first.getName() <<
"=" << expressionAdapter.translateExpression(msatValue);
119#ifdef STORM_HAVE_MATHSAT
121 expressionAdapter(nullptr),
122 lastCheckAssumptions(false),
126#ifdef STORM_HAVE_MATHSAT
127 msat_config config = msat_create_config();
129 msat_set_option(config,
"interpolation",
"true");
132 msat_set_option(config,
"model_generation",
"true");
135 msat_set_option(config,
"unsat_core_generation",
"true");
137 STORM_LOG_THROW(!MSAT_ERROR_CONFIG(config), storm::exceptions::UnexpectedException,
"Unable to create Mathsat configuration.");
140 env = msat_create_env(config);
141 STORM_LOG_THROW(!MSAT_ERROR_ENV(env), storm::exceptions::UnexpectedException,
"Unable to create Mathsat environment.");
142 msat_destroy_config(config);
144 expressionAdapter = std::make_unique<storm::adapters::MathsatExpressionAdapter>(manager, env);
151#ifdef STORM_HAVE_MATHSAT
152 if (!MSAT_ERROR_ENV(env)) {
153 msat_destroy_env(env);
163#ifdef STORM_HAVE_MATHSAT
164 msat_push_backtrack_point(env);
166 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
171#ifdef STORM_HAVE_MATHSAT
172 msat_pop_backtrack_point(env);
174 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
179#ifdef STORM_HAVE_MATHSAT
183 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
188#ifdef STORM_HAVE_MATHSAT
191 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
196#ifdef STORM_HAVE_MATHSAT
197 msat_term expression = expressionAdapter->translateExpression(e);
198 msat_assert_formula(env, expression);
199 if (expressionAdapter->hasAdditionalConstraints()) {
200 for (
auto const& constraint : expressionAdapter->getAdditionalConstraints()) {
201 msat_assert_formula(env, constraint);
206 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
211#ifdef STORM_HAVE_MATHSAT
212 lastCheckAssumptions =
false;
213 switch (msat_solve(env)) {
224 return this->lastResult;
226 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
231#ifdef STORM_HAVE_MATHSAT
232 lastCheckAssumptions =
true;
233 std::vector<msat_term> mathSatAssumptions;
234 mathSatAssumptions.reserve(assumptions.size());
237 mathSatAssumptions.push_back(this->expressionAdapter->translateExpression(assumption));
240 switch (msat_solve_with_assumptions(env, mathSatAssumptions.data(), mathSatAssumptions.size())) {
251 return this->lastResult;
254 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
259#ifdef STORM_HAVE_MATHSAT
260 lastCheckAssumptions =
true;
261 std::vector<msat_term> mathSatAssumptions;
262 mathSatAssumptions.reserve(assumptions.size());
265 mathSatAssumptions.push_back(this->expressionAdapter->translateExpression(assumption));
268 switch (msat_solve_with_assumptions(env, mathSatAssumptions.data(), mathSatAssumptions.size())) {
279 return this->lastResult;
282 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
287#ifdef STORM_HAVE_MATHSAT
289 "Unable to create model for formula that was not determined to be satisfiable.");
290 return this->convertMathsatModelToValuation();
292 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
297#ifdef STORM_HAVE_MATHSAT
299 "Unable to create model for formula that was not determined to be satisfiable.");
300 return std::shared_ptr<SmtSolver::ModelReference>(
new MathsatModelReference(this->
getManager(), env, *expressionAdapter));
302 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
306#ifdef STORM_HAVE_MATHSAT
310 msat_model_iterator modelIterator = msat_create_model_iterator(env);
311 STORM_LOG_THROW(!MSAT_ERROR_MODEL_ITERATOR(modelIterator), storm::exceptions::UnexpectedException,
"MathSat returned an illegal model iterator.");
313 while (msat_model_iterator_has_next(modelIterator)) {
315 msat_model_iterator_next(modelIterator, &t, &v);
321 stormModel.setBooleanValue(stormVariable, variableInterpretation.
isTrue());
323 stormModel.setIntegerValue(stormVariable, variableInterpretation.
evaluateAsInt());
325 stormModel.setRationalValue(stormVariable, variableInterpretation.
evaluateAsDouble());
327 STORM_LOG_THROW(
false, storm::exceptions::ExpressionEvaluationException,
"Variable interpretation in model is not of type bool, int or rational.");
335std::vector<storm::expressions::SimpleValuation>
MathsatSmtSolver::allSat(std::vector<storm::expressions::Variable>
const& important) {
336#ifdef STORM_HAVE_MATHSAT
337 std::vector<storm::expressions::SimpleValuation> valuations;
339 valuations.push_back(valuation);
345 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
349#ifdef STORM_HAVE_MATHSAT
350class AllsatValuationCallbackUserData {
354 : manager(manager), adapter(adapter), env(env), callback(callback) {
358 static int allsatValuationsCallback(msat_term* model,
int size,
void* user_data) {
359 AllsatValuationCallbackUserData* user =
reinterpret_cast<AllsatValuationCallbackUserData*
>(user_data);
362 for (
int i = 0; i < size; ++i) {
363 bool currentTermValue =
true;
364 msat_term currentTerm = model[i];
365 if (msat_term_is_not(user->env, currentTerm)) {
366 currentTerm = msat_term_get_arg(currentTerm, 0);
367 currentTermValue =
false;
370 valuation.setBooleanValue(stormVariable, currentTermValue);
373 if (user->callback(valuation)) {
382 storm::expressions::ExpressionManager
const&
manager;
385 storm::adapters::MathsatExpressionAdapter& adapter;
391 std::function<bool(storm::expressions::SimpleValuation&)>
const& callback;
394class AllsatModelReferenceCallbackUserData {
396 AllsatModelReferenceCallbackUserData(storm::expressions::ExpressionManager
const& manager, msat_env& env,
397 std::unordered_map<storm::expressions::Variable, uint_fast64_t>
const& atomToSlotMapping,
398 std::function<
bool(storm::solver::SmtSolver::ModelReference&)>
const& callback)
399 :
manager(
manager), env(env), atomToSlotMapping(atomToSlotMapping), callback(callback) {
403 static int allsatModelReferenceCallback(msat_term* model,
int,
void* user_data) {
404 AllsatModelReferenceCallbackUserData* user =
reinterpret_cast<AllsatModelReferenceCallbackUserData*
>(user_data);
405 MathsatSmtSolver::MathsatAllsatModelReference modelReference(user->manager, user->env, model, user->atomToSlotMapping);
406 if (user->callback(modelReference)) {
415 storm::expressions::ExpressionManager
const&
manager;
421 std::unordered_map<storm::expressions::Variable, uint_fast64_t>
const& atomToSlotMapping;
424 std::function<bool(storm::solver::SmtSolver::ModelReference&)>
const& callback;
430#ifdef STORM_HAVE_MATHSAT
434 std::vector<msat_term> msatImportant;
435 msatImportant.reserve(important.size());
438 STORM_LOG_THROW(variable.
hasBooleanType(), storm::exceptions::InvalidArgumentException,
"The important atoms for AllSat must be boolean variables.");
439 msatImportant.push_back(expressionAdapter->translateExpression(variable));
442 AllsatValuationCallbackUserData allSatUserData(this->
getManager(), *expressionAdapter, env, callback);
444 msat_all_sat(env, msatImportant.data(), msatImportant.size(), &AllsatValuationCallbackUserData::allsatValuationsCallback, &allSatUserData);
448 return static_cast<uint_fast64_t
>(numberOfModels);
452 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
458#ifdef STORM_HAVE_MATHSAT
462 std::vector<msat_term> msatImportant;
463 msatImportant.reserve(important.size());
464 std::unordered_map<storm::expressions::Variable, uint_fast64_t> atomToSlotMapping;
467 STORM_LOG_THROW(variable.
hasBooleanType(), storm::exceptions::InvalidArgumentException,
"The important atoms for AllSat must be boolean variables.");
468 msatImportant.push_back(expressionAdapter->translateExpression(variable));
469 atomToSlotMapping[variable] = msatImportant.size() - 1;
472 AllsatModelReferenceCallbackUserData allSatUserData(this->
getManager(), env, atomToSlotMapping, callback);
474 msat_all_sat(env, msatImportant.data(), msatImportant.size(), &AllsatModelReferenceCallbackUserData::allsatModelReferenceCallback, &allSatUserData);
478 return static_cast<uint_fast64_t
>(numberOfModels);
482 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
487#ifdef STORM_HAVE_MATHSAT
489 "Unable to generate unsatisfiable core of assumptions, because the last check did not determine the formulas to be unsatisfiable.");
490 STORM_LOG_THROW(lastCheckAssumptions, storm::exceptions::InvalidStateException,
491 "Unable to generate unsatisfiable core of assumptions, because the last check did not involve assumptions.");
493 size_t numUnsatAssumpations;
494 msat_term* msatUnsatAssumptions = msat_get_unsat_assumptions(env, &numUnsatAssumpations);
496 std::vector<storm::expressions::Expression> unsatAssumptions;
497 unsatAssumptions.reserve(numUnsatAssumpations);
499 for (
unsigned int i = 0; i < numUnsatAssumpations; ++i) {
500 unsatAssumptions.push_back(this->expressionAdapter->translateExpression(msatUnsatAssumptions[i]));
503 return unsatAssumptions;
505 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
510#ifdef STORM_HAVE_MATHSAT
511 auto groupIter = this->interpolationGroups.find(group);
512 if (groupIter == this->interpolationGroups.end()) {
513 int newGroup = msat_create_itp_group(env);
514 auto insertResult = this->interpolationGroups.insert(std::make_pair(group, newGroup));
515 groupIter = insertResult.first;
517 msat_set_itp_group(env, groupIter->second);
520 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
525#ifdef STORM_HAVE_MATHSAT
527 "Unable to generate interpolant, because the last check did not determine the formulas to be unsatisfiable.");
528 STORM_LOG_THROW(!lastCheckAssumptions, storm::exceptions::InvalidStateException,
529 "Unable to generate interpolant, because the last check for satisfiability involved assumptions.");
531 std::vector<int> msatInterpolationGroupsA;
532 msatInterpolationGroupsA.reserve(groupsA.size());
533 for (
auto groupOfA : groupsA) {
534 auto groupIter = this->interpolationGroups.find(groupOfA);
535 STORM_LOG_THROW(groupIter != this->interpolationGroups.end(), storm::exceptions::InvalidArgumentException,
536 "Unable to generate interpolant, because an unknown interpolation group was referenced.");
537 msatInterpolationGroupsA.push_back(groupIter->second);
539 msat_term interpolant = msat_get_interpolant(env, msatInterpolationGroupsA.data(), msatInterpolationGroupsA.size());
541 STORM_LOG_THROW(!MSAT_ERROR_TERM(interpolant), storm::exceptions::UnexpectedException,
"Unable to retrieve an interpolant.");
543 return this->expressionAdapter->translateExpression(interpolant);
546 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
int_fast64_t evaluateAsInt(Valuation const *valuation=nullptr) const
Evaluates the expression under the valuation of variables given by the valuation and returns the resu...
bool evaluateAsBool(Valuation const *valuation=nullptr) const
Evaluates the expression under the valuation of variables given by the valuation and returns the resu...
double evaluateAsDouble(Valuation const *valuation=nullptr) const
Evaluates the expression under the valuation of variables given by the valuation and returns the resu...
bool isTrue() const
Checks if the expression is equal to the boolean literal true.
This class is responsible for managing a set of typed variables and all expressions using these varia...
A simple implementation of the valuation interface.
bool hasBooleanType() const
Checks whether the variable is of boolean type.
bool hasIntegerType() const
Checks whether the variable is of integral type.
bool hasRationalType() const
Checks whether the variable is of rational type.
std::string const & getName() const
Retrieves the name of the variable.
A class that captures options that may be passed to the Mathsat solver.
bool enableUnsatCoreGeneration
bool enableModelGeneration
bool enableInterpolantGeneration
virtual std::vector< storm::expressions::Expression > getUnsatAssumptions() override
If the last call to checkWithAssumptions() returned Unsat, this function can be used to retrieve a su...
virtual storm::expressions::Expression getInterpolant(std::vector< uint_fast64_t > const &groupsA) override
If the last call to check() returned Unsat, the solver has been instantiated with support for interpo...
virtual std::shared_ptr< SmtSolver::ModelReference > getModel() override
If the last call to check() or checkWithAssumptions() returned Sat, this method retrieves a model tha...
virtual void add(storm::expressions::Expression const &assertion) override
Adds an assertion to the solver's stack.
MathsatSmtSolver(storm::expressions::ExpressionManager &manager, Options const &options=Options())
virtual void pop() override
Pops a backtracking point from the solver's stack.
virtual CheckResult check() override
Checks whether the conjunction of assertions that are currently on the solver's stack is satisfiable.
virtual void reset() override
Removes all assertions from the solver's stack.
virtual std::vector< storm::expressions::SimpleValuation > allSat(std::vector< storm::expressions::Variable > const &important) override
Performs AllSat over the (provided) important atoms.
virtual ~MathsatSmtSolver()
virtual void push() override
Pushes a backtracking point on the solver's stack.
virtual CheckResult checkWithAssumptions(std::set< storm::expressions::Expression > const &assumptions) override
Checks whether the conjunction of assertions that are currently on the solver's stack together with t...
virtual storm::expressions::SimpleValuation getModelAsValuation() override
If the last call to check() or checkWithAssumptions() returned Sat, this method retrieves a model tha...
virtual void setInterpolationGroup(uint_fast64_t group) override
Sets the current interpolation group.
The base class for all model references.
virtual void pop()=0
Pops a backtracking point from the solver's stack.
storm::expressions::ExpressionManager const & getManager() const
Retrieves the expression manager associated with the solver.
SmtSolver(storm::expressions::ExpressionManager &manager)
Constructs a new Smt solver with the given options.
CheckResult
possible check results
#define STORM_LOG_ERROR(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
SettingsManager const & manager()
Retrieves the settings manager.