mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 20:18:18 +00:00
restore m_crossed* and create lemmas
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
41f59cb1ed
commit
288e66de59
|
@ -2361,8 +2361,6 @@ namespace lp {
|
||||||
// dep is the reason for the new bound
|
// dep is the reason for the new bound
|
||||||
|
|
||||||
void lar_solver::set_infeasible_column_and_witness(unsigned j, bool lower_bound, u_dependency* dep) {
|
void lar_solver::set_infeasible_column_and_witness(unsigned j, bool lower_bound, u_dependency* dep) {
|
||||||
bool was_feas = column_is_feasible(j);
|
|
||||||
bool in_heap = m_mpq_lar_core_solver.m_r_solver.inf_heap().contains(j);
|
|
||||||
SASSERT(m_crossed_bounds_deps == nullptr && m_crossed_bounds_deps == nullptr);
|
SASSERT(m_crossed_bounds_deps == nullptr && m_crossed_bounds_deps == nullptr);
|
||||||
set_status(lp_status::INFEASIBLE);
|
set_status(lp_status::INFEASIBLE);
|
||||||
m_crossed_bounds_column = j;
|
m_crossed_bounds_column = j;
|
||||||
|
|
|
@ -142,6 +142,13 @@ class lar_solver : public column_namer {
|
||||||
inline void clear_columns_with_changed_bounds() { m_columns_with_changed_bounds.reset(); }
|
inline void clear_columns_with_changed_bounds() { m_columns_with_changed_bounds.reset(); }
|
||||||
public:
|
public:
|
||||||
void insert_to_columns_with_changed_bounds(unsigned j);
|
void insert_to_columns_with_changed_bounds(unsigned j);
|
||||||
|
const u_dependency* crossed_bounds_deps() const { return m_crossed_bounds_deps;}
|
||||||
|
u_dependency*& crossed_bounds_deps() { return m_crossed_bounds_deps;}
|
||||||
|
|
||||||
|
lpvar crossed_bounds_column() const { return m_crossed_bounds_column; }
|
||||||
|
lpvar& crossed_bounds_column() { return m_crossed_bounds_column; }
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void update_column_type_and_bound_check_on_equal(unsigned j, const mpq& right_side, constraint_index ci, unsigned&);
|
void update_column_type_and_bound_check_on_equal(unsigned j, const mpq& right_side, constraint_index ci, unsigned&);
|
||||||
void update_column_type_and_bound(unsigned j, const mpq& right_side, constraint_index ci);
|
void update_column_type_and_bound(unsigned j, const mpq& right_side, constraint_index ci);
|
||||||
|
|
|
@ -258,32 +258,30 @@ namespace nla {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool monomial_bounds::unit_propagate() {
|
void monomial_bounds::unit_propagate() {
|
||||||
unsigned sz = 0;
|
for (auto const& m : c().m_emons)
|
||||||
vector<lpvar> monics_vars;
|
unit_propagate(m);
|
||||||
for (auto const& m : c().m_emons) {
|
|
||||||
monics_vars.push_back(m.var());
|
|
||||||
sz++;
|
|
||||||
}
|
}
|
||||||
unsigned l = this->random();
|
|
||||||
for (unsigned i = 0; i < sz; ++i) {
|
void monomial_bounds::check_for_conflict() {
|
||||||
lpvar v = monics_vars[(i + l) % sz];
|
if (c().lra.crossed_bounds_deps() != nullptr) {
|
||||||
if (!unit_propagate(c().m_emons[v])) {
|
new_lemma lemma(c(), "fixed-values");
|
||||||
return false;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
void monomial_bounds::unit_propagate(monic const& m) {
|
||||||
}
|
|
||||||
|
|
||||||
// returns false if and only if there is a conflict
|
|
||||||
bool 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()])
|
||||||
return true;
|
return;
|
||||||
|
|
||||||
if (!is_linear(m))
|
if (!is_linear(m))
|
||||||
return true;
|
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;
|
lpvar zero_fixed = null_lpvar, non_fixed = null_lpvar;
|
||||||
|
@ -304,7 +302,6 @@ namespace nla {
|
||||||
// the m.var() has to have a zero value
|
// the m.var() has to have a zero value
|
||||||
u_dependency* d = this->dep.mk_join(c().lra.get_column_lower_bound_witness(zero_fixed),
|
u_dependency* d = this->dep.mk_join(c().lra.get_column_lower_bound_witness(zero_fixed),
|
||||||
c().lra.get_column_upper_bound_witness(zero_fixed));
|
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);
|
c().lra.update_column_type_and_bound(m.var(), lp::lconstraint_kind::EQ, mpq(0), d);
|
||||||
} else if (non_fixed != null_lpvar) {
|
} else if (non_fixed != null_lpvar) {
|
||||||
u_dependency* d = nullptr;
|
u_dependency* d = nullptr;
|
||||||
|
@ -330,7 +327,6 @@ namespace nla {
|
||||||
bool strict = b.y.is_pos();
|
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);
|
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);
|
d = c().lra.get_column_upper_bound_witness(non_fixed);
|
||||||
if (d) {
|
if (d) {
|
||||||
|
@ -359,11 +355,8 @@ namespace nla {
|
||||||
// we have m = k: m.var() getting the bounds witnesses of all fixed variables
|
// 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);
|
c().lra.update_column_type_and_bound(m.var(), lp::lconstraint_kind::EQ, k, d);
|
||||||
}
|
}
|
||||||
if (c().lra.get_status() == lp::lp_status::INFEASIBLE) {
|
check_for_conflict();
|
||||||
TRACE("nla_solver", tout << "conflict in unit_propagate\n";);
|
SASSERT (c().lra.get_status() != lp::lp_status::INFEASIBLE);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
bool monomial_bounds::is_linear(monic const& m) {
|
bool monomial_bounds::is_linear(monic const& m) {
|
||||||
unsigned non_fixed = 0;
|
unsigned non_fixed = 0;
|
||||||
|
|
|
@ -32,12 +32,13 @@ namespace nla {
|
||||||
|
|
||||||
// monomial propagation
|
// monomial propagation
|
||||||
bool_vector m_propagated;
|
bool_vector m_propagated;
|
||||||
bool 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);
|
||||||
public:
|
public:
|
||||||
monomial_bounds(core* core);
|
monomial_bounds(core* core);
|
||||||
void propagate();
|
void propagate();
|
||||||
bool unit_propagate();
|
void unit_propagate();
|
||||||
|
void check_for_conflict();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue