11MathsatSmtSolver::MathsatAllsatModelReference::MathsatAllsatModelReference(
13 std::unordered_map<storm::expressions::Variable, uint_fast64_t>
const& variableToSlotMapping)
14 : ModelReference(
manager), env(env), model(model), variableToSlotMapping(variableToSlotMapping) {
19 std::unordered_map<storm::expressions::Variable, uint_fast64_t>::const_iterator variableSlotPair = variableToSlotMapping.find(variable);
20 STORM_LOG_THROW(variableSlotPair != variableToSlotMapping.end(), storm::exceptions::InvalidArgumentException,
21 "Cannot retrieve value of unknown variable '" << variable.
getName() <<
"' from model.");
22 msat_term selectedTerm = model[variableSlotPair->second];
24 if (msat_term_is_not(env, selectedTerm)) {
32 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Unable to retrieve integer value from model that only contains boolean values.");
36 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Unable to retrieve double value from model that only contains boolean values.");
39std::string MathsatSmtSolver::MathsatAllsatModelReference::toString()
const {
40 std::stringstream str;
43 for (
auto const& varSlot : variableToSlotMapping) {
49 str << varSlot.first.getName() <<
"=" << std::boolalpha << getBooleanValue(varSlot.first);
56 storm::adapters::MathsatExpressionAdapter& expressionAdapter)
57 : ModelReference(
manager), env(env), expressionAdapter(expressionAdapter) {
63 msat_term msatVariable = expressionAdapter.translateExpression(variable);
64 msat_term msatValue = msat_get_model_value(env, msatVariable);
66 !MSAT_ERROR_TERM(msatValue),
67 "Unable to retrieve value of variable in model. This could be caused by calls to the solver between checking for satisfiability and model retrieval.");
74 msat_term msatVariable = expressionAdapter.translateExpression(variable);
75 msat_term msatValue = msat_get_model_value(env, msatVariable);
77 !MSAT_ERROR_TERM(msatValue),
78 "Unable to retrieve value of variable in model. This could be caused by calls to the solver between checking for satisfiability and model retrieval.");
85 msat_term msatVariable = expressionAdapter.translateExpression(variable);
86 msat_term msatValue = msat_get_model_value(env, msatVariable);
88 !MSAT_ERROR_TERM(msatValue),
89 "Unable to retrieve value of variable in model. This could be caused by calls to the solver between checking for satisfiability and model retrieval.");
94std::string MathsatSmtSolver::MathsatModelReference::toString()
const {
95 std::stringstream str;
98 for (
auto const& varDecl : expressionAdapter.getAllDeclaredVariables()) {
104 msat_term msatValue = msat_get_model_value(env, expressionAdapter.translateExpression(varDecl.first));
106 "Unable to retrieve value of variable in model. This could be caused by calls to the solver between checking for satisfiability and "
108 str << varDecl.first.getName() <<
"=" << expressionAdapter.translateExpression(msatValue);
118#ifdef STORM_HAVE_MSAT
120 expressionAdapter(nullptr),
121 lastCheckAssumptions(false),
125#ifdef STORM_HAVE_MSAT
126 msat_config config = msat_create_config();
128 msat_set_option(config,
"interpolation",
"true");
131 msat_set_option(config,
"model_generation",
"true");
134 msat_set_option(config,
"unsat_core_generation",
"true");
136 STORM_LOG_THROW(!MSAT_ERROR_CONFIG(config), storm::exceptions::UnexpectedException,
"Unable to create Mathsat configuration.");
139 env = msat_create_env(config);
140 STORM_LOG_THROW(!MSAT_ERROR_ENV(env), storm::exceptions::UnexpectedException,
"Unable to create Mathsat environment.");
141 msat_destroy_config(config);
143 expressionAdapter = std::unique_ptr<storm::adapters::MathsatExpressionAdapter>(
new storm::adapters::MathsatExpressionAdapter(manager, env));
150#ifdef STORM_HAVE_MSAT
151 if (!MSAT_ERROR_ENV(env)) {
152 msat_destroy_env(env);
162#ifdef STORM_HAVE_MSAT
163 msat_push_backtrack_point(env);
165 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Storm is compiled without MathSAT support.");
170#ifdef STORM_HAVE_MSAT
171 msat_pop_backtrack_point(env);
173 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Storm is compiled without MathSAT support.");
178#ifdef STORM_HAVE_MSAT
182 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Storm is compiled without MathSAT support.");
187#ifdef STORM_HAVE_MSAT
190 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Storm is compiled without MathSAT support.");
195#ifdef STORM_HAVE_MSAT
196 msat_term expression = expressionAdapter->translateExpression(e);
197 msat_assert_formula(env, expression);
198 if (expressionAdapter->hasAdditionalConstraints()) {
199 for (
auto const& constraint : expressionAdapter->getAdditionalConstraints()) {
200 msat_assert_formula(env, constraint);
205 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Storm is compiled without MathSAT support.");
210#ifdef STORM_HAVE_MSAT
211 lastCheckAssumptions =
false;
212 switch (msat_solve(env)) {
223 return this->lastResult;
225 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Storm is compiled without MathSAT support.");
230#ifdef STORM_HAVE_MSAT
231 lastCheckAssumptions =
true;
232 std::vector<msat_term> mathSatAssumptions;
233 mathSatAssumptions.reserve(assumptions.size());
236 mathSatAssumptions.push_back(this->expressionAdapter->translateExpression(assumption));
239 switch (msat_solve_with_assumptions(env, mathSatAssumptions.data(), mathSatAssumptions.size())) {
250 return this->lastResult;
253 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Storm is compiled without MathSAT support.");
258#ifdef STORM_HAVE_MSAT
259 lastCheckAssumptions =
true;
260 std::vector<msat_term> mathSatAssumptions;
261 mathSatAssumptions.reserve(assumptions.size());
264 mathSatAssumptions.push_back(this->expressionAdapter->translateExpression(assumption));
267 switch (msat_solve_with_assumptions(env, mathSatAssumptions.data(), mathSatAssumptions.size())) {
278 return this->lastResult;
281 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Storm is compiled without MathSAT support.");
286#ifdef STORM_HAVE_MSAT
288 "Unable to create model for formula that was not determined to be satisfiable.");
289 return this->convertMathsatModelToValuation();
291 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Storm is compiled without MathSAT support.");
296#ifdef STORM_HAVE_MSAT
298 "Unable to create model for formula that was not determined to be satisfiable.");
299 return std::shared_ptr<SmtSolver::ModelReference>(
new MathsatModelReference(this->
getManager(), env, *expressionAdapter));
301 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Storm is compiled without MathSAT support.");
305#ifdef STORM_HAVE_MSAT
309 msat_model_iterator modelIterator = msat_create_model_iterator(env);
310 STORM_LOG_THROW(!MSAT_ERROR_MODEL_ITERATOR(modelIterator), storm::exceptions::UnexpectedException,
"MathSat returned an illegal model iterator.");
312 while (msat_model_iterator_has_next(modelIterator)) {
314 msat_model_iterator_next(modelIterator, &t, &v);
320 stormModel.setBooleanValue(stormVariable, variableInterpretation.
isTrue());
322 stormModel.setIntegerValue(stormVariable, variableInterpretation.
evaluateAsInt());
324 stormModel.setRationalValue(stormVariable, variableInterpretation.
evaluateAsDouble());
326 STORM_LOG_THROW(
false, storm::exceptions::ExpressionEvaluationException,
"Variable interpretation in model is not of type bool, int or rational.");
334std::vector<storm::expressions::SimpleValuation>
MathsatSmtSolver::allSat(std::vector<storm::expressions::Variable>
const& important) {
335#ifdef STORM_HAVE_MSAT
336 std::vector<storm::expressions::SimpleValuation> valuations;
338 valuations.push_back(valuation);
344 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Storm is compiled without MathSAT support.");
348#ifdef STORM_HAVE_MSAT
349class AllsatValuationCallbackUserData {
353 : manager(manager), adapter(adapter), env(env), callback(callback) {
357 static int allsatValuationsCallback(msat_term* model,
int size,
void* user_data) {
358 AllsatValuationCallbackUserData* user =
reinterpret_cast<AllsatValuationCallbackUserData*
>(user_data);
361 for (
int i = 0; i < size; ++i) {
362 bool currentTermValue =
true;
363 msat_term currentTerm = model[i];
364 if (msat_term_is_not(user->env, currentTerm)) {
365 currentTerm = msat_term_get_arg(currentTerm, 0);
366 currentTermValue =
false;
369 valuation.setBooleanValue(stormVariable, currentTermValue);
372 if (user->callback(valuation)) {
384 storm::adapters::MathsatExpressionAdapter& adapter;
393class AllsatModelReferenceCallbackUserData {
396 std::unordered_map<storm::expressions::Variable, uint_fast64_t>
const& atomToSlotMapping,
398 :
manager(
manager), env(env), atomToSlotMapping(atomToSlotMapping), callback(callback) {
402 static int allsatModelReferenceCallback(msat_term* model,
int,
void* user_data) {
403 AllsatModelReferenceCallbackUserData* user =
reinterpret_cast<AllsatModelReferenceCallbackUserData*
>(user_data);
404 MathsatSmtSolver::MathsatAllsatModelReference modelReference(user->manager, user->env, model, user->atomToSlotMapping);
405 if (user->callback(modelReference)) {
420 std::unordered_map<storm::expressions::Variable, uint_fast64_t>
const& atomToSlotMapping;
429#ifdef STORM_HAVE_MSAT
433 std::vector<msat_term> msatImportant;
434 msatImportant.reserve(important.size());
437 STORM_LOG_THROW(variable.
hasBooleanType(), storm::exceptions::InvalidArgumentException,
"The important atoms for AllSat must be boolean variables.");
438 msatImportant.push_back(expressionAdapter->translateExpression(variable));
441 AllsatValuationCallbackUserData allSatUserData(this->
getManager(), *expressionAdapter, env, callback);
443 msat_all_sat(env, msatImportant.data(), msatImportant.size(), &AllsatValuationCallbackUserData::allsatValuationsCallback, &allSatUserData);
447 return static_cast<uint_fast64_t
>(numberOfModels);
451 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Storm is compiled without MathSAT support.");
457#ifdef STORM_HAVE_MSAT
461 std::vector<msat_term> msatImportant;
462 msatImportant.reserve(important.size());
463 std::unordered_map<storm::expressions::Variable, uint_fast64_t> atomToSlotMapping;
466 STORM_LOG_THROW(variable.
hasBooleanType(), storm::exceptions::InvalidArgumentException,
"The important atoms for AllSat must be boolean variables.");
467 msatImportant.push_back(expressionAdapter->translateExpression(variable));
468 atomToSlotMapping[variable] = msatImportant.size() - 1;
471 AllsatModelReferenceCallbackUserData allSatUserData(this->
getManager(), env, atomToSlotMapping, callback);
473 msat_all_sat(env, msatImportant.data(), msatImportant.size(), &AllsatModelReferenceCallbackUserData::allsatModelReferenceCallback, &allSatUserData);
477 return static_cast<uint_fast64_t
>(numberOfModels);
481 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Storm is compiled without MathSAT support.");
486#ifdef STORM_HAVE_MSAT
488 "Unable to generate unsatisfiable core of assumptions, because the last check did not determine the formulas to be unsatisfiable.");
489 STORM_LOG_THROW(lastCheckAssumptions, storm::exceptions::InvalidStateException,
490 "Unable to generate unsatisfiable core of assumptions, because the last check did not involve assumptions.");
492 size_t numUnsatAssumpations;
493 msat_term* msatUnsatAssumptions = msat_get_unsat_assumptions(env, &numUnsatAssumpations);
495 std::vector<storm::expressions::Expression> unsatAssumptions;
496 unsatAssumptions.reserve(numUnsatAssumpations);
498 for (
unsigned int i = 0; i < numUnsatAssumpations; ++i) {
499 unsatAssumptions.push_back(this->expressionAdapter->translateExpression(msatUnsatAssumptions[i]));
502 return unsatAssumptions;
504 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Storm is compiled without MathSAT support.");
509#ifdef STORM_HAVE_MSAT
510 auto groupIter = this->interpolationGroups.find(group);
511 if (groupIter == this->interpolationGroups.end()) {
512 int newGroup = msat_create_itp_group(env);
513 auto insertResult = this->interpolationGroups.insert(std::make_pair(group, newGroup));
514 groupIter = insertResult.first;
516 msat_set_itp_group(env, groupIter->second);
519 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Storm is compiled without MathSAT support.");
524#ifdef STORM_HAVE_MSAT
526 "Unable to generate interpolant, because the last check did not determine the formulas to be unsatisfiable.");
527 STORM_LOG_THROW(!lastCheckAssumptions, storm::exceptions::InvalidStateException,
528 "Unable to generate interpolant, because the last check for satisfiability involved assumptions.");
530 std::vector<int> msatInterpolationGroupsA;
531 msatInterpolationGroupsA.reserve(groupsA.size());
532 for (
auto groupOfA : groupsA) {
533 auto groupIter = this->interpolationGroups.find(groupOfA);
534 STORM_LOG_THROW(groupIter != this->interpolationGroups.end(), storm::exceptions::InvalidArgumentException,
535 "Unable to generate interpolant, because an unknown interpolation group was referenced.");
536 msatInterpolationGroupsA.push_back(groupIter->second);
538 msat_term interpolant = msat_get_interpolant(env, msatInterpolationGroupsA.data(), msatInterpolationGroupsA.size());
540 STORM_LOG_THROW(!MSAT_ERROR_TERM(interpolant), storm::exceptions::UnexpectedException,
"Unable to retrieve an interpolant.");
542 return this->expressionAdapter->translateExpression(interpolant);
545 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"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.
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.
An interface that captures the functionality of an SMT solver.
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.
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.