mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 20:18:18 +00:00
fix mixup between constraint indices and lpvar explanations fixes various newly reported unsoundness bugs
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
9c972521c4
commit
81b3c440ce
|
@ -251,8 +251,8 @@ public:
|
||||||
|
|
||||||
std::ostream& display(std::ostream& out) const {
|
std::ostream& display(std::ostream& out) const {
|
||||||
out << "number of constraints = " << m_constraints.size() << std::endl;
|
out << "number of constraints = " << m_constraints.size() << std::endl;
|
||||||
for (auto const& c : active()) {
|
for (auto const& c : indices()) {
|
||||||
display(out, c);
|
display(out << "(" << c << ") ", *m_constraints[c]);
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,7 +200,7 @@ void basics::add_fixed_zero_lemma(const monic& m, lpvar j) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void basics::negate_strict_sign(new_lemma& lemma, lpvar j) {
|
void basics::negate_strict_sign(new_lemma& lemma, lpvar j) {
|
||||||
TRACE("nla_solver_details", tout << pp_var(c(), j) << "\n";);
|
TRACE("nla_solver_details", tout << pp_var(c(), j) << " " << val(j).is_zero() << "\n";);
|
||||||
if (!val(j).is_zero()) {
|
if (!val(j).is_zero()) {
|
||||||
int sign = nla::rat_sign(val(j));
|
int sign = nla::rat_sign(val(j));
|
||||||
lemma |= ineq(j, (sign == 1? llc::LE : llc::GE), 0);
|
lemma |= ineq(j, (sign == 1? llc::LE : llc::GE), 0);
|
||||||
|
|
|
@ -1100,8 +1100,9 @@ new_lemma& new_lemma::operator|=(ineq const& ineq) {
|
||||||
}
|
}
|
||||||
|
|
||||||
new_lemma::~new_lemma() {
|
new_lemma::~new_lemma() {
|
||||||
|
static int i = 0;
|
||||||
// code for checking lemma can be added here
|
// code for checking lemma can be added here
|
||||||
TRACE("nla_solver", tout << name << "\n" << *this; );
|
TRACE("nla_solver", tout << name << " " << (++i) << "\n" << *this; );
|
||||||
}
|
}
|
||||||
|
|
||||||
lemma& new_lemma::current() const {
|
lemma& new_lemma::current() const {
|
||||||
|
@ -1143,8 +1144,8 @@ new_lemma& new_lemma::operator&=(lpvar j) {
|
||||||
|
|
||||||
new_lemma& new_lemma::explain_fixed(lpvar j) {
|
new_lemma& new_lemma::explain_fixed(lpvar j) {
|
||||||
SASSERT(c.var_is_fixed(j));
|
SASSERT(c.var_is_fixed(j));
|
||||||
*this &= c.m_lar_solver.get_column_upper_bound_witness(j);
|
explain_existing_lower_bound(j);
|
||||||
*this &= c.m_lar_solver.get_column_lower_bound_witness(j);
|
explain_existing_upper_bound(j);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1164,21 +1165,26 @@ new_lemma& new_lemma::explain_var_separated_from_zero(lpvar j) {
|
||||||
SASSERT(c.var_is_separated_from_zero(j));
|
SASSERT(c.var_is_separated_from_zero(j));
|
||||||
if (c.m_lar_solver.column_has_upper_bound(j) &&
|
if (c.m_lar_solver.column_has_upper_bound(j) &&
|
||||||
(c.m_lar_solver.get_upper_bound(j)< lp::zero_of_type<lp::impq>()))
|
(c.m_lar_solver.get_upper_bound(j)< lp::zero_of_type<lp::impq>()))
|
||||||
*this &= c.m_lar_solver.get_column_upper_bound_witness(j);
|
explain_existing_upper_bound(j);
|
||||||
else
|
else
|
||||||
*this &= c.m_lar_solver.get_column_lower_bound_witness(j);
|
explain_existing_lower_bound(j);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_lemma& new_lemma::explain_existing_lower_bound(lpvar j) {
|
new_lemma& new_lemma::explain_existing_lower_bound(lpvar j) {
|
||||||
SASSERT(c.has_lower_bound(j));
|
SASSERT(c.has_lower_bound(j));
|
||||||
*this &= c.m_lar_solver.get_column_lower_bound_witness(j);
|
lp::explanation ex;
|
||||||
|
ex.add(c.m_lar_solver.get_column_lower_bound_witness(j));
|
||||||
|
*this &= ex;
|
||||||
|
TRACE("nla_solver", tout << j << ": " << *this << "\n";);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_lemma& new_lemma::explain_existing_upper_bound(lpvar j) {
|
new_lemma& new_lemma::explain_existing_upper_bound(lpvar j) {
|
||||||
SASSERT(c.has_upper_bound(j));
|
SASSERT(c.has_upper_bound(j));
|
||||||
*this &= c.m_lar_solver.get_column_upper_bound_witness(j);
|
lp::explanation ex;
|
||||||
|
ex.add(c.m_lar_solver.get_column_upper_bound_witness(j));
|
||||||
|
*this &= ex;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1468,14 +1474,28 @@ lbool core::check(vector<lemma>& l_vec) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("nla_solver_details", print_terms(tout); tout << m_lar_solver.constraints(););
|
||||||
if (!done())
|
if (!done())
|
||||||
incremental_linearization(true);
|
m_basics.basic_lemma(true);
|
||||||
|
|
||||||
if (!done() && m_lemma_vec->empty())
|
TRACE("nla_solver", tout << "passed constraint_derived and basic lemmas\n";);
|
||||||
incremental_linearization(false);
|
SASSERT(elists_are_consistent(true));
|
||||||
|
|
||||||
lbool ret = !m_lemma_vec->empty() && !lp_settings().get_cancel_flag() ? l_false : l_undef;
|
if (l_vec.empty() && !done())
|
||||||
TRACE("nla_solver", tout << "ret = " << ret << ", lemmas count = " << m_lemma_vec->size() << "\n";);
|
m_basics.basic_lemma(false);
|
||||||
|
|
||||||
|
if (l_vec.empty() && !done())
|
||||||
|
m_order.order_lemma();
|
||||||
|
|
||||||
|
if (l_vec.empty() && !done()) {
|
||||||
|
if (!done())
|
||||||
|
m_monotone.monotonicity_lemma();
|
||||||
|
if (!done())
|
||||||
|
m_tangents.tangent_lemma();
|
||||||
|
}
|
||||||
|
|
||||||
|
lbool ret = !l_vec.empty() && !lp_settings().get_cancel_flag() ? l_false : l_undef;
|
||||||
|
TRACE("nla_solver", tout << "ret = " << ret << ", lemmas count = " << l_vec.size() << "\n";);
|
||||||
IF_VERBOSE(2, if(ret == l_undef) {verbose_stream() << "Monomials\n"; print_monics(verbose_stream());});
|
IF_VERBOSE(2, if(ret == l_undef) {verbose_stream() << "Monomials\n"; print_monics(verbose_stream());});
|
||||||
CTRACE("nla_solver", ret == l_undef, tout << "Monomials\n"; print_monics(tout););
|
CTRACE("nla_solver", ret == l_undef, tout << "Monomials\n"; print_monics(tout););
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1840,15 +1860,10 @@ unsigned core::get_var_weight(lpvar j) const {
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool core::is_nl_var(lpvar j) const {
|
bool core::is_nl_var(lpvar j) const {
|
||||||
if (is_monic_var(j))
|
return is_monic_var(j) || m_emons.is_used_in_monic(j);
|
||||||
return true;
|
|
||||||
return m_emons.is_used_in_monic(j);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool core::influences_nl_var(lpvar j) const {
|
bool core::influences_nl_var(lpvar j) const {
|
||||||
if (lp::tv::is_term(j))
|
if (lp::tv::is_term(j))
|
||||||
j = lp::tv::unmask_term(j);
|
j = lp::tv::unmask_term(j);
|
||||||
|
|
|
@ -90,7 +90,6 @@ class new_lemma {
|
||||||
char const* name;
|
char const* name;
|
||||||
core& c;
|
core& c;
|
||||||
lemma& current() const;
|
lemma& current() const;
|
||||||
lp::explanation& expl() { return current().expl(); }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
new_lemma(core& c, char const* name);
|
new_lemma(core& c, char const* name);
|
||||||
|
@ -110,6 +109,8 @@ public:
|
||||||
new_lemma& explain_existing_upper_bound(lpvar j);
|
new_lemma& explain_existing_upper_bound(lpvar j);
|
||||||
new_lemma& explain_separation_from_zero(lpvar j);
|
new_lemma& explain_separation_from_zero(lpvar j);
|
||||||
|
|
||||||
|
lp::explanation& expl() { return current().expl(); }
|
||||||
|
|
||||||
unsigned num_ineqs() const { return current().ineqs().size(); }
|
unsigned num_ineqs() const { return current().ineqs().size(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue