mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 20:18:18 +00:00
fix a bug in unit nl prop
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
adbee0cd3f
commit
180ab727e7
|
@ -305,8 +305,8 @@ namespace nla {
|
||||||
void monomial_bounds::unit_propagate(monic & m) {
|
void monomial_bounds::unit_propagate(monic & m) {
|
||||||
if (m.is_propagated())
|
if (m.is_propagated())
|
||||||
return;
|
return;
|
||||||
|
lpvar w, fixed_to_zero;
|
||||||
if (!is_linear(m)) {
|
if (!is_linear(m, w, fixed_to_zero)) {
|
||||||
#if UNIT_PROPAGATE_BOUNDS
|
#if UNIT_PROPAGATE_BOUNDS
|
||||||
propagate(m);
|
propagate(m);
|
||||||
#endif
|
#endif
|
||||||
|
@ -315,12 +315,16 @@ namespace nla {
|
||||||
|
|
||||||
c().emons().set_propagated(m);
|
c().emons().set_propagated(m);
|
||||||
|
|
||||||
rational k = fixed_var_product(m);
|
if (fixed_to_zero != null_lpvar) {
|
||||||
lpvar w = non_fixed_var(m);
|
propagate_fixed_to_zero(m, fixed_to_zero);
|
||||||
if (w == null_lpvar || k == 0)
|
}
|
||||||
|
else {
|
||||||
|
rational k = fixed_var_product(m, w);
|
||||||
|
if (w == null_lpvar)
|
||||||
propagate_fixed(m, k);
|
propagate_fixed(m, k);
|
||||||
else
|
else
|
||||||
propagate_nonfixed(m, k, w);
|
propagate_nonfixed(m, k, w);
|
||||||
|
}
|
||||||
++c().lra.settings().stats().m_nla_propagate_eq;
|
++c().lra.settings().stats().m_nla_propagate_eq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,12 +337,18 @@ namespace nla {
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void monomial_bounds::propagate_fixed_to_zero(monic const& m, lpvar fixed_to_zero) {
|
||||||
|
auto* dep = c().lra.get_bound_constraint_witnesses_for_column(fixed_to_zero);
|
||||||
|
TRACE("nla_solver", tout << "propagate fixed " << m << " = 0, fixed_to_zero = " << fixed_to_zero << "\n";);
|
||||||
|
c().lra.update_column_type_and_bound(m.var(), lp::lconstraint_kind::EQ, rational(0), dep);
|
||||||
|
|
||||||
|
// propagate fixed equality
|
||||||
|
auto exp = get_explanation(dep);
|
||||||
|
c().add_fixed_equality(c().lra.column_to_reported_index(m.var()), rational(0), exp);
|
||||||
|
}
|
||||||
|
|
||||||
void monomial_bounds::propagate_fixed(monic const& m, rational const& k) {
|
void monomial_bounds::propagate_fixed(monic const& m, rational const& k) {
|
||||||
auto* dep = explain_fixed(m, k);
|
auto* dep = explain_fixed(m, k);
|
||||||
if (!c().lra.is_base(m.var())) {
|
|
||||||
lp::impq val(k);
|
|
||||||
c().lra.set_value_for_nbasic_column(m.var(), val);
|
|
||||||
}
|
|
||||||
TRACE("nla_solver", tout << "propagate fixed " << m << " = " << k << "\n";);
|
TRACE("nla_solver", tout << "propagate fixed " << m << " = " << k << "\n";);
|
||||||
c().lra.update_column_type_and_bound(m.var(), lp::lconstraint_kind::EQ, k, dep);
|
c().lra.update_column_type_and_bound(m.var(), lp::lconstraint_kind::EQ, k, dep);
|
||||||
|
|
||||||
|
@ -385,25 +395,32 @@ namespace nla {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool monomial_bounds::is_linear(monic const& m) {
|
bool monomial_bounds::is_linear(monic const& m, lpvar& w, lpvar & fixed_to_zero) {
|
||||||
unsigned non_fixed = 0;
|
w = fixed_to_zero = null_lpvar;
|
||||||
for (lpvar v : m) {
|
for (lpvar v : m) {
|
||||||
if (!c().var_is_fixed(v))
|
if (!c().var_is_fixed(v)) {
|
||||||
++non_fixed;
|
if (w != null_lpvar)
|
||||||
else if (c().val(v).is_zero())
|
return false;
|
||||||
|
w = v;
|
||||||
|
}
|
||||||
|
else if (c().get_lower_bound(v).is_zero()) {
|
||||||
|
fixed_to_zero = v;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return non_fixed <= 1;
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
rational monomial_bounds::fixed_var_product(monic const& m) {
|
rational monomial_bounds::fixed_var_product(monic const& m, lpvar w) {
|
||||||
rational r(1);
|
rational r(1);
|
||||||
for (lpvar v : m) {
|
for (lpvar v : m) {
|
||||||
// we have to use the column bounds here, because the column value may be outside the bounds
|
// we have to use the column bounds here, because the column value may be outside the bounds
|
||||||
if (c().var_is_fixed(v))
|
if (v != w ){
|
||||||
|
SASSERT(c().var_is_fixed(v));
|
||||||
r *= c().lra.get_lower_bound(v).x;
|
r *= c().lra.get_lower_bound(v).x;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace nla {
|
||||||
bool propagate_value(dep_interval& range, lpvar v, unsigned power);
|
bool propagate_value(dep_interval& range, lpvar v, unsigned power);
|
||||||
void compute_product(unsigned start, monic const& m, scoped_dep_interval& i);
|
void compute_product(unsigned start, monic const& m, scoped_dep_interval& i);
|
||||||
bool propagate(monic const& m);
|
bool propagate(monic const& m);
|
||||||
|
void propagate_fixed_to_zero(monic const& m, lpvar fixed_to_zero);
|
||||||
void propagate_fixed(monic const& m, rational const& k);
|
void propagate_fixed(monic const& m, rational const& k);
|
||||||
void propagate_nonfixed(monic const& m, rational const& k, lpvar w);
|
void propagate_nonfixed(monic const& m, rational const& k, lpvar w);
|
||||||
u_dependency* explain_fixed(monic const& m, rational const& k);
|
u_dependency* explain_fixed(monic const& m, rational const& k);
|
||||||
|
@ -35,8 +36,8 @@ namespace nla {
|
||||||
|
|
||||||
// monomial propagation
|
// monomial propagation
|
||||||
void unit_propagate(monic & m);
|
void unit_propagate(monic & m);
|
||||||
bool is_linear(monic const& m);
|
bool is_linear(monic const& m, lpvar& w, lpvar & fixed_to_zero);
|
||||||
rational fixed_var_product(monic const& m);
|
rational fixed_var_product(monic const& m, lpvar w);
|
||||||
lpvar non_fixed_var(monic const& m);
|
lpvar non_fixed_var(monic const& m);
|
||||||
public:
|
public:
|
||||||
monomial_bounds(core* core);
|
monomial_bounds(core* core);
|
||||||
|
|
Loading…
Reference in a new issue