13#ifdef STORM_HAVE_MATHSAT
14MathsatSmtSolver::MathsatAllsatModelReference::MathsatAllsatModelReference(
15 storm::expressions::ExpressionManager
const& manager, msat_env
const& env, msat_term* model,
16 std::unordered_map<storm::expressions::Variable, uint_fast64_t>
const& variableToSlotMapping)
17 : ModelReference(
manager), env(env), model(model), variableToSlotMapping(variableToSlotMapping) {
22 std::unordered_map<storm::expressions::Variable, uint_fast64_t>::const_iterator variableSlotPair = variableToSlotMapping.find(variable);
23 STORM_LOG_THROW(variableSlotPair != variableToSlotMapping.end(), storm::exceptions::InvalidArgumentException,
24 "Cannot retrieve value of unknown variable '" << variable.
getName() <<
"' from model.");
25 msat_term selectedTerm = model[variableSlotPair->second];
27 if (msat_term_is_not(env, selectedTerm)) {
35 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Unable to retrieve integer value from model that only contains boolean values.");
39 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Unable to retrieve double value from model that only contains boolean values.");
42std::string MathsatSmtSolver::MathsatAllsatModelReference::toString()
const {
43 std::stringstream str;
46 for (
auto const& varSlot : variableToSlotMapping) {
52 str << varSlot.first.getName() <<
"=" << std::boolalpha << getBooleanValue(varSlot.first);
59 storm::adapters::MathsatExpressionAdapter& expressionAdapter)
60 : ModelReference(
manager), env(env), expressionAdapter(expressionAdapter) {
66 msat_term msatVariable = expressionAdapter.translateExpression(variable);
67 msat_term msatValue = msat_get_model_value(env, msatVariable);
69 !MSAT_ERROR_TERM(msatValue),
70 "Unable to retrieve value of variable in model. This could be caused by calls to the solver between checking for satisfiability and model retrieval.");
77 msat_term msatVariable = expressionAdapter.translateExpression(variable);
78 msat_term msatValue = msat_get_model_value(env, msatVariable);
80 !MSAT_ERROR_TERM(msatValue),
81 "Unable to retrieve value of variable in model. This could be caused by calls to the solver between checking for satisfiability and model retrieval.");
88 msat_term msatVariable = expressionAdapter.translateExpression(variable);
89 msat_term msatValue = msat_get_model_value(env, msatVariable);
91 !MSAT_ERROR_TERM(msatValue),
92 "Unable to retrieve value of variable in model. This could be caused by calls to the solver between checking for satisfiability and model retrieval.");
97std::string MathsatSmtSolver::MathsatModelReference::toString()
const {
98 std::stringstream str;
101 for (
auto const& varDecl : expressionAdapter.getAllDeclaredVariables()) {
107 msat_term msatValue = msat_get_model_value(env, expressionAdapter.translateExpression(varDecl.first));
109 "Unable to retrieve value of variable in model. This could be caused by calls to the solver between checking for satisfiability and "
111 str << varDecl.first.getName() <<
"=" << expressionAdapter.translateExpression(msatValue);
121#ifdef STORM_HAVE_MATHSAT
123 expressionAdapter(nullptr),
124 lastCheckAssumptions(false),
128#ifdef STORM_HAVE_MATHSAT
129 msat_config config = msat_create_config();
131 msat_set_option(config,
"interpolation",
"true");
134 msat_set_option(config,
"model_generation",
"true");
137 msat_set_option(config,
"unsat_core_generation",
"true");
139 STORM_LOG_THROW(!MSAT_ERROR_CONFIG(config), storm::exceptions::UnexpectedException,
"Unable to create Mathsat configuration.");
142 env = msat_create_env(config);
143 STORM_LOG_THROW(!MSAT_ERROR_ENV(env), storm::exceptions::UnexpectedException,
"Unable to create Mathsat environment.");
144 msat_destroy_config(config);
146 expressionAdapter = std::make_unique<storm::adapters::MathsatExpressionAdapter>(manager, env);
153#ifdef STORM_HAVE_MATHSAT
154 if (!MSAT_ERROR_ENV(env)) {
155 msat_destroy_env(env);
165#ifdef STORM_HAVE_MATHSAT
166 msat_push_backtrack_point(env);
168 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
173#ifdef STORM_HAVE_MATHSAT
174 msat_pop_backtrack_point(env);
176 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
181#ifdef STORM_HAVE_MATHSAT
185 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
190#ifdef STORM_HAVE_MATHSAT
193 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
198#ifdef STORM_HAVE_MATHSAT
199 msat_term expression = expressionAdapter->translateExpression(e);
200 msat_assert_formula(env, expression);
201 if (expressionAdapter->hasAdditionalConstraints()) {
202 for (
auto const& constraint : expressionAdapter->getAdditionalConstraints()) {
203 msat_assert_formula(env, constraint);
208 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
213#ifdef STORM_HAVE_MATHSAT
214 lastCheckAssumptions =
false;
215 switch (msat_solve(env)) {
226 return this->lastResult;
228 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
233#ifdef STORM_HAVE_MATHSAT
234 lastCheckAssumptions =
true;
235 std::vector<msat_term> mathSatAssumptions;
236 mathSatAssumptions.reserve(assumptions.size());
239 mathSatAssumptions.push_back(this->expressionAdapter->translateExpression(assumption));
242 switch (msat_solve_with_assumptions(env, mathSatAssumptions.data(), mathSatAssumptions.size())) {
253 return this->lastResult;
256 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
261#ifdef STORM_HAVE_MATHSAT
262 lastCheckAssumptions =
true;
263 std::vector<msat_term> mathSatAssumptions;
264 mathSatAssumptions.reserve(assumptions.size());
267 mathSatAssumptions.push_back(this->expressionAdapter->translateExpression(assumption));
270 switch (msat_solve_with_assumptions(env, mathSatAssumptions.data(), mathSatAssumptions.size())) {
281 return this->lastResult;
284 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
289#ifdef STORM_HAVE_MATHSAT
291 "Unable to create model for formula that was not determined to be satisfiable.");
292 return this->convertMathsatModelToValuation();
294 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
299#ifdef STORM_HAVE_MATHSAT
301 "Unable to create model for formula that was not determined to be satisfiable.");
302 return std::shared_ptr<SmtSolver::ModelReference>(
new MathsatModelReference(this->
getManager(), env, *expressionAdapter));
304 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
308#ifdef STORM_HAVE_MATHSAT
312 msat_model_iterator modelIterator = msat_create_model_iterator(env);
313 STORM_LOG_THROW(!MSAT_ERROR_MODEL_ITERATOR(modelIterator), storm::exceptions::UnexpectedException,
"MathSat returned an illegal model iterator.");
315 while (msat_model_iterator_has_next(modelIterator)) {
317 msat_model_iterator_next(modelIterator, &t, &v);
323 stormModel.setBooleanValue(stormVariable, variableInterpretation.
isTrue());
325 stormModel.setIntegerValue(stormVariable, variableInterpretation.
evaluateAsInt());
327 stormModel.setRationalValue(stormVariable, variableInterpretation.
evaluateAsDouble());
329 STORM_LOG_THROW(
false, storm::exceptions::ExpressionEvaluationException,
"Variable interpretation in model is not of type bool, int or rational.");
337std::vector<storm::expressions::SimpleValuation>
MathsatSmtSolver::allSat(std::vector<storm::expressions::Variable>
const& important) {
338#ifdef STORM_HAVE_MATHSAT
339 std::vector<storm::expressions::SimpleValuation> valuations;
341 valuations.push_back(valuation);
347 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
351#ifdef STORM_HAVE_MATHSAT
352class AllsatValuationCallbackUserData {
356 : manager(manager), adapter(adapter), env(env), callback(callback) {
360 static int allsatValuationsCallback(msat_term* model,
int size,
void* user_data) {
361 AllsatValuationCallbackUserData* user =
reinterpret_cast<AllsatValuationCallbackUserData*
>(user_data);
364 for (
int i = 0; i < size; ++i) {
365 bool currentTermValue =
true;
366 msat_term currentTerm = model[i];
367 if (msat_term_is_not(user->env, currentTerm)) {
368 currentTerm = msat_term_get_arg(currentTerm, 0);
369 currentTermValue =
false;
372 valuation.setBooleanValue(stormVariable, currentTermValue);
375 if (user->callback(valuation)) {
384 storm::expressions::ExpressionManager
const&
manager;
387 storm::adapters::MathsatExpressionAdapter& adapter;
393 std::function<bool(storm::expressions::SimpleValuation&)>
const& callback;
396class AllsatModelReferenceCallbackUserData {
398 AllsatModelReferenceCallbackUserData(storm::expressions::ExpressionManager
const& manager, msat_env& env,
399 std::unordered_map<storm::expressions::Variable, uint_fast64_t>
const& atomToSlotMapping,
400 std::function<
bool(storm::solver::SmtSolver::ModelReference&)>
const& callback)
401 :
manager(
manager), env(env), atomToSlotMapping(atomToSlotMapping), callback(callback) {
405 static int allsatModelReferenceCallback(msat_term* model,
int,
void* user_data) {
406 AllsatModelReferenceCallbackUserData* user =
reinterpret_cast<AllsatModelReferenceCallbackUserData*
>(user_data);
407 MathsatSmtSolver::MathsatAllsatModelReference modelReference(user->manager, user->env, model, user->atomToSlotMapping);
408 if (user->callback(modelReference)) {
417 storm::expressions::ExpressionManager
const&
manager;
423 std::unordered_map<storm::expressions::Variable, uint_fast64_t>
const& atomToSlotMapping;
426 std::function<bool(storm::solver::SmtSolver::ModelReference&)>
const& callback;
432#ifdef STORM_HAVE_MATHSAT
436 std::vector<msat_term> msatImportant;
437 msatImportant.reserve(important.size());
440 STORM_LOG_THROW(variable.
hasBooleanType(), storm::exceptions::InvalidArgumentException,
"The important atoms for AllSat must be boolean variables.");
441 msatImportant.push_back(expressionAdapter->translateExpression(variable));
444 AllsatValuationCallbackUserData allSatUserData(this->
getManager(), *expressionAdapter, env, callback);
446 msat_all_sat(env, msatImportant.data(), msatImportant.size(), &AllsatValuationCallbackUserData::allsatValuationsCallback, &allSatUserData);
450 return static_cast<uint_fast64_t
>(numberOfModels);
454 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
460#ifdef STORM_HAVE_MATHSAT
464 std::vector<msat_term> msatImportant;
465 msatImportant.reserve(important.size());
466 std::unordered_map<storm::expressions::Variable, uint_fast64_t> atomToSlotMapping;
469 STORM_LOG_THROW(variable.
hasBooleanType(), storm::exceptions::InvalidArgumentException,
"The important atoms for AllSat must be boolean variables.");
470 msatImportant.push_back(expressionAdapter->translateExpression(variable));
471 atomToSlotMapping[variable] = msatImportant.size() - 1;
474 AllsatModelReferenceCallbackUserData allSatUserData(this->
getManager(), env, atomToSlotMapping, callback);
476 msat_all_sat(env, msatImportant.data(), msatImportant.size(), &AllsatModelReferenceCallbackUserData::allsatModelReferenceCallback, &allSatUserData);
480 return static_cast<uint_fast64_t
>(numberOfModels);
484 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
489#ifdef STORM_HAVE_MATHSAT
491 "Unable to generate unsatisfiable core of assumptions, because the last check did not determine the formulas to be unsatisfiable.");
492 STORM_LOG_THROW(lastCheckAssumptions, storm::exceptions::InvalidStateException,
493 "Unable to generate unsatisfiable core of assumptions, because the last check did not involve assumptions.");
495 size_t numUnsatAssumpations;
496 msat_term* msatUnsatAssumptions = msat_get_unsat_assumptions(env, &numUnsatAssumpations);
498 std::vector<storm::expressions::Expression> unsatAssumptions;
499 unsatAssumptions.reserve(numUnsatAssumpations);
501 for (
unsigned int i = 0; i < numUnsatAssumpations; ++i) {
502 unsatAssumptions.push_back(this->expressionAdapter->translateExpression(msatUnsatAssumptions[i]));
505 return unsatAssumptions;
507 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
512#ifdef STORM_HAVE_MATHSAT
513 auto groupIter = this->interpolationGroups.find(group);
514 if (groupIter == this->interpolationGroups.end()) {
515 int newGroup = msat_create_itp_group(env);
516 auto insertResult = this->interpolationGroups.insert(std::make_pair(group, newGroup));
517 groupIter = insertResult.first;
519 msat_set_itp_group(env, groupIter->second);
522 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Storm is compiled without MathSAT support.");
527#ifdef STORM_HAVE_MATHSAT
529 "Unable to generate interpolant, because the last check did not determine the formulas to be unsatisfiable.");
530 STORM_LOG_THROW(!lastCheckAssumptions, storm::exceptions::InvalidStateException,
531 "Unable to generate interpolant, because the last check for satisfiability involved assumptions.");
533 std::vector<int> msatInterpolationGroupsA;
534 msatInterpolationGroupsA.reserve(groupsA.size());
535 for (
auto groupOfA : groupsA) {
536 auto groupIter = this->interpolationGroups.find(groupOfA);
537 STORM_LOG_THROW(groupIter != this->interpolationGroups.end(), storm::exceptions::InvalidArgumentException,
538 "Unable to generate interpolant, because an unknown interpolation group was referenced.");
539 msatInterpolationGroupsA.push_back(groupIter->second);
541 msat_term interpolant = msat_get_interpolant(env, msatInterpolationGroupsA.data(), msatInterpolationGroupsA.size());
543 STORM_LOG_THROW(!MSAT_ERROR_TERM(interpolant), storm::exceptions::UnexpectedException,
"Unable to retrieve an interpolant.");
545 return this->expressionAdapter->translateExpression(interpolant);
548 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 CheckResult checkWithAssumptions(storm::expressions::ExpressionSet const &assumptions) override
Checks whether the conjunction of assertions that are currently on the solver's stack together with t...
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 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)
std::set< Expression, ExpressionComparator > ExpressionSet
SettingsManager const & manager()
Retrieves the settings manager.