mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 12:08:18 +00:00
restore the lemma scheme
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
288e66de59
commit
47b64e689c
|
@ -31,7 +31,7 @@ namespace lp {
|
||||||
lra.remove_fixed_vars_from_base();
|
lra.remove_fixed_vars_from_base();
|
||||||
lp_assert(lia.is_feasible());
|
lp_assert(lia.is_feasible());
|
||||||
for (unsigned j : lra.r_basis())
|
for (unsigned j : lra.r_basis())
|
||||||
if (!lra.get_value(j).is_int() && lra.column_is_int(j)&& !lia.is_fixed(j))
|
if (!lra.get_value(j).is_int() && lra.column_is_int(j) && !lia.is_fixed(j))
|
||||||
patch_basic_column(j);
|
patch_basic_column(j);
|
||||||
if (!lia.has_inf_int()) {
|
if (!lia.has_inf_int()) {
|
||||||
lia.settings().stats().m_patches_success++;
|
lia.settings().stats().m_patches_success++;
|
||||||
|
|
|
@ -258,23 +258,11 @@ namespace nla {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void monomial_bounds::unit_propagate() {
|
void monomial_bounds::unit_propagate() {
|
||||||
for (auto const& m : c().m_emons)
|
for (auto const& m : c().m_emons)
|
||||||
unit_propagate(m);
|
unit_propagate(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
void monomial_bounds::check_for_conflict() {
|
|
||||||
if (c().lra.crossed_bounds_deps() != nullptr) {
|
|
||||||
new_lemma lemma(c(), "fixed-values");
|
|
||||||
lp::explanation ex;
|
|
||||||
c().lra.fill_explanation_from_crossed_bounds_column(ex);
|
|
||||||
lemma &= ex;
|
|
||||||
c().lra.crossed_bounds_deps() = nullptr;
|
|
||||||
c().lra.crossed_bounds_column() = null_lpvar;
|
|
||||||
c().lra.set_status(lp::lp_status::OPTIMAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void monomial_bounds::unit_propagate(monic const& m) {
|
void monomial_bounds::unit_propagate(monic const& m) {
|
||||||
m_propagated.reserve(m.var() + 1, false);
|
m_propagated.reserve(m.var() + 1, false);
|
||||||
if (m_propagated[m.var()])
|
if (m_propagated[m.var()])
|
||||||
|
@ -284,80 +272,37 @@ namespace nla {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
c().trail().push(set_bitvector_trail(m_propagated, m.var()));
|
c().trail().push(set_bitvector_trail(m_propagated, m.var()));
|
||||||
lpvar zero_fixed = null_lpvar, non_fixed = null_lpvar;
|
|
||||||
// find a zero fixed variable and a non-fixed variable
|
rational k = fixed_var_product(m);
|
||||||
for (lpvar v : m) {
|
|
||||||
if (c().var_is_fixed(v)) {
|
new_lemma lemma(c(), "fixed-values");
|
||||||
if (c().val(v).is_zero()) {
|
if (k == 0) {
|
||||||
zero_fixed = v;
|
for (auto v : m) {
|
||||||
|
if (c().var_is_fixed(v) && c().val(v).is_zero()) {
|
||||||
|
lemma.explain_fixed(v);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
lemma += ineq(m.var(), lp::lconstraint_kind::EQ, 0);
|
||||||
non_fixed = v;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
if (zero_fixed != null_lpvar) {
|
for (auto v : m)
|
||||||
// the m.var() has to have a zero value
|
if (c().var_is_fixed(v))
|
||||||
u_dependency* d = this->dep.mk_join(c().lra.get_column_lower_bound_witness(zero_fixed),
|
lemma.explain_fixed(v);
|
||||||
c().lra.get_column_upper_bound_witness(zero_fixed));
|
|
||||||
c().lra.update_column_type_and_bound(m.var(), lp::lconstraint_kind::EQ, mpq(0), d);
|
lpvar w = non_fixed_var(m);
|
||||||
} else if (non_fixed != null_lpvar) {
|
if (w != null_lpvar) {
|
||||||
u_dependency* d = nullptr;
|
lp::lar_term term;
|
||||||
rational k(1);
|
term.add_var(m.var());
|
||||||
for (auto v : m)
|
term.add_monomial(-k, w);
|
||||||
if (v != non_fixed) {
|
lemma += ineq(term, lp::lconstraint_kind::EQ, 0);
|
||||||
d = this->dep.mk_join(d, c().lra.get_column_upper_bound_witness(v));
|
|
||||||
d = this->dep.mk_join(d, c().lra.get_column_lower_bound_witness(v));
|
|
||||||
k *= c().val(v);
|
|
||||||
}
|
|
||||||
SASSERT(k.is_pos() || k.is_neg());
|
|
||||||
// we have m = k* non_fixed: m.var() getting the bounds witnesses of non_fixed
|
|
||||||
if (k.is_pos()) {
|
|
||||||
d = c().lra.get_column_upper_bound_witness(non_fixed);
|
|
||||||
if (d) {
|
|
||||||
const auto& b = c().lra.get_column_value(non_fixed);
|
|
||||||
bool strict = b.y.is_neg();
|
|
||||||
c().lra.update_column_type_and_bound(m.var(), strict ? lp::lconstraint_kind::LT : lp::lconstraint_kind::LE, k * b.x, d);
|
|
||||||
}
|
|
||||||
d = c().lra.get_column_lower_bound_witness(non_fixed);
|
|
||||||
if (d) {
|
|
||||||
const auto& b = c().lra.get_column_value(non_fixed);
|
|
||||||
bool strict = b.y.is_pos();
|
|
||||||
c().lra.update_column_type_and_bound(m.var(), strict ? lp::lconstraint_kind::GT : lp::lconstraint_kind::GE, k * b.x, d);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
d = c().lra.get_column_upper_bound_witness(non_fixed);
|
lemma += ineq(m.var(), lp::lconstraint_kind::EQ, k);
|
||||||
if (d) {
|
|
||||||
const auto& b = c().lra.get_column_value(non_fixed);
|
|
||||||
bool strict = b.y.is_neg();
|
|
||||||
c().lra.update_column_type_and_bound(m.var(), strict ? lp::lconstraint_kind::GT : lp::lconstraint_kind::GE, k * b.x, d);
|
|
||||||
}
|
|
||||||
d = c().lra.get_column_lower_bound_witness(non_fixed);
|
|
||||||
if (d) {
|
|
||||||
const auto& b = c().lra.get_column_value(non_fixed);
|
|
||||||
bool strict = b.y.is_pos();
|
|
||||||
c().lra.update_column_type_and_bound(m.var(), strict ? lp::lconstraint_kind::LT : lp::lconstraint_kind::LE, k * b.x, d);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
SASSERT(non_fixed == null_lpvar && zero_fixed == null_lpvar);
|
|
||||||
rational k(1);
|
|
||||||
u_dependency* d = nullptr;
|
|
||||||
for (auto v : m) {
|
|
||||||
SASSERT(c().var_is_fixed(v));
|
|
||||||
d = this->dep.mk_join(d, c().lra.get_column_upper_bound_witness(v));
|
|
||||||
d = this->dep.mk_join(d, c().lra.get_column_lower_bound_witness(v));
|
|
||||||
k *= c().val(v);
|
|
||||||
}
|
|
||||||
SASSERT(k.is_pos() || k.is_neg());
|
|
||||||
// we have m = k: m.var() getting the bounds witnesses of all fixed variables
|
|
||||||
c().lra.update_column_type_and_bound(m.var(), lp::lconstraint_kind::EQ, k, d);
|
|
||||||
}
|
}
|
||||||
check_for_conflict();
|
|
||||||
SASSERT (c().lra.get_status() != lp::lp_status::INFEASIBLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool monomial_bounds::is_linear(monic const& m) {
|
bool monomial_bounds::is_linear(monic const& m) {
|
||||||
unsigned non_fixed = 0;
|
unsigned non_fixed = 0;
|
||||||
for (lpvar v : m) {
|
for (lpvar v : m) {
|
||||||
|
@ -379,6 +324,12 @@ namespace nla {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lpvar monomial_bounds::non_fixed_var(monic const& m) {
|
||||||
|
for (lpvar v : m)
|
||||||
|
if (!c().var_is_fixed(v))
|
||||||
|
return v;
|
||||||
|
return null_lpvar;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,10 +35,11 @@ namespace nla {
|
||||||
void unit_propagate(monic const& m);
|
void unit_propagate(monic const& m);
|
||||||
bool is_linear(monic const& m);
|
bool is_linear(monic const& m);
|
||||||
rational fixed_var_product(monic const& m);
|
rational fixed_var_product(monic const& m);
|
||||||
|
lpvar non_fixed_var(monic const& m);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
monomial_bounds(core* core);
|
monomial_bounds(core* core);
|
||||||
void propagate();
|
void propagate();
|
||||||
void unit_propagate();
|
void unit_propagate();
|
||||||
void check_for_conflict();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1818,18 +1818,14 @@ bool core::improve_bounds() {
|
||||||
}
|
}
|
||||||
return bounds_improved;
|
return bounds_improved;
|
||||||
}
|
}
|
||||||
// returns false if and only if makes lp_solver inconsistent
|
|
||||||
bool core::propagate(vector<lemma>& lemmas) {
|
void core::propagate(vector<lemma>& lemmas) {
|
||||||
// propagate linear monomials, those that have all, or all but one, variables fixed
|
// propagate linear monomials, those that have all, or all but one, variables fixed
|
||||||
lemmas.reset();
|
lemmas.reset();
|
||||||
m_lemma_vec = &lemmas;
|
m_lemma_vec = &lemmas;
|
||||||
|
|
||||||
m_monomial_bounds.unit_propagate();
|
m_monomial_bounds.unit_propagate();
|
||||||
if (lra.get_status() == lp::lp_status::INFEASIBLE) {
|
|
||||||
TRACE("nla_solver", tout << "propagation found infeasibility\n";);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -392,7 +392,7 @@ public:
|
||||||
|
|
||||||
bool no_lemmas_hold() const;
|
bool no_lemmas_hold() const;
|
||||||
|
|
||||||
bool propagate(vector<lemma>& lemmas);
|
void propagate(vector<lemma>& lemmas);
|
||||||
|
|
||||||
lbool test_check(vector<lemma>& l);
|
lbool test_check(vector<lemma>& l);
|
||||||
lpvar map_to_root(lpvar) const;
|
lpvar map_to_root(lpvar) const;
|
||||||
|
|
Loading…
Reference in a new issue