mirror of
https://github.com/Z3Prover/z3
synced 2025-04-26 10:35:33 +00:00
Polysat: conflict resolution updates (#5534)
* variable elimination / saturation sketch * conflict resolution updates
This commit is contained in:
parent
dc547510db
commit
9f387f5738
14 changed files with 343 additions and 294 deletions
|
@ -17,32 +17,6 @@ Author:
|
|||
|
||||
namespace polysat {
|
||||
|
||||
bool inf_polynomial_superposition:: perform(conflict_explainer& ce) {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
conflict_explainer::conflict_explainer(solver& s): m_solver(s) {
|
||||
inference_engines.push_back(alloc(inf_polynomial_superposition));
|
||||
}
|
||||
|
||||
bool conflict_explainer::saturate() {
|
||||
for (auto* engine : inference_engines)
|
||||
if (engine->perform(*this))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// clause_ref conflict_explainer::resolve(pvar v, ptr_vector<constraint> const& cjust) {
|
||||
// LOG_H3("Attempting to explain conflict for v" << v);
|
||||
// m_var = v;
|
||||
// m_cjust_v = cjust;
|
||||
|
@ -128,148 +102,6 @@ namespace polysat {
|
|||
// return lemma;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Polynomial superposition.
|
||||
// * So far between two equalities.
|
||||
// * TODO: Also handle =, != superposition here?
|
||||
// * TODO: handle case when m_conflict.units().size() > 2
|
||||
// * TODO: handle super-position into a clause?
|
||||
// */
|
||||
// clause_ref conflict_explainer::by_polynomial_superposition() {
|
||||
// LOG_H3("units-size: " << m_conflict.units().size() << " conflict-clauses " << m_conflict.clauses().size());
|
||||
|
||||
// #if 0
|
||||
// constraint* c1 = nullptr, *c2 = nullptr;
|
||||
|
||||
// if (m_conflict.units().size() == 2 && m_conflict.clauses().size() == 0) {
|
||||
// c1 = m_conflict.units()[0];
|
||||
// c2 = m_conflict.units()[1];
|
||||
// }
|
||||
// else {
|
||||
// // other combinations?
|
||||
|
||||
// #if 1
|
||||
// // A clause can also be a unit.
|
||||
// // Even if a clause is not a unit, we could still resolve a propagation
|
||||
// // into some literal in the current conflict clause.
|
||||
// // Selecting resolvents should not be specific to superposition.
|
||||
|
||||
// for (auto clause : m_conflict.clauses()) {
|
||||
// LOG("clause " << *clause << " size " << clause->size());
|
||||
// if (clause->size() == 1) {
|
||||
// sat::literal lit = (*clause)[0];
|
||||
// // if (lit.sign())
|
||||
// // continue;
|
||||
// constraint* c = m_solver.m_constraints.lookup(lit.var());
|
||||
// // Morally, a derived unit clause is always asserted at the base level.
|
||||
// // (Even if we don't want to keep this one around. But maybe we should? Do we want to reconstruct proofs?)
|
||||
// c->set_unit_clause(clause);
|
||||
// c->assign(!lit.sign());
|
||||
// // this clause is really a unit.
|
||||
// LOG("unit clause: " << *c);
|
||||
// if (c->is_eq()) { // && c->is_positive()) {
|
||||
// c1 = c;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (!c1)
|
||||
// return nullptr;
|
||||
|
||||
// for (constraint* c : m_conflict.units()) {
|
||||
// if (c->is_eq() && c->is_positive()) {
|
||||
// c2 = c;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// #endif
|
||||
// }
|
||||
// if (!c1 || !c2 || c1 == c2)
|
||||
// return nullptr;
|
||||
// LOG("c1: " << show_deref(c1));
|
||||
// LOG("c2: " << show_deref(c2));
|
||||
// if (c1->is_eq() && c2->is_eq() && c1->is_positive() && c2->is_positive()) {
|
||||
// pdd a = c1->to_eq().p();
|
||||
// pdd b = c2->to_eq().p();
|
||||
// pdd r = a;
|
||||
// if (!a.resolve(m_var, b, r) && !b.resolve(m_var, a, r))
|
||||
// return nullptr;
|
||||
// unsigned const lvl = std::max(c1->level(), c2->level());
|
||||
// clause_builder clause(m_solver);
|
||||
// clause.push_literal(~c1->blit());
|
||||
// clause.push_literal(~c2->blit());
|
||||
// clause.push_new_constraint(m_solver.m_constraints.eq(lvl, r));
|
||||
// return clause.build();
|
||||
// }
|
||||
// if (c1->is_eq() && c2->is_eq() && c1->is_negative() && c2->is_positive()) {
|
||||
// pdd a = c1->to_eq().p();
|
||||
// pdd b = c2->to_eq().p();
|
||||
// pdd r = a;
|
||||
// // TODO: only holds if the factor for 'a' is non-zero
|
||||
// if (!a.resolve(m_var, b, r))
|
||||
// return nullptr;
|
||||
// unsigned const lvl = std::max(c1->level(), c2->level());
|
||||
// clause_builder clause(m_solver);
|
||||
// clause.push_literal(~c1->blit());
|
||||
// clause.push_literal(~c2->blit());
|
||||
// clause.push_new_constraint(~m_solver.m_constraints.eq(lvl, r));
|
||||
// SASSERT(false); // TODO "breakpoint" for debugging
|
||||
// return clause.build();
|
||||
// }
|
||||
|
||||
// #else
|
||||
// for (constraint* c1 : m_conflict_units) {
|
||||
// if (!c1->is_eq())
|
||||
// continue;
|
||||
// for (constraint* c2 : m_conflict_units) { // TODO: can start iteration at index(c1)+1
|
||||
// if (c1 == c2)
|
||||
// continue;
|
||||
// if (!c2->is_eq())
|
||||
// continue;
|
||||
// if (c1->is_negative() && c2->is_negative())
|
||||
// continue;
|
||||
// LOG("c1: " << show_deref(c1));
|
||||
// LOG("c2: " << show_deref(c2));
|
||||
// if (c1->is_positive() && c2->is_negative()) {
|
||||
// std::swap(c1, c2);
|
||||
// }
|
||||
// pdd a = c1->to_eq().p();
|
||||
// pdd b = c2->to_eq().p();
|
||||
// pdd r = a;
|
||||
// unsigned const lvl = std::max(c1->level(), c2->level());
|
||||
// if (c1->is_positive() && c2->is_positive()) {
|
||||
// if (!a.resolve(m_var, b, r) && !b.resolve(m_var, a, r))
|
||||
// continue;
|
||||
// clause_builder clause(m_solver);
|
||||
// clause.push_literal(~c1->blit());
|
||||
// clause.push_literal(~c2->blit());
|
||||
// clause.push_new_constraint(m_solver.m_constraints.eq(lvl, r));
|
||||
// auto cl = clause.build();
|
||||
// LOG("r: " << show_deref(cl->new_constraints()[0]));
|
||||
// LOG("result: " << show_deref(cl));
|
||||
// // SASSERT(false); // NOTE: this is a simple "breakpoint" for debugging
|
||||
// return cl;
|
||||
// }
|
||||
// if (c1->is_negative() && c2->is_positive()) {
|
||||
// // TODO: only holds if the factor for 'a' is non-zero
|
||||
// if (!a.resolve(m_var, b, r))
|
||||
// continue;
|
||||
// clause_builder clause(m_solver);
|
||||
// clause.push_literal(~c1->blit());
|
||||
// clause.push_literal(~c2->blit());
|
||||
// clause.push_new_constraint(~m_solver.m_constraints.eq(lvl, r));
|
||||
// auto cl = clause.build();
|
||||
// LOG("r: " << show_deref(cl->new_constraints()[0]));
|
||||
// LOG("result: " << show_deref(cl));
|
||||
// // SASSERT(false); // NOTE: this is a simple "breakpoint" for debugging
|
||||
// return cl;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// #endif
|
||||
// return nullptr;
|
||||
// }
|
||||
|
||||
// /// [x] zx > yx ==> Ω*(x,y) \/ z > y
|
||||
// /// [x] yx <= zx ==> Ω*(x,y) \/ y <= z
|
||||
// clause_ref conflict_explainer::by_ugt_x() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue