SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
CoveringNGModule.tpp
Go to the documentation of this file.
1 #include "CoveringNGModule.h"
2 
3 #include <carl-arith/ran/Conversion.h>
4 #include <carl-formula/formula/functions/Substitution.h>
5 #include <smtrat-coveringng/Algorithm.h>
6 #include <smtrat-coveringng/VariableOrdering.h>
7 
8 namespace smtrat {
9 
10 template<class Settings>
11 CoveringNGModule<Settings>::CoveringNGModule(const ModuleInput* _formula, Conditionals& _conditionals, Manager* _manager)
12  : Module(_formula, _conditionals, _manager) {}
13 
14 template<class Settings>
15 CoveringNGModule<Settings>::~CoveringNGModule() {}
16 
17 template<class Settings>
18 bool CoveringNGModule<Settings>::informCore(const FormulaT&) {
19  return true;
20 }
21 
22 template<class Settings>
23 bool CoveringNGModule<Settings>::addCore(ModuleInput::const_iterator) {
24  return true;
25 }
26 
27 template<class Settings>
28 void CoveringNGModule<Settings>::removeCore(ModuleInput::const_iterator) {}
29 
30 template<class Settings>
31 void CoveringNGModule<Settings>::updateModel() const {}
32 
33 template<typename Settings>
34 Answer CoveringNGModule<Settings>::checkCore() {
35  FormulaT input(rReceivedFormula());
36 
37  std::map<carl::Variable, carl::Variable> var_mapping;
38  // for quantified problems, the following setting is mandatory for correctness:
39  if constexpr (Settings::transform_boolean_variables_to_reals) {
40  // this is a hack until we have proper Boolean reasoning
41  std::map<FormulaT,FormulaT> substitutions;
42  for (const auto b_var : carl::boolean_variables(input)) {
43  auto r_var = carl::fresh_real_variable("r_"+b_var.name());
44  var_mapping.emplace(r_var, b_var);
45  auto constraint = FormulaT(ConstraintT(r_var, carl::Relation::GREATER));
46  substitutions.emplace(FormulaT(b_var), constraint);
47  //substitutions.emplace(FormulaT(b_var).negated(), constraint.negated());
48  }
49  input = carl::substitute(input, substitutions);
50  assert(carl::boolean_variables(input).empty());
51  SMTRAT_LOG_DEBUG("smtrat.covering_ng", "Formula after replacing Boolean variables: " << input);
52  }
53 
54  carl::QuantifierPrefix prefix;
55  FormulaT matrix;
56  if ((carl::PROP_CONTAINS_QUANTIFIER_EXISTS <= input.properties()) || (carl::PROP_CONTAINS_QUANTIFIER_FORALL <= input.properties())) {
57  std::tie(prefix, matrix) = carl::to_pnf(input);
58  SMTRAT_LOG_DEBUG("smtrat.covering_ng", "Got PNF: " << prefix << " " << matrix);
59  #ifdef SMTRAT_DEVOPTION_Validation
60  SMTRAT_VALIDATION_ADD("smtrat.covering_ng", "pnf", FormulaT(carl::FormulaType::IFF, input, carl::to_formula(prefix, matrix)).negated(), false)
61  #endif
62  } else {
63  SMTRAT_LOG_DEBUG("smtrat.covering_ng", "Got QF formula: " << input);
64  matrix = input;
65  }
66  assert(!prefix.empty() || input == matrix);
67 
68  covering_ng::VariableQuantification variable_quantification;
69  for (const auto& q : prefix) {
70  variable_quantification.set_var_type(q.second, q.first);
71  }
72 
73  std::vector<carl::Variable> var_order = covering_ng::variables::get_variable_ordering<Settings::variable_ordering_heuristic>(prefix, matrix);
74 
75  SMTRAT_STATISTICS_CALL(covering_ng::statistics().variable_ordering(var_order, var_mapping));
76  SMTRAT_STATISTICS_CALL(cadcells::statistics().set_max_level(var_order.size()));
77 
78  //auto var_order = carl::variables(input).to_vector();
79  // std::vector<ConstraintT> constraints;
80  // carl::arithmetic_constraints(input, constraints);
81  // auto var_order = mcsat::calculate_variable_order<Settings::variable_ordering>(constraints);
82 
83  cadcells::Polynomial::ContextType context(var_order);
84  cadcells::datastructures::PolyPool pool(context);
85  cadcells::datastructures::Projections proj(pool);
86 
87  cadcells::Assignment ass;
88  auto f = Settings::formula_evaluation::create(proj);
89  f.set_formula(matrix);
90  f.extend_valuation(ass);
91  if (f.root_valuation() == covering_ng::formula::Valuation::FALSE || matrix.is_false()) {
92  mModel.clear();
93  generateTrivialInfeasibleSubset();
94  return Answer::UNSAT;
95  } else if (f.root_valuation() == covering_ng::formula::Valuation::TRUE || matrix.is_true()) {
96  mModel.clear();
97  return Answer::SAT;
98  }
99 
100  //auto res = covering_ng::exists<typename Settings::op, typename Settings::formula_evaluation::Type, Settings::covering_heuristic, Settings::sampling_algorithm>(proj, f, ass);
101  auto res = covering_ng::recurse<typename Settings::op, typename Settings::formula_evaluation::Type, Settings::covering_heuristic, Settings::sampling_algorithm, Settings::cell_heuristic>(proj, f, ass, variable_quantification);
102 
103  if (res.is_failed()) {
104  assert(!Settings::transform_boolean_variables_to_reals || res.is_failed_projection());
105  mModel.clear();
106  return Answer::UNKNOWN;
107  } else if (res.is_sat()) {
108  mModel.clear();
109  if (res.sample()) {
110  for (const auto& a : *res.sample()) {
111  if constexpr (Settings::transform_boolean_variables_to_reals) {
112  auto var_mapping_it = var_mapping.find(a.first);
113  if (var_mapping_it != var_mapping.end()) {
114  mModel.emplace(var_mapping_it->second, a.second > 0);
115  } else {
116  mModel.emplace(a.first, carl::convert<smtrat::RAN>(a.second));
117  }
118  } else {
119  mModel.emplace(a.first, carl::convert<smtrat::RAN>(a.second));
120  }
121  }
122  }
123  return Answer::SAT;
124  } else {
125  mModel.clear();
126  generateTrivialInfeasibleSubset();
127  return Answer::UNSAT;
128  }
129 }
130 
131 } // namespace smtrat
132