3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-11-06 06:16:02 +00:00

merging master to unit_prop_on_monomials

This commit is contained in:
Lev Nachmanson 2023-10-02 16:42:59 -07:00
parent a297a2b25c
commit 7de06c4350
19 changed files with 333 additions and 375 deletions

View file

@ -264,7 +264,7 @@ class theory_lra::imp {
void ensure_nla() {
if (!m_nla) {
m_nla = alloc(nla::solver, *m_solver.get(), ctx().get_params(), m.limit(), m_implied_bounds);
m_nla = alloc(nla::solver, *m_solver.get(), ctx().get_params(), m.limit());
for (auto const& _s : m_scopes) {
(void)_s;
m_nla->push();
@ -1528,14 +1528,12 @@ public:
unsigned old_sz = m_assume_eq_candidates.size();
unsigned num_candidates = 0;
int start = ctx().get_random_value();
unsigned num_relevant = 0;
for (theory_var i = 0; i < sz; ++i) {
theory_var v = (i + start) % sz;
enode* n1 = get_enode(v);
if (!th.is_relevant_and_shared(n1)) {
continue;
}
++num_relevant;
ensure_column(v);
if (!is_registered_var(v))
continue;
@ -1553,7 +1551,7 @@ public:
num_candidates++;
}
}
if (num_candidates > 0) {
ctx().push_trail(restore_vector(m_assume_eq_candidates, old_sz));
}
@ -1605,8 +1603,7 @@ public:
case l_true:
return FC_DONE;
case l_false:
for (const nla::lemma & l : m_nla->lemmas())
false_case_of_check_nla(l);
add_lemmas();
return FC_CONTINUE;
case l_undef:
return FC_GIVEUP;
@ -1803,8 +1800,7 @@ public:
if (!m_nla)
return true;
m_nla->check_bounded_divisions();
for (auto & lemma : m_nla->lemmas())
false_case_of_check_nla(lemma);
add_lemmas();
return m_nla->lemmas().empty();
}
@ -2003,7 +1999,7 @@ public:
// create term >= 0 (or term <= 0)
atom = mk_bound(ineq.term(), ineq.rs(), is_lower);
return literal(ctx().get_bool_var(atom), pos);
}
}
void false_case_of_check_nla(const nla::lemma & l) {
m_lemma = l; //todo avoid the copy
@ -2024,14 +2020,11 @@ public:
final_check_status check_nla_continue() {
m_a1 = nullptr; m_a2 = nullptr;
lbool r = m_nla->check(m_nla_literals);
lbool r = m_nla->check();
switch (r) {
case l_false:
for (const nla::ineq& i : m_nla_literals)
assume_literal(i);
for (const nla::lemma & l : m_nla->lemmas())
false_case_of_check_nla(l);
add_lemmas();
return FC_CONTINUE;
case l_true:
return assume_eqs()? FC_CONTINUE: FC_DONE;
@ -2120,6 +2113,8 @@ public:
bool propagate_core() {
m_model_is_initialized = false;
flush_bound_axioms();
// disabled in master:
propagate_nla();
if (!can_propagate_core())
return false;
m_new_def = false;
@ -2151,7 +2146,6 @@ public:
break;
case l_true:
propagate_basic_bounds();
propagate_bounds_with_nlp();
propagate_bounds_with_lp_solver();
break;
case l_undef:
@ -2161,6 +2155,47 @@ public:
return true;
}
void propagate_nla() {
if (m_nla) {
m_nla->propagate();
add_lemmas();
add_equalities();
}
}
void add_equalities() {
if (!propagate_eqs())
return;
for (auto const& [v,k,e] : m_nla->fixed_equalities())
add_equality(v, k, e);
for (auto const& [i,j,e] : m_nla->equalities())
add_eq(i,j,e,false);
}
void add_equality(lpvar j, rational const& k, lp::explanation const& exp) {
//verbose_stream() << "equality " << j << " " << k << "\n";
TRACE("arith", tout << "equality " << j << " " << k << "\n");
theory_var v;
if (k == 1)
v = m_one_var;
else if (k == 0)
v = m_zero_var;
else if (!m_value2var.find(k, v))
return;
theory_var w = lp().local_to_external(j);
if (w < 0)
return;
lpvar i = register_theory_var_in_lar_solver(v);
add_eq(i, j, exp, true);
}
void add_lemmas() {
for (const nla::ineq& i : m_nla->literals())
assume_literal(i);
for (const nla::lemma & l : m_nla->lemmas())
false_case_of_check_nla(l);
}
bool should_propagate() const {
return bound_prop_mode::BP_NONE != propagation_mode();
}
@ -2173,50 +2208,33 @@ public:
set_evidence(j, m_core, m_eqs);
m_explanation.add_pair(j, v);
}
void propagate_bounds_with_lp_solver() {
if (!should_propagate())
return;
m_bp.init();
lp().propagate_bounds_for_touched_rows(m_bp);
if (!m.inc())
return;
void finish_bound_propagation() {
if (is_infeasible()) {
get_infeasibility_explanation_and_set_conflict();
// verbose_stream() << "unsat\n";
}
else {
for (auto &ib : m_bp.ibounds()) {
unsigned count = 0, prop = 0;
for (auto& ib : m_bp.ibounds()) {
m.inc();
if (ctx().inconsistent())
break;
propagate_lp_solver_bound(ib);
++prop;
count += propagate_lp_solver_bound(ib);
}
}
}
void propagate_bounds_with_lp_solver() {
if (!should_propagate())
return;
m_bp.init();
lp().propagate_bounds_for_touched_rows(m_bp);
if (m.inc())
finish_bound_propagation();
}
void propagate_bounds_for_monomials() {
m_nla->propagate_bounds_for_touched_monomials();
for (const auto & l : m_nla->lemmas())
false_case_of_check_nla(l);
}
void propagate_bounds_with_nlp() {
if (!m_nla)
return;
if (is_infeasible() || !should_propagate())
return;
propagate_bounds_for_monomials();
if (m.inc())
finish_bound_propagation();
}
bool bound_is_interesting(unsigned vi, lp::lconstraint_kind kind, const rational & bval) const {
theory_var v = lp().local_to_external(vi);
if (v == null_theory_var)
@ -3161,8 +3179,7 @@ public:
std::function<expr*(void)> fn = [&]() { return m.mk_eq(x->get_expr(), y->get_expr()); };
scoped_trace_stream _sts(th, fn);
// SASSERT(validate_eq(x, y));
//VERIFY(validate_eq(x, y));
ctx().assign_eq(x, y, eq_justification(js));
}
@ -3206,12 +3223,11 @@ public:
}
lp::explanation m_explanation;
vector<nla::ineq> m_nla_literals;
literal_vector m_core;
svector<enode_pair> m_eqs;
vector<parameter> m_params;
void reset_evidence() {
void reset_evidence() {
m_core.reset();
m_eqs.reset();
m_params.reset();
@ -3278,6 +3294,7 @@ public:
display(tout << "is-conflict: " << is_conflict << "\n"););
for (auto ev : m_explanation)
set_evidence(ev.ci(), m_core, m_eqs);
// SASSERT(validate_conflict(m_core, m_eqs));
if (is_conflict) {
@ -3533,6 +3550,8 @@ public:
lbool r = nctx.check();
if (r == l_true) {
nctx.display_asserted_formulas(std::cout);
std::cout.flush();
std::cout.flush();
}
return l_true != r;
}
@ -3882,6 +3901,7 @@ public:
IF_VERBOSE(1, verbose_stream() << enode_pp(n, ctx()) << " evaluates to " << r2 << " but arith solver has " << r1 << "\n");
}
}
};
theory_lra::theory_lra(context& ctx):