3 #include <carl-arith/constraint/Conversion.h> 
    4 #include <carl-arith/ran/Conversion.h> 
    6 #include <carl-common/util/streamingOperators.h> 
   11 using carl::operator<<;
 
   13 namespace formula_ds {
 
   16 template<
class... Ts> 
struct overloaded : Ts... { 
using Ts::operator()...; };
 
   23             stream << std::string(level, 
' ') << 
"TRUE";
 
   26             stream << std::string(level, 
' ') << 
"FALSE";
 
   29             stream << std::string(level, 
' ') << 
"NOT(" << std::endl;
 
   30             print(stream, db, c.subformula, level+1);
 
   31             stream << std::endl << std::string(level, 
' ') << 
")";
 
   34             stream << std::string(level, 
' ') << 
"AND(" << std::endl;
 
   35             for (
const auto subformula : c.subformulas) {
 
   36                 print(stream, db, subformula, level+1);
 
   39             stream << std::string(level, 
' ') << 
")";
 
   42             stream << std::string(level, 
' ') << 
"OR(" << std::endl;
 
   43             for (
const auto subformula : c.subformulas) {
 
   44                 print(stream, db, subformula, level+1);
 
   47             stream << std::string(level, 
' ') << 
")";
 
   50             stream << std::string(level, 
' ') << 
"IFF(" << std::endl;
 
   51             for (
const auto subformula : c.subformulas) {
 
   52                 print(stream, db, subformula, level+1);
 
   55             stream << std::string(level, 
' ') << 
")";
 
   58             stream << std::string(level, 
' ') << 
"XOR(" << std::endl;
 
   59             for (
const auto subformula : c.subformulas) {
 
   60                 print(stream, db, subformula, level+1);
 
   63             stream << std::string(level, 
' ') << 
")";
 
   66             stream << std::string(level, 
' ') << c.variable;
 
   69             stream << std::string(level, 
' ') << c.constraint;
 
   73     std::size_t spacing = 50 - level;
 
   74     if (level > 50) spacing = 4;
 
   76     stream << std::string(spacing, 
' ') << 
"id: " << 
id << 
" T: " << db[id].reasons_true << 
" F: " << db[id].reasons_false;
 
   90         auto cache_it = cache.find(f.id());
 
   91         if (cache_it != cache.end()) 
return cache_it->second;
 
   94     assert(db.size() < std::numeric_limits<FormulaID>::max());
 
   96     if (f.id() > f.negated().id()) {
 
   98         db.emplace_back(
NOT{ child });
 
   99         db[child].parents.insert((
FormulaID)(db.size()-1));
 
  100         cache.emplace(f.id(), (
FormulaID)(db.size()-1));
 
  106             auto id = 
to_formula_db(c, 
FormulaT(
carl::FormulaType::OR, 
FormulaT(
carl::FormulaType::AND, f.condition(), f.first_case()), 
FormulaT(
carl::FormulaType::AND, f.condition().negated(), f.second_case())), db, vartof, cache);
 
  107             cache.emplace(f.id(), 
id);
 
  110         case carl::FormulaType::TRUE: {
 
  111             db.emplace_back(
TRUE{ });
 
  112             cache.emplace(f.id(), (
FormulaID)(db.size()-1));
 
  115         case carl::FormulaType::FALSE: {
 
  116             db.emplace_back(
FALSE{ });
 
  117             cache.emplace(f.id(), (
FormulaID)(db.size()-1));
 
  121             auto child = 
to_formula_db(c,f.subformula(),db,vartof, cache);
 
  122             db.emplace_back(
NOT{ child });
 
  123             db[child].parents.insert((
FormulaID)(db.size()-1));
 
  124             cache.emplace(f.id(), (
FormulaID)(db.size()-1));
 
  127         case carl::FormulaType::IMPLIES: {
 
  129             cache.emplace(f.id(), 
id);
 
  133             std::vector<FormulaID> subformulas;
 
  134             for (
const auto& sf : f.subformulas()) {
 
  135                 subformulas.emplace_back(
to_formula_db(c,sf, db, vartof, cache));
 
  137             db.emplace_back(
AND{ subformulas });
 
  138             for (
const auto child : subformulas) {
 
  139                 db[child].parents.insert((
FormulaID)(db.size()-1));
 
  141             cache.emplace(f.id(), (
FormulaID)(db.size()-1));
 
  145             std::vector<FormulaID> subformulas;
 
  146             for (
const auto& sf : f.subformulas()) {
 
  147                 subformulas.emplace_back(
to_formula_db(c,sf, db, vartof, cache));
 
  149             db.emplace_back(
OR{ subformulas });
 
  150             for (
const auto child : subformulas) {
 
  151                 db[child].parents.insert((
FormulaID)(db.size()-1));
 
  153             cache.emplace(f.id(), (
FormulaID)(db.size()-1));
 
  157             std::vector<FormulaID> subformulas;
 
  158             for (
const auto& sf : f.subformulas()) {
 
  159                 subformulas.emplace_back(
to_formula_db(c,sf, db, vartof, cache));
 
  161             db.emplace_back(
XOR{ subformulas });
 
  162             for (
const auto child : subformulas) {
 
  163                 db[child].parents.insert((
FormulaID)(db.size()-1));
 
  165             cache.emplace(f.id(), (
FormulaID)(db.size()-1));
 
  169             std::vector<FormulaID> subformulas;
 
  170             for (
const auto& sf : f.subformulas()) {
 
  171                 subformulas.emplace_back(
to_formula_db(c,sf, db, vartof, cache));
 
  173             db.emplace_back(
IFF{ subformulas });
 
  174             for (
const auto child : subformulas) {
 
  175                 db[child].parents.insert((
FormulaID)(db.size()-1));
 
  177             cache.emplace(f.id(), (
FormulaID)(db.size()-1));
 
  180         case carl::FormulaType::CONSTRAINT: {
 
  181             auto bc = carl::convert<cadcells::Polynomial>(c.
polys().context(), f.constraint().constr());
 
  183             auto var = bc.lhs().main_var();
 
  184             vartof.try_emplace(
var).first->second.push_back((
FormulaID)(db.size()-1));
 
  185             cache.emplace(f.id(), (
FormulaID)(db.size()-1));
 
  188         case carl::FormulaType::BOOL: {
 
  189             db.emplace_back(
BOOL{ f.boolean() });
 
  190             vartof.try_emplace(f.boolean()).first->second.push_back((
FormulaID)(db.size()-1));
 
  191             cache.emplace(f.id(), (
FormulaID)(db.size()-1));
 
  196             db.emplace_back(
FALSE{});
 
  197             cache.emplace(f.id(), (
FormulaID)(db.size()-1));
 
  206     if (a.size() == b.size()) {
 
  207         auto it_a = a.begin();
 
  208         auto it_b = b.begin();
 
  209         while (it_a != a.end() && *it_a == *it_b) {
 
  210             assert(it_b != b.end());
 
  214         return (it_a == a.end()) ? 
EQ : 
NONE;
 
  215     } 
else if (a.size() < b.size()) {
 
  223     for (
auto s = set.begin(); s != set.end(); ) {
 
  242     for (
const auto& add : adds) {
 
  243         bool redundant = 
false;
 
  244         for (
auto s = set.begin(); s != set.end(); ) {
 
  259         if (!redundant) to_add.push_back(add);
 
  261     if (to_add.empty()) 
return false;
 
  263         set.insert(set.end(), to_add.begin(), to_add.end());
 
  270     result.reserve(a.size()+b.size());
 
  271     auto first1 = a.begin();
 
  272     auto last1 = a.end();
 
  273     auto first2 = b.begin();
 
  274     auto last2 = b.end();
 
  275     auto d_first = std::back_inserter(
result);
 
  276     for (; first1 != last1; ++d_first) {
 
  277         if (first2 == last2) {
 
  281         if (*first2 < *first1) {
 
  284         } 
else if (*first2 > *first1) {
 
  300     for (
const auto& ar : a) {
 
  301         for (
const auto& br : b) {
 
  309     std::vector<FormulaID> 
tru;
 
  317     for (
const auto f : formulas) {
 
  318         auto sub_val = db[f].valuation();
 
  320             subs.
fals.push_back(f);
 
  322             subs.
tru.push_back(f);
 
  324             subs.
multi.push_back(f);
 
  327             subs.
confl.push_back(f);
 
  341     #ifdef SMTRAT_DEVOPTION_Expensive 
  349             auto val = 
db[id].valuation();
 
  350             auto sub_val = 
db[c.subformula].valuation();
 
  366             auto val = 
db[id].valuation();
 
  371                 if (!subs.fals.empty()) {
 
  372                     for (
const auto& subformula : subs.fals) {
 
  375                 } 
else if (subs.confl.empty() && subs.multi.empty() && subs.fals.empty()) {
 
  377                     reasons.emplace_back();
 
  378                     for (
const auto& subformula : subs.tru) {
 
  388                     for (
const auto subformula : subs.multi) { 
 
  392                     if (subs.multi.size() == 1 && subs.confl.empty() && subs.fals.empty()) {
 
  394                         for (
const auto& subformula : subs.tru) {
 
  403             auto val = 
db[id].valuation();
 
  408                 if (!subs.tru.empty()) {
 
  409                     for (
const auto& subformula : subs.tru) {
 
  412                 } 
else if (subs.confl.empty() && subs.multi.empty() && subs.tru.empty()) {
 
  414                     reasons.emplace_back();
 
  415                     for (
const auto& subformula : subs.fals) {
 
  425                     if (subs.multi.size() == 1 && subs.confl.empty() && subs.tru.empty()) {
 
  427                         for (
const auto& subformula : subs.fals) {
 
  433                     for (
const auto subformula : subs.multi) { 
 
  441             auto val = 
db[id].valuation();
 
  445                 if (!subs.tru.empty() && !subs.fals.empty()) {
 
  447                     for (
const auto t : subs.tru) {
 
  448                         for (
const auto f : subs.fals) {
 
  454                 } 
else if (subs.multi.empty() && !subs.tru.empty()) {
 
  456                     reasons.emplace_back();
 
  457                     for (
const auto t : subs.tru) {
 
  461                 } 
else if (subs.multi.empty() && !subs.fals.empty()) {
 
  463                     reasons.emplace_back();
 
  464                     for (
const auto f : subs.fals) {
 
  474                     for (
const auto t : subs.tru) {
 
  475                         for (
const auto sub : c.subformulas) {
 
  476                             auto sub_val = 
db[sub].valuation();
 
  482                     for (
const auto f : subs.fals) {
 
  483                         for (
const auto sub : c.subformulas) {
 
  484                             auto sub_val = 
db[sub].valuation();
 
  491                     if (subs.multi.size() == 1 && (subs.tru.empty() || subs.fals.empty())) {
 
  492                         if (subs.tru.empty()) {
 
  494                             for (
const auto f : subs.fals) {
 
  499                             assert(subs.fals.empty());
 
  501                             for (
const auto t : subs.tru) {
 
  511             auto val = 
db[id].valuation();
 
  514             if (subs.confl.empty() && (subs.multi.empty() || subs.multi.size() == 1)) {
 
  516                 reasons.emplace_back();
 
  517                 for (
const auto subformula : subs.tru) {
 
  520                 for (
const auto subformula : subs.fals) {
 
  525                 if (subs.multi.empty() && subs.confl.empty()) {
 
  526                     if (subs.tru.size() % 2 != 0) {
 
  535                     if (subs.multi.size() == 1 && subs.confl.empty()) {
 
  536                         bool value = (subs.tru.size() % 2 != 0);
 
  560     SMTRAT_LOG_FUNC(
"smtrat.covering_ng.evaluation", 
id << 
", " << is_true);
 
  561     #ifdef SMTRAT_DEVOPTION_Expensive 
  566         db[id].reasons_true.emplace_back();
 
  569         db[id].reasons_false.emplace_back();
 
  575     SMTRAT_LOG_FUNC(
"smtrat.covering_ng.evaluation", 
id << 
", " << is_true);
 
  576     #ifdef SMTRAT_DEVOPTION_Expensive 
  591             for (
const auto parent : 
db[
id].parents) {
 
  604             for (
const auto parent : 
db[
id].parents) {
 
  625         for (
auto reason = f.reasons_true.begin(); reason != f.reasons_true.end(); ) {
 
  626             if (std::binary_search(reason->begin(), reason->end(), std::make_pair(
id, is_true))) {
 
  627                 reason = f.reasons_true.erase(reason);
 
  632         for (
auto reason = f.reasons_false.begin(); reason != f.reasons_false.end(); ) {
 
  633             if (std::binary_search(reason->begin(), reason->end(), std::make_pair(
id, is_true))) {
 
  634                 reason = f.reasons_false.erase(reason);
 
  640         if (f.reasons_true.empty() || f.reasons_false.empty()) {
 
  649     for (
const auto& [k,v] : new_ass) {
 
  650         if (old_ass.find(k) == old_ass.end()) 
return k;
 
  652     return carl::Variable::NO_VARIABLE;
 
  657 inline carl::BasicConstraint<Poly> 
normalize(
const carl::BasicConstraint<Poly>& c) {
 
  658     assert(c.relation() == carl::Relation::LESS || c.relation() == carl::Relation::LEQ || c.relation() == 
carl::Relation::EQ || c.relation() == carl::Relation::NEQ);
 
  659     return carl::BasicConstraint<Poly>(c.lhs().normalize(), carl::is_negative(c.lhs().lcoeff()) ? carl::turn_around(c.relation()) : c.relation());
 
  669     void set(carl::Relation rel) {
 
  671         else if (rel == carl::Relation::NEQ) 
NEQ = 
true;
 
  672         else if (rel == carl::Relation::LESS) 
LESS = 
true;
 
  673         else if (rel == carl::Relation::LEQ) 
LEQ = 
true;
 
  674         else if (rel == carl::Relation::GREATER) 
GREATER = 
true;
 
  675         else if (rel == carl::Relation::GEQ) 
GEQ = 
true;
 
  680     std::vector<ConstraintT> constraints;
 
  681     carl::arithmetic_constraints(f, constraints);
 
  682     boost::container::flat_map<Poly,PolyInfo> info;
 
  683     for (
const auto& c : constraints) {
 
  685         info.try_emplace(constr.lhs()).first->second.set(constr.relation());
 
  688     std::vector<FormulaT> lemmas;
 
  689     for (
const auto& [poly,rels] : info) {
 
  690         if ((rels.LESS || rels.GEQ) && (rels.GREATER || rels.LEQ)) {
 
  693         if ((rels.LESS || rels.GEQ) && (rels.EQ || rels.NEQ)) {
 
  696         if ((rels.GREATER || rels.LEQ) && (rels.EQ || rels.NEQ)) {
 
  699         if ((rels.LESS || rels.GEQ) && (rels.GREATER || rels.LEQ) && (rels.EQ || rels.NEQ)) {
 
  718     std::map<std::size_t,formula_ds::FormulaID> cache;
 
  724         if (
var.type() == carl::VariableType::VT_REAL) {
 
  726                 const auto& constr_a = std::get<formula_ds::CONSTRAINT>(true_graph.db[a].content).constraint;
 
  727                 const auto& constr_b = std::get<formula_ds::CONSTRAINT>(true_graph.db[b].content).constraint;
 
  728                 return m_constraint_complexity_ordering(m_proj, constr_a, constr_b);
 
  739         if (std::holds_alternative<formula_ds::TRUE>(
true_graph.
db[i].content)) {
 
  742         if (std::holds_alternative<formula_ds::FALSE>(
true_graph.
db[i].content)) {
 
  749         if (std::holds_alternative<formula_ds::TRUE>(
false_graph.
db[i].content)) {
 
  752         if (std::holds_alternative<formula_ds::FALSE>(
false_graph.
db[i].content)) {
 
  761     std::optional<formula_ds::FormulaID> next_dec_id;
 
  762     for (
const auto& [k,vs] : 
vartof) {
 
  764         for (
const auto& v : vs) {
 
  765             if (graph.
db[v].reasons_true.empty() && graph.
db[v].reasons_false.empty()) {
 
  770         if (next_dec_id) 
break;
 
  776     if (true_conflicts.empty()) {
 
  777         true_conflicts = 
explore(graph);
 
  780     if (true_conflicts.empty()) {
 
  786     if (false_conflicts.empty()) {
 
  787         false_conflicts = 
explore(graph);
 
  790     if (false_conflicts.empty()) {
 
  796         std::erase(conflict, std::make_pair(*next_dec_id, 
true));
 
  797         std::erase(conflict, std::make_pair(*next_dec_id, 
false));
 
  806     if (
var == carl::Variable::NO_VARIABLE) 
return;
 
  809     if (atoms == 
vartof.end()) 
return;
 
  811     for (
const auto id : atoms->second) {
 
  812         const auto& constr = std::get<formula_ds::CONSTRAINT>(
true_graph.
db[
id].content).constraint;
 
  815         SMTRAT_LOG_TRACE(
"smtrat.covering_ng.evaluation", 
"Evaluate constraint " << constr);
 
  817         if (!boost::indeterminate(res)) {
 
  855     if (
var == carl::Variable::NO_VARIABLE) 
return;
 
  857     if (atomset == 
vartof.end()) 
return;
 
  859     for (
const auto id : atomset->second) {
 
  864             if (std::binary_search(iter->begin(), iter->end(), std::make_pair(
id, 
m_decisions[
id]))) {
 
  872             if (std::binary_search(iter->begin(), iter->end(), std::make_pair(
id, 
m_decisions[
id]))) {
 
  887     boost::container::flat_set<cadcells::Constraint> implicant;
 
  888     for (
const auto& e : i) {
 
  889         implicant.insert(proj.
polys()(e));
 
  891     std::vector<cadcells::Polynomial> equations;
 
  892     for (
const auto& c : implicant) {
 
  894             equations.emplace_back(c.lhs());
 
  897     if (equations.size()>1) {
 
  898         equations = carl::groebner_basis(equations);
 
  899         for (
auto it = implicant.begin(); it != implicant.end(); ) {
 
  901                 it = implicant.erase(it);
 
  906         for (
const auto& poly : equations) {
 
  911     for (
const auto& e : implicant) {
 
  912         i.insert(proj.
polys()(e));
 
  919     std::vector<boost::container::flat_set<cadcells::datastructures::PolyConstraint>> implicants;
 
  920     for (
const auto& r : reasons) {
 
  921         implicants.emplace_back();
 
  922         for (
const auto& c : r) {
 
  924                 implicants.back().insert(std::get<formula_ds::CONSTRAINT>(
true_graph.
db[c.first].content).constraint);
 
  936         implicants.erase(implicants.begin() + 1, implicants.end());
 
  940             implicants.erase(implicants.begin() + 
m_results, implicants.end());
 
  944         for (
auto& implicant : implicants) {
 
Encapsulates all computations on polynomials.
 
RAN evaluate(const Assignment &sample, IndexedRoot r)
 
PolyConstraint negation(const PolyConstraint &constraint) const
 
auto main_var(PolyRef p) const
 
void sort(T *array, int size, LessThan lt)
 
static void copy(const T &from, T &to)
 
carl::Assignment< RAN > Assignment
 
bool includes(const VariableRange &superset, const carl::Variables &subset)
 
carl::Formula< Poly > FormulaT
 
carl::Constraint< Poly > ConstraintT
 
#define SMTRAT_LOG_TRACE(channel, msg)
 
#define SMTRAT_LOG_FUNC(channel, args)
 
#define SMTRAT_STATISTICS_CALL(function)