mirror of
https://github.com/Z3Prover/z3
synced 2025-06-07 06:33:23 +00:00
add ad-hoc debug output, add rule for incremental linearization
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
677e261bb1
commit
f0b056d859
6 changed files with 73 additions and 7 deletions
|
@ -311,8 +311,13 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
|
|
||||||
void core::viable_conflict(pvar v) {
|
void core::viable_conflict(pvar v) {
|
||||||
|
if (s.inconsistent())
|
||||||
|
return;
|
||||||
TRACE("bv", tout << "viable-conflict v" << v << "\n");
|
TRACE("bv", tout << "viable-conflict v" << v << "\n");
|
||||||
s.set_conflict(m_viable.explain(), "viable-conflict");
|
auto exp = m_viable.explain();
|
||||||
|
if (s.inconsistent())
|
||||||
|
verbose_stream() << "inconsistent " << exp << "\n";
|
||||||
|
s.set_conflict(exp, "viable-conflict");
|
||||||
decay_activity();
|
decay_activity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,6 +376,7 @@ namespace polysat {
|
||||||
else if (v == null_var && weak_eval(sc) == l_false) {
|
else if (v == null_var && weak_eval(sc) == l_false) {
|
||||||
auto ex = explain_weak_eval(sc);
|
auto ex = explain_weak_eval(sc);
|
||||||
ex.push_back(dep);
|
ex.push_back(dep);
|
||||||
|
verbose_stream() << "infeasible propagation " << ~sc << " <- " << ex << "\n";
|
||||||
s.set_conflict(ex, "infeasible propagation");
|
s.set_conflict(ex, "infeasible propagation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -381,6 +387,7 @@ namespace polysat {
|
||||||
if (!m_viable.assign(v, value)) {
|
if (!m_viable.assign(v, value)) {
|
||||||
auto deps = m_viable.explain();
|
auto deps = m_viable.explain();
|
||||||
deps.push_back(dep);
|
deps.push_back(dep);
|
||||||
|
verbose_stream() << "non-viable assignment v" << v << " == " << value << " <- " << deps << "\n";
|
||||||
s.set_conflict(deps, "non-viable assignment");
|
s.set_conflict(deps, "non-viable assignment");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -489,6 +496,7 @@ namespace polysat {
|
||||||
else if (value != eval_value) {
|
else if (value != eval_value) {
|
||||||
m_unsat_core = explain_weak_eval(sc);
|
m_unsat_core = explain_weak_eval(sc);
|
||||||
m_unsat_core.push_back(m_constraint_index[id.id].d);
|
m_unsat_core.push_back(m_constraint_index[id.id].d);
|
||||||
|
verbose_stream() << "infeasible propagation " << m_unsat_core << "\n";
|
||||||
s.set_conflict(m_unsat_core, "polysat-constraint-core");
|
s.set_conflict(m_unsat_core, "polysat-constraint-core");
|
||||||
decay_activity();
|
decay_activity();
|
||||||
}
|
}
|
||||||
|
@ -645,7 +653,7 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
|
|
||||||
void core::inc_activity(pvar v) {
|
void core::inc_activity(pvar v) {
|
||||||
unsigned& act = m_activity[v].second;
|
unsigned& act = m_activity[v].act;
|
||||||
act += m_activity_inc;
|
act += m_activity_inc;
|
||||||
m_var_queue.activity_increased_eh(v);
|
m_var_queue.activity_increased_eh(v);
|
||||||
if (act > (1 << 24))
|
if (act > (1 << 24))
|
||||||
|
@ -654,7 +662,7 @@ namespace polysat {
|
||||||
|
|
||||||
void core::rescale_activity() {
|
void core::rescale_activity() {
|
||||||
for (auto& act : m_activity)
|
for (auto& act : m_activity)
|
||||||
act.second >>= 14;
|
act.act >>= 14;
|
||||||
m_activity_inc >>= 14;
|
m_activity_inc >>= 14;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,11 +35,23 @@ namespace polysat {
|
||||||
|
|
||||||
|
|
||||||
class core {
|
class core {
|
||||||
|
struct var_activity {
|
||||||
|
unsigned sz;
|
||||||
|
unsigned act;
|
||||||
|
bool operator<(var_activity const& other) const {
|
||||||
|
if (other.sz != sz)
|
||||||
|
return sz > other.sz;
|
||||||
|
return act < other.act;
|
||||||
|
};
|
||||||
|
bool operator>(var_activity const& other) const {
|
||||||
|
return other < *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
class mk_add_var;
|
class mk_add_var;
|
||||||
class mk_dqueue_var;
|
class mk_dqueue_var;
|
||||||
class mk_assign_var;
|
class mk_assign_var;
|
||||||
class mk_add_watch;
|
class mk_add_watch;
|
||||||
typedef svector<std::pair<unsigned, unsigned>> activity;
|
typedef svector<var_activity> activity;
|
||||||
friend class viable;
|
friend class viable;
|
||||||
friend class constraints;
|
friend class constraints;
|
||||||
friend class assignment;
|
friend class assignment;
|
||||||
|
|
|
@ -66,6 +66,8 @@ namespace polysat {
|
||||||
return l_false;
|
return l_false;
|
||||||
if (any_of(m_to_refine, [&](auto i) { return mul1(m_monomials[i]); }))
|
if (any_of(m_to_refine, [&](auto i) { return mul1(m_monomials[i]); }))
|
||||||
return l_false;
|
return l_false;
|
||||||
|
if (any_of(m_to_refine, [&](auto i) { return mul1_inverse(m_monomials[i]); }))
|
||||||
|
return l_false;
|
||||||
|
|
||||||
if (any_of(m_to_refine, [&](auto i) { return non_overflow_unit(m_monomials[i]); }))
|
if (any_of(m_to_refine, [&](auto i) { return non_overflow_unit(m_monomials[i]); }))
|
||||||
return l_false;
|
return l_false;
|
||||||
|
@ -169,6 +171,23 @@ namespace polysat {
|
||||||
return c.add_axiom("p = k => p * q = k * q", cs, true);
|
return c.add_axiom("p = k => p * q = k * q", cs, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// p * q = p => q = 1 or p = 0
|
||||||
|
bool monomials::mul1_inverse(monomial const& mon) {
|
||||||
|
for (unsigned j = mon.size(); j-- > 0; ) {
|
||||||
|
auto const& arg_val = mon.arg_vals[j];
|
||||||
|
if (arg_val == mon.val) {
|
||||||
|
auto const& p = mon.args[j];
|
||||||
|
pdd qs = c.value(rational(1), mon.num_bits());
|
||||||
|
for (unsigned k = mon.size(); k-- > 0; )
|
||||||
|
if (k != j)
|
||||||
|
qs *= mon.arg_vals[k];
|
||||||
|
c.add_axiom("p * q = p => q = 1 or p = 0", { ~C.eq(mon.var, p), C.eq(qs, 1), C.eq(p) }, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// parity p >= i => parity p * q >= i
|
// parity p >= i => parity p * q >= i
|
||||||
bool monomials::parity(monomial const& mon) {
|
bool monomials::parity(monomial const& mon) {
|
||||||
unsigned parity_val = get_parity(mon.val, mon.num_bits());
|
unsigned parity_val = get_parity(mon.val, mon.num_bits());
|
||||||
|
|
|
@ -49,6 +49,7 @@ namespace polysat {
|
||||||
bool mul0(monomial const& mon);
|
bool mul0(monomial const& mon);
|
||||||
bool mul1(monomial const& mon);
|
bool mul1(monomial const& mon);
|
||||||
bool mulp2(monomial const& mon);
|
bool mulp2(monomial const& mon);
|
||||||
|
bool mul1_inverse(monomial const& mon);
|
||||||
bool mul(monomial const& mon, std::function<bool(rational const&)> const& p);
|
bool mul(monomial const& mon, std::function<bool(rational const&)> const& p);
|
||||||
bool parity(monomial const& mon);
|
bool parity(monomial const& mon);
|
||||||
bool non_overflow_monotone(monomial const& mon);
|
bool non_overflow_monotone(monomial const& mon);
|
||||||
|
|
|
@ -555,6 +555,8 @@ namespace polysat {
|
||||||
auto last = m_explain.back();
|
auto last = m_explain.back();
|
||||||
auto after = last;
|
auto after = last;
|
||||||
|
|
||||||
|
if (c.inconsistent())
|
||||||
|
verbose_stream() << "inconistent explain\n";
|
||||||
TRACE("bv", display_explain(tout));
|
TRACE("bv", display_explain(tout));
|
||||||
|
|
||||||
auto unmark = [&]() {
|
auto unmark = [&]() {
|
||||||
|
@ -564,13 +566,20 @@ namespace polysat {
|
||||||
|
|
||||||
auto explain_entry = [&](entry* e) {
|
auto explain_entry = [&](entry* e) {
|
||||||
auto index = e->constraint_index;
|
auto index = e->constraint_index;
|
||||||
|
if (c.inconsistent())
|
||||||
|
return;
|
||||||
if (e->marked)
|
if (e->marked)
|
||||||
return;
|
return;
|
||||||
e->marked = true;
|
e->marked = true;
|
||||||
if (m_var != e->var)
|
if (m_var != e->var)
|
||||||
result.push_back(offset_claim(m_var, { e->var, 0 }));
|
result.push_back(offset_claim(m_var, { e->var, 0 }));
|
||||||
for (auto const& sc : e->side_cond)
|
for (auto const& sc : e->side_cond) {
|
||||||
result.push_back(c.propagate(sc, c.explain_weak_eval(sc)));
|
auto d = c.propagate(sc, c.explain_weak_eval(sc));
|
||||||
|
if (c.inconsistent()) {
|
||||||
|
verbose_stream() << "inconsistent " << d << " " << sc << "\n";
|
||||||
|
}
|
||||||
|
result.push_back(d);
|
||||||
|
}
|
||||||
result.append(e->deps);
|
result.append(e->deps);
|
||||||
if (!index.is_null())
|
if (!index.is_null())
|
||||||
result.push_back(c.get_dependency(index));
|
result.push_back(c.get_dependency(index));
|
||||||
|
@ -600,7 +609,11 @@ namespace polysat {
|
||||||
explain_entry(first.e);
|
explain_entry(first.e);
|
||||||
// add constraint that there is only a single viable value.
|
// add constraint that there is only a single viable value.
|
||||||
auto sc = cs.eq(last.e->interval.hi() + 1, first.e->interval.lo());
|
auto sc = cs.eq(last.e->interval.hi() + 1, first.e->interval.lo());
|
||||||
result.push_back(c.propagate(sc, c.explain_weak_eval(sc)));
|
auto exp = c.propagate(sc, c.explain_weak_eval(sc));
|
||||||
|
if (c.inconsistent()) {
|
||||||
|
verbose_stream() << "inconsistent " << sc << " " << exp << "\n";
|
||||||
|
}
|
||||||
|
result.push_back(exp);
|
||||||
}
|
}
|
||||||
if (m_explain_kind == explain_t::assignment) {
|
if (m_explain_kind == explain_t::assignment) {
|
||||||
// there is just one entry
|
// there is just one entry
|
||||||
|
@ -608,6 +621,8 @@ namespace polysat {
|
||||||
explain_entry(last.e);
|
explain_entry(last.e);
|
||||||
}
|
}
|
||||||
unmark();
|
unmark();
|
||||||
|
if (c.inconsistent())
|
||||||
|
verbose_stream() << "inconistent after explain\n";
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,6 +706,8 @@ namespace polysat {
|
||||||
t.reset(lo.manager());
|
t.reset(lo.manager());
|
||||||
t = c.value(mod(e.value, rational::power_of_two(aw)), aw);
|
t = c.value(mod(e.value, rational::power_of_two(aw)), aw);
|
||||||
// verbose_stream() << "after " << t << "\n";
|
// verbose_stream() << "after " << t << "\n";
|
||||||
|
if (c.inconsistent())
|
||||||
|
verbose_stream() << "inconsistent overlap " << sc << " " << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abw < aw)
|
if (abw < aw)
|
||||||
|
@ -700,6 +717,12 @@ namespace polysat {
|
||||||
SASSERT(!sc.is_always_false());
|
SASSERT(!sc.is_always_false());
|
||||||
if (!sc.is_always_true())
|
if (!sc.is_always_true())
|
||||||
deps.push_back(c.propagate(sc, c.explain_weak_eval(sc)));
|
deps.push_back(c.propagate(sc, c.explain_weak_eval(sc)));
|
||||||
|
if (c.inconsistent()) {
|
||||||
|
verbose_stream() << "inconsistent ult " << sc << " " << "\n";
|
||||||
|
verbose_stream() << "before bw " << ebw << " " << bw << " " << *e.e << "\nafter bw " << abw << " " << aw << " " << *after.e << "\n";
|
||||||
|
display(verbose_stream());
|
||||||
|
// UNREACHABLE();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -260,6 +260,9 @@ namespace polysat {
|
||||||
hint = mk_proof_hint(hint_info, core, eqs);
|
hint = mk_proof_hint(hint_info, core, eqs);
|
||||||
core.pop_back();
|
core.pop_back();
|
||||||
}
|
}
|
||||||
|
if (s().value(lit) == l_false) {
|
||||||
|
verbose_stream() << "contradictory propagation " << sc << " <- " << deps << "\n";
|
||||||
|
}
|
||||||
auto ex = euf::th_explain::propagate(*this, core, eqs, lit, hint);
|
auto ex = euf::th_explain::propagate(*this, core, eqs, lit, hint);
|
||||||
validate_propagate(lit, core, eqs);
|
validate_propagate(lit, core, eqs);
|
||||||
ctx.propagate(lit, ex);
|
ctx.propagate(lit, ex);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue