3 #include "../SolverTypes.h"
6 #include "../ClauseChecker.h"
10 #include <carl-formula/model/Assignment.h>
22 using carl::operator<<;
32 std::function<const Minisat::vec<Minisat::CRef>&()>
getClauses;
44 carl::Variable
variable = carl::Variable::NO_VARIABLE;
51 template<
typename Settings>
77 std::map<Minisat::Var, std::vector<Minisat::Var>>
mVarDeps;
94 bool has(
const carl::Variable& v)
const {
107 std::vector<Minisat::Var> res;
109 res.push_back(it->first);
116 #ifdef SMTRAT_DEVOPTION_Statistics
117 MCSATStatistics& mStatistics;
157 ModelAssignmentCache mModelAssignmentCache;
162 std::optional<std::vector<Minisat::Var>>
theoryVars = std::nullopt;
177 return static_cast<std::size_t
>(
var);
181 template<
typename BaseModule>
184 [&baseModule](
Minisat::Var v){
return baseModule.value(v); },
185 [&baseModule](
Minisat::Lit l){
return baseModule.value(l); },
186 [&baseModule](
Minisat::Var l){
return baseModule.bool_value(l); },
187 [&baseModule](
Minisat::Var v){
return baseModule.vardata[v].level; },
188 [&baseModule](
Minisat::Var v){
return baseModule.vardata[v].mTrailIndex; },
189 [&baseModule](
Minisat::Var v){
return baseModule.reason(v); },
190 [&baseModule](
Minisat::CRef c) ->
const auto& {
return baseModule.ca[c]; },
191 [&baseModule]() ->
const auto& {
return baseModule.clauses; },
192 [&baseModule]() ->
const auto& {
return baseModule.learnts; },
193 [&baseModule](
Minisat::Var v){
return (baseModule.mBooleanConstraintMap.size() > v) && (baseModule.mBooleanConstraintMap[v].first !=
nullptr); },
194 [&baseModule](
const FormulaT& f) {
return baseModule.mConstraintLiteralMap.count(f) > 0; },
195 [&baseModule](
const FormulaT& f) {
return var(baseModule.mConstraintLiteralMap.at(f).front()); },
196 [&baseModule](
Minisat::Var v) ->
const auto& {
return baseModule.mBooleanConstraintMap[v].first->reabstraction; },
197 [&baseModule](
Minisat::Lit l) ->
const auto& {
return sign(l) ? baseModule.mBooleanConstraintMap[
var(l)].second->reabstraction : baseModule.mBooleanConstraintMap[
var(l)].first->reabstraction; },
198 [&baseModule](
Minisat::Lit l) ->
const auto& {
return baseModule.watches[l]; },
199 [&baseModule]() ->
Minisat::Var { baseModule.mBooleanConstraintMap.push( std::make_pair(
nullptr,
nullptr ) );
return baseModule.newVar(
true,
true,0,
false); }
202 #ifdef SMTRAT_DEVOPTION_Statistics
203 , mStatistics(baseModule.mMCSATStatistics)
239 if (
level == 0)
return carl::Variable::NO_VARIABLE;
252 if (f.type() == carl::FormulaType::VARASSIGN) {
279 if (f.type() == carl::FormulaType::VARASSIGN) {
289 if (
theoryLevel(
var(lit)) < std::numeric_limits<std::size_t>::max()) {
326 SMTRAT_LOG_DEBUG(
"smtrat.sat.mcsat",
"Checking whether trail is feasible (w.r.t. " <<
var <<
")");
337 if (std::holds_alternative<ModelValues>(res)) {
341 const auto& confl = std::get<FormulasT>(res);
362 if (std::holds_alternative<ModelValues>(res)) {
363 const auto& values = std::get<ModelValues>(res);
366 for (
const auto& value : values) {
367 FormulaT repr = carl::representingFormula(value.first, value.second);
368 reprs.push_back(std::move(repr));
372 const auto& confl = std::get<FormulasT>(res);
406 SMTRAT_LOG_DEBUG(
"smtrat.sat.mcsat",
"Inconsistent: " << confl <<
" evaluates to false");
409 auto vars = carl::arithmetic_variables(confl);
410 for (
const auto& avar :
mBackend.assignedVariables())
412 assert(
vars.size() > 0);
413 auto explanation =
mBackend.explain(*(
vars.begin()), {confl});
424 carl::carlVariables
vars;
425 carl::variables(f,
vars);
426 for (
const auto& v :
mBackend.assignedVariables())
428 assert(
vars.size() == 1);
429 carl::Variable tvar = *(
vars.begin());
431 auto conflict =
mBackend.isInfeasible(tvar, !f);
432 assert(std::holds_alternative<FormulasT>(conflict));
433 auto& confl = std::get<FormulasT>(conflict);
434 assert(
std::find(confl.begin(), confl.end(), !f) != confl.end() );
435 SMTRAT_LOG_DEBUG(
"smtrat.sat.mcsat",
"Explaining " << f <<
" from " << confl);
436 auto res =
mBackend.explain(tvar, !f, confl);
439 if (std::holds_alternative<FormulaT>(res)) {
440 if (std::get<FormulaT>(res).is_false()) {
443 assert(std::get<FormulaT>(res).
contains(f));
447 assert(std::get<ClauseChain>(res).chain().back().clause().
contains(f));
452 template<
typename Constra
ints>
455 carl::carlVariables
vars;
456 std::map<carl::Variable,carl::Variables> deps;
457 for (
int i = 0; i < c.size(); ++i) {
458 if (c[i].first ==
nullptr)
continue;
459 if (c[i].first->reabstraction.type() == carl::FormulaType::CONSTRAINT) {
460 const ConstraintT& constr = c[i].first->reabstraction.constraint();
461 carl::variables(constr,
vars);
462 }
else if (c[i].first->reabstraction.type() == carl::FormulaType::VARCOMPARE) {
463 const auto& constr = c[i].first->reabstraction.variable_comparison();
464 carl::variables(constr,
vars);
465 if (std::holds_alternative<carl::MultivariateRoot<Poly>>(constr.value())) {
466 auto dep_vars = carl::variables(constr);
467 dep_vars.erase(constr.var());
468 deps.try_emplace(constr.var()).first->second.insert(dep_vars.begin(), dep_vars.end());
473 for (
const carl::Variable& theoryVar :
vars) {
479 for (
const auto& p : deps) {
480 std::vector<Minisat::Var> d;
481 for (
const auto& v : p.second) {
508 if (e ==
mVarDeps.end())
return false;
509 auto d = std::find_if(e->second.begin(), e->second.end(), [
this](
const auto& c) {
510 return !this->isAssignedTheoryVariable(this->carlVar(c));
512 return (d != e->second.end());
534 if constexpr(!Settings::early_evaluation) {
535 auto poly_variables = f.variables();
536 if (poly_variables.empty()) {
541 if (poly_variables.empty())
return level;
544 return std::numeric_limits<std::size_t>::max();
546 carl::carlVariables
vars;
547 carl::variables(f,
vars);
549 SMTRAT_LOG_TRACE(
"smtrat.sat.mcsat", f <<
" has no variable, thus on level 0");
556 return std::numeric_limits<std::size_t>::max();
558 for (std::size_t lvl =
level(); lvl > 0; lvl--) {
559 if (
variable(lvl) == carl::Variable::NO_VARIABLE)
continue;
585 return std::numeric_limits<int>::max();
592 return std::numeric_limits<int>::max();
596 return std::numeric_limits<int>::max();
602 const auto& trail =
mBackend.getTrail();
603 SMTRAT_LOG_DEBUG(
"smtrat.sat.mcsat",
"Checking trail against " << trail.model());
604 auto evaluator = [&trail](
const auto& c){
608 if (!res.asBool())
return false;
612 for (
const auto& c: trail.constraints()) {
613 if (!
mBackend.isActive(c))
continue;
617 if (!evaluator(c))
return false;
619 for (
const auto& b: trail.mvBounds()) {
620 if (!
mBackend.isActive(b))
continue;
624 if (!evaluator(b))
return false;
638 if (reabstraction.type() == carl::FormulaType::CONSTRAINT) {
639 const auto& constr = reabstraction.constraint();
640 auto vars = carl::arithmetic_variables(reabstraction);
641 std::size_t maxDeg = 0;
642 for (
const auto& tvar :
vars) {
643 std::size_t deg = constr.lhs().degree(tvar);
644 if (deg > maxDeg) maxDeg = deg;
647 }
else if (reabstraction.type() == carl::FormulaType::VARCOMPARE) {
669 auto tvars = carl::arithmetic_variables(reabstraction);
670 std::vector<Minisat::Var>
vars;
671 for (
const auto& tvar : tvars) {
685 template<
typename Sett>
bool theoryAssignmentComplete() const
std::vector< size_t > mTheoryLevels
Theory levels for Boolean variables.
bool hasUnassignedDep(Minisat::Var v) const
std::size_t computeTheoryLevel(const FormulaT &f) const
bool isAssignedTheoryVariable(const carl::Variable &var) const
Minisat::lbool evaluateLiteral(Minisat::Lit lit) const
Evaluate a literal in the theory, set lastReason to last theory decision involved.
friend std::ostream & operator<<(std::ostream &os, const MCSATMixin< Sett > &mcm)
bool isTheoryVar(Minisat::Var v) const
bool fullConsistencyCheck() const
std::pair< bool, std::optional< Explanation > > isBooleanDecisionFeasible(Minisat::Lit lit, bool always_explain=false)
std::map< Minisat::Var, std::vector< Minisat::Var > > mVarDeps
std::vector< Minisat::Var > mInconsistentVariables
Variables that are inconsistent in the current theory level.
const std::vector< Minisat::Var > & undecidedBooleanVariables() const
int assignedAtTrailIndex(Minisat::Var variable) const
bool is_consistent()
Checks if any inconsistency was detected.
void pushTheoryDecision(const FormulaT &assignment, Minisat::Lit decisionLiteral)
Push a theory decision.
std::vector< TheoryLevel > TheoryStackT
The first entry of the stack always contains an entry for the non-theory variables: the variable is s...
const TheoryLevel & get(std::size_t level) const
Returns the respective theory level.
bool backtrackTo(Minisat::Lit literal)
Backtracks to the theory decision represented by the given literal.
MCSATBackend< Settings > mBackend
Minisat::Lit getDecisionLiteral(Minisat::Var var) const
void undoBooleanAssignment(Minisat::Lit lit)
Remove the last constraint.
int decisionLevel(Minisat::Var v) const
std::optional< Explanation > isFeasible(const carl::Variable &var)
std::size_t computeTheoryLevel(Minisat::Var var) const
void updateCurrentLevel()
Updates lookup for the current level.
const TheoryLevel & current() const
Returns the current theory level.
std::size_t level() const
std::vector< Minisat::Var > theoryVarAbstractions() const
void printClause(std::ostream &os, Minisat::CRef clause) const
Prints a single clause.
void popTheoryDecision()
Pop a theory decision.
void doBooleanAssignment(Minisat::Lit lit)
Add a new constraint.
Minisat::Var minisatVar(const carl::Variable &v) const
InformationGetter mGetter
std::size_t theoryLevel(Minisat::Var var) const
std::set< Minisat::Var > mSemanticPropagations
Semantically propagated variables that are not yet inserted into the trail.
std::variant< Explanation, FormulasT > makeTheoryDecision(const carl::Variable &var)
carl::Variable variable(std::size_t level) const
Retrieve already decided theory variables.
VarMapping mTheoryVarMapping
MCSATMixin(BaseModule &baseModule)
TheoryStackT mTheoryStack
std::pair< boost::tribool, std::optional< Explanation > > propagateBooleanDomain(Minisat::Lit lit)
std::size_t addBooleanVariable(Minisat::Var variable)
Add a variable, return the level it was inserted on.
std::vector< Minisat::Var > theoryVars(const Minisat::Var &var)
const Model & model() const
void initVariables(const Constraints &c)
Minisat::Var topSemanticPropagation()
Getter for semantic propagations.
const carl::Variable & carlVar(Minisat::Var v) const
std::size_t varid(Minisat::Var var) const
bool is_consistent(Minisat::Var v)
std::vector< Minisat::Var > mUndecidedVariables
Variables that are not univariate in any variable yet.
bool isFormulaUnivariate(const FormulaT &formula, std::size_t level) const
Checks whether the given formula is univariate on the given level.
Explanation explainTheoryPropagation(Minisat::Lit literal)
std::optional< Explanation > explainInconsistency()
Checks if the trail is consistent after the assignment on the current level.
std::size_t maxDegree(const Minisat::Var &var)
std::vector< VarProperties > mVarPropertyCache
Cache for static information about variables.
static bool find(V &ts, const T &t)
RegionAllocator< uint32_t >::Ref CRef
Rational evaluate(carl::Variable v, const Poly &p, const Rational &r)
bool contains(const std::vector< TagPoly > &polys, const Poly &poly)
std::variant< FormulaT, ClauseChain > Explanation
std::variant< ModelValues, FormulasT > AssignmentOrConflict
std::vector< carl::Variable > vars(const std::pair< QuantifierType, std::vector< carl::Variable >> &p)
Class to create the formulas for axioms.
carl::Formula< Poly > FormulaT
carl::Model< Rational, Poly > Model
carl::Constraint< Poly > ConstraintT
carl::Formulas< Poly > FormulasT
#define SMTRAT_LOG_TRACE(channel, msg)
#define SMTRAT_LOG_INFO(channel, msg)
#define SMTRAT_LOG_DEBUG(channel, msg)
bool has(const carl::Variable &v) const
Minisat::Var minisatVar(const carl::Variable &v) const
std::vector< Minisat::Var > minisatVars() const
std::map< carl::Variable, Minisat::Var > carlToMinisat
bool has(Minisat::Var v) const
std::map< Minisat::Var, carl::Variable > minisatToCarl
const carl::Variable & carlVar(Minisat::Var v) const
void insert(const carl::Variable &carlVar, Minisat::Var minisatVar)
std::optional< std::size_t > maxDegree
std::optional< std::vector< Minisat::Var > > theoryVars
carl::Variable variable
Theory variable for this level.
std::vector< Minisat::Var > decidedVariables
Boolean variables univariate in this theory variable.
Minisat::Lit decisionLiteral
Literal that assigns this theory variable.