SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
Explanation.cpp
Go to the documentation of this file.
1 #include "Explanation.h"
2 #include "OneCellCAD.h"
3 
5 
6 #include <carl-common/config.h>
7 
8 namespace smtrat {
9 namespace mcsat {
10 namespace onecellcad {
11 namespace levelwise {
12 
13 template<class Setting1, class Setting2>
14 std::optional<mcsat::Explanation>
15 Explanation<Setting1,Setting2>::operator()(const mcsat::Bookkeeping& trail, // current assignment state
16  carl::Variable var,
17  const FormulasT& trailLiterals, bool) const {
18 
19  assert(trail.model().size() == trail.assignedVariables().size());
20 
21 #ifdef SMTRAT_DEVOPTION_Statistics
22  getStatistic().explanationCalled();
23 #endif
24 
25 #if not(defined USE_COCOA || defined USE_GINAC)
26 // OneCellCAD needs carl::irreducible_factors to be implemented
27 #warning OneCellCAD may be incorrect as USE_COCOA is disabled
28 #endif
29 
30  // compute compatible complete variable ordering
31  std::vector varOrder(trail.assignedVariables());
32  varOrder.push_back(var);
33  for (const auto& v : trail.variables()) {
34  if (std::find(varOrder.begin(), varOrder.end(), v) == varOrder.end()) {
35  varOrder.push_back(v);
36  }
37  }
38 
39  // Temp. workaround, should at least one theory-var should be assigned, otherwise no OneCell construct possible
40  // TODO remove as soon, mcsat backend handles this case.
41  if (trail.assignedVariables().size() == 0) {
42  SMTRAT_LOG_DEBUG("smtrat.mcsat.nlsat", " OneCellExplanation called with 0 theory-assignment");
43  FormulasT explainLiterals;
44  for (const auto& trailLiteral : trailLiterals)
45  explainLiterals.emplace_back(trailLiteral.negated());
46  return std::variant<FormulaT, ClauseChain>(FormulaT(carl::FormulaType::OR, std::move(explainLiterals)));
47  }
48  assert(trail.assignedVariables().size() > 0);
49 
50  SMTRAT_LOG_DEBUG("smtrat.mcsat.nlsat", "Starting an explanation");
51  SMTRAT_LOG_DEBUG("smtrat.mcsat.nlsat", trail);
52  SMTRAT_LOG_DEBUG("smtrat.mcsat.nlsat", "Number of assigned vars: " << trail.model().size());
53  SMTRAT_LOG_DEBUG("smtrat.mcsat.nlsat", "Trail literals: " << trailLiterals); //<< " Implied literal: " << impliedLiteral);
54  SMTRAT_LOG_DEBUG("smtrat.mcsat.nlsat", "Ascending variable order: " << varOrder
55  << " and eliminate down from: " << var);
56 
57  const auto& trailVariables = trail.assignedVariables();
58  std::vector<carl::Variable> fullProjectionVarOrder = varOrder;
59  std::vector<carl::Variable> oneCellCADVarOrder;
60  for (std::size_t i = 0; i < trailVariables.size(); i++)
61  oneCellCADVarOrder.emplace_back(fullProjectionVarOrder[i]);
62 
63  SMTRAT_LOG_DEBUG("smtrat.mcsat.nlsat", "Ascending OneCellVarOrder: " << oneCellCADVarOrder);
64 
65  std::size_t oneCellMaxLvl = trail.model().size() - 1; // -1, b/c we count first var = poly level 0
66  std::vector<std::vector<TagPoly>> projectionLevels(fullProjectionVarOrder.size()); // init all levels with empty vector
67 
68  std::vector<Poly> polys; // extract from trailLiterals
69  for (const auto& constraint : nlsat::helper::convertToConstraints(trailLiterals))
70  polys.emplace_back(constraint.lhs()); // constraints have the form 'poly < 0' with <, = etc.
71 
72  //Fill projectionLevels
73  for(const auto& poly : polys){
74  appendOnCorrectLevel(poly, InvarianceType::SIGN_INV, projectionLevels, varOrder);
75  }
76 
77  SMTRAT_LOG_DEBUG("smtrat.mcsat.nlsat", "Polys at levels before full CAD projection:\n"
78  << projectionLevels);
79 
80  // Project higher level polys down to "normal" level
81  RealAlgebraicPoint<Rational> point = asRANPoint(trail).prefixPoint(oneCellMaxLvl + 1);
82  auto maxLevel = fullProjectionVarOrder.size() - 1;
83  while (projectionLevels[maxLevel].empty() && maxLevel > 0){
84  projectionLevels.erase(projectionLevels.begin() + maxLevel);
85  maxLevel--;
86  }
87  assert(maxLevel > 0 || !projectionLevels[0].empty());
88 
89  LevelwiseCAD cad = LevelwiseCAD(fullProjectionVarOrder, point);
90  for (std::size_t currentLvl = maxLevel; currentLvl > oneCellMaxLvl; currentLvl--) {
91  auto currentVar = fullProjectionVarOrder[currentLvl];
92  assert(currentLvl >= 1);
93 
94  if(currentLvl == oneCellMaxLvl+1){
95  bool failcheck = optimized_singleLevelFullProjection(currentVar, currentLvl,projectionLevels, cad);
96  if(!failcheck){
97  SMTRAT_LOG_WARN("smtrat.mcsat.nlsat", "OneCell construction failed");
98  return std::nullopt;
99  }
100  } else{
101  singleLevelFullProjection(fullProjectionVarOrder, currentVar, currentLvl, projectionLevels);
102  }
103 
104  projectionLevels.erase(projectionLevels.begin() + currentLvl);
105  SMTRAT_LOG_DEBUG("smtrat.mcsat.nlsat", "Polys at levels after a CAD projection at level: " << currentLvl << ":\n" << projectionLevels);
106  }
107 
108  assert(1 <= Setting1::sectionHeuristic && Setting1::sectionHeuristic <= 3);
109  assert(1 <= Setting2::sectorHeuristic && Setting2::sectorHeuristic <= 3);
110  std::optional<CADCell> cellOpt =
111  cad.constructCADCellEnclosingPoint(projectionLevels, Setting1::sectionHeuristic, Setting2::sectorHeuristic);
112  if (!cellOpt) {
113  SMTRAT_LOG_WARN("smtrat.mcsat.nlsat", "OneCell construction failed");
114  return std::nullopt;
115  }
116 
117  auto cell = *cellOpt;
118  SMTRAT_LOG_DEBUG("smtrat.mcsat.nlsat", "Constructed cell: " << cell);
119 
120  // If we have trail literals: L_M, ... , L_M,
121  // an implied literal L
122  // and cell boundary atoms : A, .., A
123  // We construct the formula '(A & ... & A & L_M & ... & L_M) => L'
124  // in its clausal form 'E := (-A v ... v -A v -L_M v ... v -L_M v L)'
125  // as our explanation.
126  FormulasT explainLiterals;
127 
128  for (const auto& trailLiteral : trailLiterals)
129  explainLiterals.emplace_back(trailLiteral.negated());
130 
131  for (std::size_t i = 0; i < cell.size(); i++) {
132  auto& cellComponent = cell[i];
133  auto cellVariable = oneCellCADVarOrder[i];
134  if (std::holds_alternative<Section>(cellComponent)) {
135  auto section = std::get<Section>(cellComponent).boundFunction;
136  auto param = std::make_pair(section.poly(), section.k());
137  explainLiterals.emplace_back(nlsat::helper::buildEquality(cellVariable, param).negated());
138  } else {
139  auto sectorLowBound = std::get<Sector>(cellComponent).lowBound;
140  if (sectorLowBound) {
141  auto param = std::make_pair(sectorLowBound->boundFunction.poly(), sectorLowBound->boundFunction.k());
142  explainLiterals.emplace_back(nlsat::helper::buildAbove(cellVariable, param).negated());
143  }
144  auto sectorHighBound = std::get<Sector>(cellComponent).highBound;
145  if (sectorHighBound) {
146  auto param = std::make_pair(sectorHighBound->boundFunction.poly(), sectorHighBound->boundFunction.k());
147  explainLiterals.emplace_back(nlsat::helper::buildBelow(cellVariable, param).negated());
148  }
149  }
150  }
151 
152  // if (!impliedLiteral.is_false())
153  // explainLiterals.emplace_back(impliedLiteral);
154 
155  SMTRAT_LOG_DEBUG("smtrat.mcsat.nlsat", "Explain literals: " << explainLiterals);
156 #ifdef SMTRAT_DEVOPTION_Statistics
157  getStatistic().explanationSuccess();
158 #endif
159  return std::variant<FormulaT, ClauseChain>(FormulaT(carl::FormulaType::OR, std::move(explainLiterals)));
160 }
161 
162 // Instantiations
172 
173 
174 } // namespace levelwise
175 } // namespace onecellcad
176 } // namespace mcsat
177 } // namespace smtrat
Represent the trail, i.e.
Definition: Bookkeeping.h:19
const auto & assignedVariables() const
Definition: Bookkeeping.h:37
const auto & variables() const
Definition: Bookkeeping.h:49
const auto & model() const
Definition: Bookkeeping.h:34
std::optional< CADCell > constructCADCellEnclosingPoint(std::vector< std::vector< TagPoly >> &polys, int sectionHeuristic, int sectorHeuristic)
Construct a single CADCell that contains the given 'point' and is sign-invariant for the given polyno...
Definition: OneCellCAD.h:46
int var(Lit p)
Definition: SolverTypes.h:64
static bool find(V &ts, const T &t)
Definition: Alg.h:47
FormulaT buildEquality(carl::Variable var, const MVRootParams &mvp)
Construct an atomic formula representing a variable being equal to the given multivariate root.
std::set< ConstraintT > convertToConstraints(std::vector< FormulaT > constraintAtoms)
Transform constraints represented as atomic formualas into the easier to use objects of the Constrain...
FormulaT buildBelow(carl::Variable var, const MVRootParams &mvp)
Construct an atomic formula representing a variable being less than the given multivariate root.
FormulaT buildAbove(carl::Variable var, const MVRootParams &mvp)
Construct an atomic formula representing a variable being greater than the given multivariate root.
void appendOnCorrectLevel(const Poly &poly, InvarianceType tag, std::vector< std::vector< TagPoly >> &polys, std::vector< carl::Variable > variableOrder)
Definition: utils.h:186
RealAlgebraicPoint< smtrat::Rational > asRANPoint(const mcsat::Bookkeeping &data)
Definition: utils.h:336
void singleLevelFullProjection(std::vector< carl::Variable > &variableOrder, carl::Variable mainVar, size_t currentLevel, std::vector< std::vector< TagPoly >> &projectionLevels)
Definition: utils.h:655
bool optimized_singleLevelFullProjection(carl::Variable mainVar, size_t currentLevel, std::vector< std::vector< TagPoly >> &projectionLevels, OneCellCAD &cad)
Definition: utils.h:602
Class to create the formulas for axioms.
carl::Formula< Poly > FormulaT
Definition: types.h:37
carl::Formulas< Poly > FormulasT
Definition: types.h:39
Construct a single open CAD Cell around a given point that is sign-invariant on a given set of polyno...
#define SMTRAT_LOG_WARN(channel, msg)
Definition: logging.h:33
#define SMTRAT_LOG_DEBUG(channel, msg)
Definition: logging.h:35
std::optional< mcsat::Explanation > operator()(const mcsat::Bookkeeping &trail, carl::Variable var, const FormulasT &trailLiterals, bool) const
Definition: Explanation.cpp:15