1 #include "CoveringNGModule.h"
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>
10 template<class Settings>
11 CoveringNGModule<Settings>::CoveringNGModule(const ModuleInput* _formula, Conditionals& _conditionals, Manager* _manager)
12 : Module(_formula, _conditionals, _manager) {}
14 template<class Settings>
15 CoveringNGModule<Settings>::~CoveringNGModule() {}
17 template<class Settings>
18 bool CoveringNGModule<Settings>::informCore(const FormulaT&) {
22 template<class Settings>
23 bool CoveringNGModule<Settings>::addCore(ModuleInput::const_iterator) {
27 template<class Settings>
28 void CoveringNGModule<Settings>::removeCore(ModuleInput::const_iterator) {}
30 template<class Settings>
31 void CoveringNGModule<Settings>::updateModel() const {}
33 template<typename Settings>
34 Answer CoveringNGModule<Settings>::checkCore() {
35 FormulaT input(rReceivedFormula());
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());
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);
54 carl::QuantifierPrefix prefix;
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)
63 SMTRAT_LOG_DEBUG("smtrat.covering_ng", "Got QF formula: " << input);
66 assert(!prefix.empty() || input == matrix);
68 covering_ng::VariableQuantification variable_quantification;
69 for (const auto& q : prefix) {
70 variable_quantification.set_var_type(q.second, q.first);
73 std::vector<carl::Variable> var_order = covering_ng::variables::get_variable_ordering<Settings::variable_ordering_heuristic>(prefix, matrix);
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()));
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);
83 cadcells::Polynomial::ContextType context(var_order);
84 cadcells::datastructures::PolyPool pool(context);
85 cadcells::datastructures::Projections proj(pool);
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()) {
93 generateTrivialInfeasibleSubset();
95 } else if (f.root_valuation() == covering_ng::formula::Valuation::TRUE || matrix.is_true()) {
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);
103 if (res.is_failed()) {
104 assert(!Settings::transform_boolean_variables_to_reals || res.is_failed_projection());
106 return Answer::UNKNOWN;
107 } else if (res.is_sat()) {
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);
116 mModel.emplace(a.first, carl::convert<smtrat::RAN>(a.second));
119 mModel.emplace(a.first, carl::convert<smtrat::RAN>(a.second));
126 generateTrivialInfeasibleSubset();
127 return Answer::UNSAT;
131 } // namespace smtrat