SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
BaseBackend.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "MCSATSettings.h"
4 
6 
7 #include <carl-arith/extended/Encoding.h>
8 #include <carl-formula/formula/functions/Visit.h>
9 
10 namespace smtrat {
11 namespace mcsat {
12 
13 template<typename Settings>
14 class MCSATBackend {
16  typename Settings::AssignmentFinderBackend mAssignmentFinder;
17  typename Settings::ExplanationBackend mExplanation;
18 
19 public:
20  void pushConstraint(const FormulaT& f) {
22  }
23 
24  void popConstraint(const FormulaT& f) {
26  }
27 
28  void pushAssignment(carl::Variable v, const ModelValue& mv, const FormulaT& f) {
29  mBookkeeping.pushAssignment(v, mv, f);
30  }
31 
32  void popAssignment(carl::Variable v) {
34  }
35 
36  const auto& getModel() const {
37  return mBookkeeping.model();
38  }
39  const auto& getTrail() const {
40  return mBookkeeping;
41  }
42 
43  void initVariables(const carl::Variables& variables) {
45  }
46 
47  const auto& variables() const {
48  return mBookkeeping.variables();
49  }
50 
51  const auto& assignedVariables() const {
53  }
54 
55  AssignmentOrConflict findAssignment(carl::Variable var) const {
56  auto res = mAssignmentFinder(getTrail(), var);
57  if (res) {
58  return *res;
59  } else {
60  SMTRAT_LOG_ERROR("smtrat.mcsat", "AssignmentFinder backend failed.");
61  assert(false);
62  return ModelValues();
63  }
64  }
65 
66  AssignmentOrConflict isInfeasible(carl::Variable var, const FormulaT& f) {
67  SMTRAT_LOG_DEBUG("smtrat.mcsat", "Checking whether " << f << " is feasible");
68  pushConstraint(f);
69  auto res = findAssignment(var);
70  popConstraint(f);
71  if (std::holds_alternative<ModelValues>(res)) {
72  SMTRAT_LOG_DEBUG("smtrat.mcsat", f << " is feasible");
73  } else {
74  SMTRAT_LOG_DEBUG("smtrat.mcsat", f << " is infeasible with reason " << std::get<FormulasT>(res));
75  }
76  return res;
77  }
78 
79  Explanation explain(carl::Variable var, const FormulasT& reason, bool force_use_core = false) const {
80  if (getModel().empty()) {
81  FormulasT expl;
82  for (const auto& r: reason) expl.emplace_back(r.negated());
83  return FormulaT(carl::FormulaType::OR, std::move(expl));
84  }
85  std::optional<Explanation> res = mExplanation(getTrail(), var, reason, force_use_core);
86  if (res) {
87  SMTRAT_LOG_INFO("smtrat.mcsat", "Got explanation " << *res);
88  #ifdef SMTRAT_DEVOPTION_Validation
89  SMTRAT_VALIDATION_INIT_STATIC("smtrat.mcsat.base", validation_point);
90  FormulaT formula;
91  if (std::holds_alternative<FormulaT>(*res)) {
92  // Checking validity: forall x. phi(x) = ~exists x. ~phi(x)
93  formula = std::get<FormulaT>(*res);
94  } else {
95  // Tseitin: phi(x) = exists t. phi'(x,t)
96  // Checking validity: exists t. phi'(x,t) = ~exists x. ~(exists t. phi'(x,t)) = ~exists x. forall t. ~phi'(x,t)
97  // this is kind of ugly, so we just resolve the clause chain
98  formula = std::get<ClauseChain>(*res).resolve();
99  }
100  if (false) {
101  // Note that we can only encode some properties of the indexed root expressions. Thus, some explanation might wrongly be detected as incorrect.
102  carl::Assignment<RAN> ass;
103  for (const auto& [key, value] : getTrail().model()) {
104  if (value.isRAN()) {
105  ass.emplace(key.asVariable(), value.asRAN());
106  } else {
107  assert(value.isRational());
108  ass.emplace(key.asVariable(), RAN(value.asRational()));
109  }
110  }
111  carl::EncodingCache<Poly> cache;
112  formula = carl::visit_result(formula, [&](const FormulaT& f) {
113  if (f.type() == carl::FormulaType::VARCOMPARE) {
114  auto [conds, constr] = carl::encode_as_constraints(f.variable_comparison(), ass, cache);
115  FormulasT fs;
116  for (const auto& c: conds) {
117  fs.emplace_back(FormulaT(ConstraintT(c)));
118  }
119  fs.emplace_back(ConstraintT(constr));
120  return FormulaT(carl::FormulaType::AND, std::move(fs));
121  } else {
122  return f;
123  }
124  });
125  }
126  SMTRAT_VALIDATION_ADD_TO(validation_point, "explanation", formula.negated(), false);
127  #endif
128  return *res;
129  } else {
130  SMTRAT_LOG_ERROR("smtrat.mcsat", "Explanation backend failed.");
131  return Explanation(FormulaT(carl::FormulaType::FALSE));
132  }
133  }
134 
135  Explanation explain(carl::Variable var, const FormulaT& f, const FormulasT& reason) {
136  pushConstraint(f);
137  auto res = explain(var, reason, true);
138  popConstraint(f);
139  return res;
140  }
141 
142  bool isActive(const FormulaT& f) const {
143  return mAssignmentFinder.active(getTrail(), f);
144  }
145 };
146 
147 
148 template<typename Settings>
149 std::ostream& operator<<(std::ostream& os, const MCSATBackend<Settings>& backend) {
150  return os << backend.getTrail();
151 }
152 
153 } // namespace mcsat
154 } // namespace smtrat
#define SMTRAT_VALIDATION_INIT_STATIC(channel, variable)
Definition: Validation.h:24
#define SMTRAT_VALIDATION_ADD_TO(variable, name, formula, consistent)
Definition: Validation.h:25
Represent the trail, i.e.
Definition: Bookkeeping.h:19
const auto & assignedVariables() const
Definition: Bookkeeping.h:37
void popConstraint(const FormulaT &f)
Definition: Bookkeeping.h:73
void popAssignment(carl::Variable v)
Definition: Bookkeeping.h:98
const auto & variables() const
Definition: Bookkeeping.h:49
const auto & model() const
Definition: Bookkeeping.h:34
void pushConstraint(const FormulaT &f)
Assert a constraint/literal.
Definition: Bookkeeping.h:58
void updateVariables(const carl::Variables &variables)
Definition: Bookkeeping.h:53
void pushAssignment(carl::Variable v, const ModelValue &mv, const FormulaT &f)
Definition: Bookkeeping.h:90
AssignmentOrConflict findAssignment(carl::Variable var) const
Definition: BaseBackend.h:55
void pushAssignment(carl::Variable v, const ModelValue &mv, const FormulaT &f)
Definition: BaseBackend.h:28
bool isActive(const FormulaT &f) const
Definition: BaseBackend.h:142
const auto & getModel() const
Definition: BaseBackend.h:36
void popAssignment(carl::Variable v)
Definition: BaseBackend.h:32
void popConstraint(const FormulaT &f)
Definition: BaseBackend.h:24
mcsat::Bookkeeping mBookkeeping
Definition: BaseBackend.h:15
void pushConstraint(const FormulaT &f)
Definition: BaseBackend.h:20
const auto & getTrail() const
Definition: BaseBackend.h:39
Explanation explain(carl::Variable var, const FormulaT &f, const FormulasT &reason)
Definition: BaseBackend.h:135
Settings::AssignmentFinderBackend mAssignmentFinder
Definition: BaseBackend.h:16
Settings::ExplanationBackend mExplanation
Definition: BaseBackend.h:17
AssignmentOrConflict isInfeasible(carl::Variable var, const FormulaT &f)
Definition: BaseBackend.h:66
const auto & assignedVariables() const
Definition: BaseBackend.h:51
const auto & variables() const
Definition: BaseBackend.h:47
void initVariables(const carl::Variables &variables)
Definition: BaseBackend.h:43
Explanation explain(carl::Variable var, const FormulasT &reason, bool force_use_core=false) const
Definition: BaseBackend.h:79
int var(Lit p)
Definition: SolverTypes.h:64
Polynomial::RootType RAN
Definition: common.h:24
std::vector< std::pair< carl::Variable, ModelValue > > ModelValues
Definition: smtrat-mcsat.h:12
std::variant< FormulaT, ClauseChain > Explanation
Definition: smtrat-mcsat.h:14
std::variant< ModelValues, FormulasT > AssignmentOrConflict
Definition: smtrat-mcsat.h:13
Class to create the formulas for axioms.
carl::ModelValue< Rational, Poly > ModelValue
Definition: model.h:12
carl::Formula< Poly > FormulaT
Definition: types.h:37
std::ostream & operator<<(std::ostream &os, CMakeOptionPrinter cmop)
carl::Constraint< Poly > ConstraintT
Definition: types.h:29
carl::Formulas< Poly > FormulasT
Definition: types.h:39
#define SMTRAT_LOG_INFO(channel, msg)
Definition: logging.h:34
#define SMTRAT_LOG_ERROR(channel, msg)
Definition: logging.h:32
#define SMTRAT_LOG_DEBUG(channel, msg)
Definition: logging.h:35