mirror of
https://github.com/Z3Prover/z3
synced 2025-10-30 11:12:28 +00:00
Merge branch 'master' into polysat
This commit is contained in:
commit
59c3234fb8
196 changed files with 4705 additions and 4168 deletions
|
|
@ -136,9 +136,22 @@ namespace arith {
|
|||
arith_proof_hint const* solver::explain_conflict(sat::literal_vector const& core, euf::enode_pair_vector const& eqs) {
|
||||
arith_proof_hint* hint = nullptr;
|
||||
if (ctx.use_drat()) {
|
||||
m_coeffs.reset();
|
||||
for (auto const& e : m_explanation) {
|
||||
if (inequality_source == m_constraint_sources[e.ci()])
|
||||
m_coeffs.push_back(e.coeff());
|
||||
}
|
||||
|
||||
m_arith_hint.set_type(ctx, hint_type::farkas_h);
|
||||
for (auto lit : core)
|
||||
m_arith_hint.add_lit(rational::one(), lit);
|
||||
if (m_coeffs.size() == core.size()) {
|
||||
unsigned i = 0;
|
||||
for (auto lit : core)
|
||||
m_arith_hint.add_lit(m_coeffs[i], lit), ++i;
|
||||
}
|
||||
else {
|
||||
for (auto lit : core)
|
||||
m_arith_hint.add_lit(rational::one(), lit);
|
||||
}
|
||||
for (auto const& [a,b] : eqs)
|
||||
m_arith_hint.add_eq(a, b);
|
||||
hint = m_arith_hint.mk(ctx);
|
||||
|
|
|
|||
|
|
@ -160,7 +160,6 @@ namespace arith {
|
|||
expr_ref_vector& terms = st.terms();
|
||||
svector<theory_var>& vars = st.vars();
|
||||
vector<rational>& coeffs = st.coeffs();
|
||||
rational& offset = st.offset();
|
||||
rational r;
|
||||
expr* n1, * n2;
|
||||
unsigned index = 0;
|
||||
|
|
@ -204,7 +203,9 @@ namespace arith {
|
|||
++index;
|
||||
}
|
||||
else if (a.is_numeral(n, r)) {
|
||||
offset += coeffs[index] * r;
|
||||
theory_var v = internalize_numeral(to_app(n), r);
|
||||
coeffs[vars.size()] = coeffs[index];
|
||||
vars.push_back(v);
|
||||
++index;
|
||||
}
|
||||
else if (a.is_uminus(n, n1)) {
|
||||
|
|
@ -457,6 +458,19 @@ namespace arith {
|
|||
return v;
|
||||
}
|
||||
|
||||
theory_var solver::internalize_numeral(app* n, rational const& val) {
|
||||
theory_var v = mk_evar(n);
|
||||
lpvar vi = get_lpvar(v);
|
||||
if (vi == UINT_MAX) {
|
||||
vi = lp().add_var(v, a.is_int(n));
|
||||
add_def_constraint_and_equality(vi, lp::GE, val);
|
||||
add_def_constraint_and_equality(vi, lp::LE, val);
|
||||
register_fixed_var(v, val);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
theory_var solver::internalize_mul(app* t) {
|
||||
SASSERT(a.is_mul(t));
|
||||
internalize_args(t, true);
|
||||
|
|
@ -484,57 +498,32 @@ namespace arith {
|
|||
theory_var v = mk_evar(term);
|
||||
TRACE("arith", tout << mk_bounded_pp(term, m) << " v" << v << "\n";);
|
||||
|
||||
if (is_unit_var(st) && v == st.vars()[0]) {
|
||||
if (is_unit_var(st) && v == st.vars()[0])
|
||||
return st.vars()[0];
|
||||
}
|
||||
else if (is_one(st) && a.is_numeral(term)) {
|
||||
return lp().local_to_external(get_one(a.is_int(term)));
|
||||
}
|
||||
else if (is_zero(st) && a.is_numeral(term)) {
|
||||
return lp().local_to_external(get_zero(a.is_int(term)));
|
||||
}
|
||||
else {
|
||||
init_left_side(st);
|
||||
lpvar vi = get_lpvar(v);
|
||||
if (vi == UINT_MAX) {
|
||||
if (m_left_side.empty()) {
|
||||
vi = lp().add_var(v, a.is_int(term));
|
||||
add_def_constraint_and_equality(vi, lp::GE, st.offset());
|
||||
add_def_constraint_and_equality(vi, lp::LE, st.offset());
|
||||
register_fixed_var(v, st.offset());
|
||||
return v;
|
||||
}
|
||||
if (!st.offset().is_zero()) {
|
||||
m_left_side.push_back(std::make_pair(st.offset(), get_one(a.is_int(term))));
|
||||
}
|
||||
if (m_left_side.empty()) {
|
||||
vi = lp().add_var(v, a.is_int(term));
|
||||
add_def_constraint_and_equality(vi, lp::GE, rational(0));
|
||||
add_def_constraint_and_equality(vi, lp::LE, rational(0));
|
||||
}
|
||||
else {
|
||||
vi = lp().add_term(m_left_side, v);
|
||||
SASSERT(lp::tv::is_term(vi));
|
||||
TRACE("arith_verbose",
|
||||
tout << "v" << v << " := " << mk_pp(term, m)
|
||||
<< " slack: " << vi << " scopes: " << m_scopes.size() << "\n";
|
||||
lp().print_term(lp().get_term(lp::tv::raw(vi)), tout) << "\n";);
|
||||
}
|
||||
|
||||
init_left_side(st);
|
||||
lpvar vi = get_lpvar(v);
|
||||
|
||||
if (vi == UINT_MAX) {
|
||||
if (m_left_side.empty()) {
|
||||
vi = lp().add_var(v, a.is_int(term));
|
||||
add_def_constraint_and_equality(vi, lp::GE, rational(0));
|
||||
add_def_constraint_and_equality(vi, lp::LE, rational(0));
|
||||
}
|
||||
else {
|
||||
vi = lp().add_term(m_left_side, v);
|
||||
SASSERT(lp::tv::is_term(vi));
|
||||
TRACE("arith_verbose",
|
||||
tout << "v" << v << " := " << mk_pp(term, m)
|
||||
<< " slack: " << vi << " scopes: " << m_scopes.size() << "\n";
|
||||
lp().print_term(lp().get_term(lp::tv::raw(vi)), tout) << "\n";);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
bool solver::is_unit_var(scoped_internalize_state& st) {
|
||||
return st.offset().is_zero() && st.vars().size() == 1 && st.coeffs()[0].is_one();
|
||||
}
|
||||
|
||||
bool solver::is_one(scoped_internalize_state& st) {
|
||||
return st.offset().is_one() && st.vars().empty();
|
||||
}
|
||||
|
||||
bool solver::is_zero(scoped_internalize_state& st) {
|
||||
return st.offset().is_zero() && st.vars().empty();
|
||||
return st.vars().size() == 1 && st.coeffs()[0].is_one();
|
||||
}
|
||||
|
||||
void solver::init_left_side(scoped_internalize_state& st) {
|
||||
|
|
|
|||
|
|
@ -145,13 +145,11 @@ namespace arith {
|
|||
expr_ref_vector m_terms;
|
||||
vector<rational> m_coeffs;
|
||||
svector<theory_var> m_vars;
|
||||
rational m_offset;
|
||||
ptr_vector<expr> m_to_ensure_enode, m_to_ensure_var;
|
||||
internalize_state(ast_manager& m) : m_terms(m) {}
|
||||
void reset() {
|
||||
m_terms.reset();
|
||||
m_coeffs.reset();
|
||||
m_offset.reset();
|
||||
m_vars.reset();
|
||||
m_to_ensure_enode.reset();
|
||||
m_to_ensure_var.reset();
|
||||
|
|
@ -178,7 +176,6 @@ namespace arith {
|
|||
expr_ref_vector& terms() { return m_st.m_terms; }
|
||||
vector<rational>& coeffs() { return m_st.m_coeffs; }
|
||||
svector<theory_var>& vars() { return m_st.m_vars; }
|
||||
rational& offset() { return m_st.m_offset; }
|
||||
ptr_vector<expr>& to_ensure_enode() { return m_st.m_to_ensure_enode; }
|
||||
ptr_vector<expr>& to_ensure_var() { return m_st.m_to_ensure_var; }
|
||||
void push(expr* e, rational c) { m_st.m_terms.push_back(e); m_st.m_coeffs.push_back(c); }
|
||||
|
|
@ -254,6 +251,7 @@ namespace arith {
|
|||
lp::explanation m_explanation;
|
||||
vector<nla::lemma> m_nla_lemma_vector;
|
||||
literal_vector m_core, m_core2;
|
||||
vector<rational> m_coeffs;
|
||||
svector<enode_pair> m_eqs;
|
||||
vector<parameter> m_params;
|
||||
nla::lemma m_lemma;
|
||||
|
|
@ -290,6 +288,7 @@ namespace arith {
|
|||
void ensure_arg_vars(app* t);
|
||||
theory_var internalize_power(app* t, app* n, unsigned p);
|
||||
theory_var internalize_mul(app* t);
|
||||
theory_var internalize_numeral(app* t, rational const& v);
|
||||
theory_var internalize_def(expr* term);
|
||||
theory_var internalize_def(expr* term, scoped_internalize_state& st);
|
||||
theory_var internalize_linearized_def(expr* term, scoped_internalize_state& st);
|
||||
|
|
|
|||
|
|
@ -43,15 +43,19 @@ namespace user_solver {
|
|||
m_prop.push_back(prop_info(explain, v, r));
|
||||
}
|
||||
|
||||
void solver::propagate_cb(
|
||||
unsigned num_fixed, expr* const* fixed_ids,
|
||||
unsigned num_eqs, expr* const* eq_lhs, expr* const* eq_rhs,
|
||||
expr* conseq) {
|
||||
bool solver::propagate_cb(
|
||||
unsigned num_fixed, expr* const* fixed_ids,
|
||||
unsigned num_eqs, expr* const* eq_lhs, expr* const* eq_rhs,
|
||||
expr* conseq) {
|
||||
auto* n = ctx.get_enode(conseq);
|
||||
if (n && s().value(ctx.enode2literal(n)) == l_true)
|
||||
return false;
|
||||
m_fixed_ids.reset();
|
||||
for (unsigned i = 0; i < num_fixed; ++i)
|
||||
m_fixed_ids.push_back(get_th_var(fixed_ids[i]));
|
||||
m_prop.push_back(prop_info(num_fixed, m_fixed_ids.data(), num_eqs, eq_lhs, eq_rhs, expr_ref(conseq, m)));
|
||||
DEBUG_CODE(validate_propagation(););
|
||||
return true;
|
||||
}
|
||||
|
||||
void solver::register_cb(expr* e) {
|
||||
|
|
@ -76,7 +80,7 @@ namespace user_solver {
|
|||
|
||||
sat::check_result solver::check() {
|
||||
if (!(bool)m_final_eh)
|
||||
return sat::check_result::CR_DONE;
|
||||
return sat::check_result::CR_DONE;
|
||||
unsigned sz = m_prop.size();
|
||||
m_final_eh(m_user_context, this);
|
||||
return sz == m_prop.size() ? sat::check_result::CR_DONE : sat::check_result::CR_CONTINUE;
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ namespace user_solver {
|
|||
|
||||
bool has_fixed() const { return (bool)m_fixed_eh; }
|
||||
|
||||
void propagate_cb(unsigned num_fixed, expr* const* fixed_ids, unsigned num_eqs, expr* const* lhs, expr* const* rhs, expr* conseq) override;
|
||||
bool propagate_cb(unsigned num_fixed, expr* const* fixed_ids, unsigned num_eqs, expr* const* lhs, expr* const* rhs, expr* conseq) override;
|
||||
void register_cb(expr* e) override;
|
||||
bool next_split_cb(expr* e, unsigned idx, lbool phase) override;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue