SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
Explanation.h
Go to the documentation of this file.
1 #pragma once
2 
5 #include "OCStatistics.h"
6 
7 #include "onecell.h"
8 
9 #include <carl-formula/formula/functions/Negations.h>
10 #include <carl-arith/ran/Conversion.h>
11 #include <carl-arith/poly/Conversion.h>
12 #include <carl-arith/constraint/Conversion.h>
13 #include <carl-arith/extended/Conversion.h>
14 
15 #include "../../utils/RootExpr.h"
16 
17 
19 
20 struct BaseSettings {
21  static constexpr bool clause_chain_with_equivalences = false;
22  static constexpr bool enforce_tarski = false;
23 
24  constexpr static bool use_approximation = false;
25 
26  constexpr static bool exploit_strict_constraints = true;
27 };
28 
29 /*
30 
31 struct LDBSettings : BaseSettings {
32  // constexpr static auto cell_heuristic = cadcells::representation::BIGGEST_CELL;
33  // constexpr static auto cell_heuristic = cadcells::representation::CHAIN_EQ;
34  // constexpr static auto cell_heuristic = cadcells::representation::LOWEST_DEGREE_BARRIERS_EQ;
35  constexpr static auto cell_heuristic = cadcells::representation::LOWEST_DEGREE_BARRIERS;
36  constexpr static auto covering_heuristic = cadcells::representation::LDB_COVERING;
37  // constexpr static auto covering_heuristic = cadcells::representation::CHAIN_COVERING;
38  //constexpr static auto op = cadcells::operators::op::mccallum;
39  constexpr static auto op = cadcells::operators::op::mccallum;
40 };
41 
42 struct LDBpdelSettings : BaseSettings {
43  constexpr static auto cell_heuristic = cadcells::representation::LOWEST_DEGREE_BARRIERS_PDEL;
44  constexpr static auto covering_heuristic = cadcells::representation::BIGGEST_CELL_COVERING_PDEL;
45  constexpr static auto op = cadcells::operators::op::mccallum_pdel;
46 };
47 
48 struct LDBFilteredAllSelectiveSettings : BaseSettings {
49  constexpr static auto cell_heuristic = cadcells::representation::LOWEST_DEGREE_BARRIERS_FILTER;
50  constexpr static auto covering_heuristic = cadcells::representation::BIGGEST_CELL_COVERING_FILTER;
51  constexpr static auto op = cadcells::operators::op::mccallum_filtered_onlyrat_ew;
52 };
53 
54 struct BCSettings : BaseSettings {
55  constexpr static auto cell_heuristic = cadcells::representation::BIGGEST_CELL;
56  constexpr static auto covering_heuristic = cadcells::representation::BIGGEST_CELL_COVERING;
57  constexpr static auto op = cadcells::operators::op::mccallum;
58 };
59 
60 struct BCpdelSettings : BaseSettings {
61  constexpr static auto cell_heuristic = cadcells::representation::BIGGEST_CELL_PDEL;
62  constexpr static auto covering_heuristic = cadcells::representation::BIGGEST_CELL_COVERING_PDEL;
63  constexpr static auto op = cadcells::operators::op::mccallum_pdel;
64 };
65 
66 struct BCFilteredSettings : BaseSettings {
67  constexpr static auto cell_heuristic = cadcells::representation::BIGGEST_CELL_FILTER;
68  constexpr static auto covering_heuristic = cadcells::representation::BIGGEST_CELL_COVERING_FILTER;
69  constexpr static auto op = cadcells::operators::op::mccallum_filtered;
70 };
71 
72 struct BCApproximationSettings : BCSettings {
73  constexpr static bool use_approximation = true;
74  constexpr static auto cell_apx_heuristic = cadcells::representation::BIGGEST_CELL_APPROXIMATION;
75 };
76 */
77 
78 struct DefaultSettings : BaseSettings { // current default
79  constexpr static bool exploit_strict_constraints = true;
80 
84 };
85 
86 // TODO keep context and cache as long as variable ordering does not change. but we need to make a context extensible.
87 
88 template<typename Settings = DefaultSettings>
89 struct Explanation {
90  #ifdef SMTRAT_DEVOPTION_Statistics
91  OCStatistics& mStatistics = statistics_get<OCStatistics>("mcsat-explanation-onecell");
92  #endif
93 
94  std::optional<mcsat::Explanation> operator()(const mcsat::Bookkeeping& trail, carl::Variable var, const FormulasT& reason, bool) const {
95  #ifdef SMTRAT_DEVOPTION_Statistics
96  mStatistics.explanationCalled();
97  #endif
98 
100  vars.push_back(var);
101 
102  cadcells::Polynomial::ContextType context(vars);
103 
105  for (const auto& [key, value] : trail.model()) {
106  if (value.isRAN()) {
107  ass.emplace(key.asVariable(), carl::convert<cadcells::RAN>(value.asRAN()));
108  } else {
109  assert(value.isRational());
110  ass.emplace(key.asVariable(), cadcells::RAN(value.asRational()));
111  }
112  }
113 
114  SMTRAT_STATISTICS_CALL(mStatistics.assignment(ass));
115  //SMTRAT_STATISTICS_CALL(cadcells::statistics().set_max_level(ass.size()+1));
116 
117  carl::carlVariables reason_vars;
118  for (const auto& r : reason) carl::variables(r,reason_vars);
119  for (const auto v : reason_vars) {
120  if (ass.find(v) == ass.end() && v != var) {
121  SMTRAT_LOG_DEBUG("smtrat.mcsat.onecell", "Conflict reasons are of higher level than the current one.");
122  return std::nullopt;
123  }
124  }
125 
126  std::vector<cadcells::Atom> constr;
127  for (const auto& r : reason) {
128  if (r.type() == carl::FormulaType::CONSTRAINT) {
129  constr.emplace_back(carl::convert<cadcells::Polynomial>(context, r.constraint().constr()));
130  } else if (r.type() == carl::FormulaType::VARCOMPARE) {
131  constr.emplace_back(carl::convert<cadcells::Polynomial>(context, r.variable_comparison()));
132  }
133  }
134  SMTRAT_LOG_DEBUG("smtrat.mcsat.onecell", "Explain conflict " << constr << " with " << vars << " and " << ass);
135  #ifdef SMTRAT_DEVOPTION_Statistics
136  SMTRAT_TIME_START(start);
137  #endif
138  auto result = onecell<Settings>(constr, context, ass);
139  #ifdef SMTRAT_DEVOPTION_Statistics
140  SMTRAT_TIME_FINISH(mStatistics.timer(), start);
141  #endif
142 
143  if (!result) {
144  SMTRAT_LOG_DEBUG("smtrat.mcsat.onecell", "Could not generate explanation");
145  return std::nullopt;
146  }
147  else {
148  #ifdef SMTRAT_DEVOPTION_Statistics
149  mStatistics.explanationSuccess();
150  #endif
151  SMTRAT_LOG_DEBUG("smtrat.mcsat.onecell", "Got unsat cell " << result << " of constraints " << constr << " wrt " << vars << " and " << ass);
152  FormulasT expl;
153  for (const auto& f : reason) {
154  expl.push_back(f.negated());
155  }
156  bool is_clause = true;
157  for (const auto& disjunction : *result) {
158  std::vector<FormulaT> tmp;
159  for (const auto& f : disjunction) {
160  if (std::holds_alternative<cadcells::Constraint>(f)) {
161  tmp.push_back(FormulaT(ConstraintT(carl::convert<Poly>(std::get<cadcells::Constraint>(f)))).negated());
162  } else if (std::holds_alternative<cadcells::VariableComparison>(f)) {
163  auto transf = constr_from_vc(std::get<cadcells::VariableComparison>(f), ass, Settings::enforce_tarski);
164  if (transf.empty()) {
165  tmp.push_back(FormulaT(carl::convert<Poly>(std::get<cadcells::VariableComparison>(f))).negated());
166  } else {
167  std::vector<FormulaT> tmp2;
168  for (const auto& c : transf) {
169  tmp2.push_back(FormulaT(ConstraintT(carl::convert<Poly>(c))).negated());
170  }
171  tmp.emplace_back(carl::FormulaType::OR, std::move(tmp2));
172  }
173  } else {
174  assert(false);
175  }
176  }
177  if (tmp.size() > 1) is_clause = false;
178  expl.emplace_back(carl::FormulaType::AND, std::move(tmp));
179  }
180  if (is_clause) {
181  return mcsat::Explanation(FormulaT(carl::FormulaType::OR, std::move(expl)));
182  } else {
183  return mcsat::Explanation(ClauseChain::from_formula(FormulaT(carl::FormulaType::OR, std::move(expl)), trail.model(), Settings::clause_chain_with_equivalences));
184  }
185  }
186  }
187 };
188 
189 }
Represent the trail, i.e.
Definition: Bookkeeping.h:19
const auto & assignedVariables() const
Definition: Bookkeeping.h:37
const auto & model() const
Definition: Bookkeeping.h:34
static ClauseChain from_formula(const FormulaT &f, const Model &model, bool with_equivalence)
Transforms a given Boolean conjunction over AND and OR to CNF via Tseitin-Transformation so that,...
int var(Lit p)
Definition: SolverTypes.h:64
std::vector< carl::Variable > VariableOrdering
Definition: common.h:11
Polynomial::RootType RAN
Definition: common.h:24
carl::Assignment< RAN > Assignment
Definition: common.h:25
std::vector< carl::BasicConstraint< P > > constr_from_vc(const carl::VariableComparison< P > &vc, const carl::Assignment< typename P::RootType > assignment, bool tarski=false)
Definition: RootExpr.h:6
std::variant< FormulaT, ClauseChain > Explanation
Definition: smtrat-mcsat.h:14
std::vector< carl::Variable > vars(const std::pair< QuantifierType, std::vector< carl::Variable >> &p)
Definition: QEQuery.h:43
carl::Formula< Poly > FormulaT
Definition: types.h:37
carl::Constraint< Poly > ConstraintT
Definition: types.h:29
carl::Formulas< Poly > FormulasT
Definition: types.h:39
#define SMTRAT_LOG_DEBUG(channel, msg)
Definition: logging.h:35
#define SMTRAT_STATISTICS_CALL(function)
Definition: Statistics.h:23
#define SMTRAT_TIME_START(variable)
Definition: Statistics.h:24
#define SMTRAT_TIME_FINISH(timer, start)
Definition: Statistics.h:25
constexpr static bool exploit_strict_constraints
Definition: Explanation.h:26
constexpr static bool use_approximation
Definition: Explanation.h:24
static constexpr bool clause_chain_with_equivalences
Definition: Explanation.h:21
static constexpr bool enforce_tarski
Definition: Explanation.h:22
constexpr static auto covering_heuristic
Definition: Explanation.h:82
constexpr static bool exploit_strict_constraints
Definition: Explanation.h:79
constexpr static auto cell_heuristic
Definition: Explanation.h:81
std::optional< mcsat::Explanation > operator()(const mcsat::Bookkeeping &trail, carl::Variable var, const FormulasT &reason, bool) const
Definition: Explanation.h:94