3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 09:05:31 +00:00

Merge branch 'master' into polysat

This commit is contained in:
Jakob Rath 2023-07-10 09:45:55 +02:00
commit 59c3234fb8
196 changed files with 4705 additions and 4168 deletions

View file

@ -398,6 +398,7 @@ namespace smt {
bool qi_queue::final_check_eh() {
TRACE("qi_queue", display_delayed_instances_stats(tout); tout << "lazy threshold: " << m_params.m_qi_lazy_threshold
<< ", scope_level: " << m_context.get_scope_level() << "\n";);
if (m_params.m_qi_conservative_final_check) {
bool init = false;
float min_cost = 0.0;

View file

@ -3337,6 +3337,7 @@ namespace smt {
reset_assumptions();
m_literal2assumption.reset();
m_unsat_core.reset();
if (!asms.empty()) {
// We must give a chance to the theories to propagate before we create a new scope...
propagate();
@ -3346,6 +3347,7 @@ namespace smt {
return;
if (get_cancel_flag())
return;
del_inactive_lemmas();
push_scope();
vector<std::pair<expr*,expr_ref>> asm2proxy;
internalize_proxies(asms, asm2proxy);

View file

@ -267,6 +267,7 @@ namespace {
};
void get_unsat_core(expr_ref_vector & r) override {
unsigned sz = m_context.get_unsat_core_size();
for (unsigned i = 0; i < sz; i++) {
r.push_back(m_context.get_unsat_core_expr(i));

View file

@ -17,7 +17,7 @@ Revision History:
--*/
#pragma once
// clang-format off
#include "ast/ast_pp.h"
#include "ast/ast_ll_pp.h"
#include "ast/ast_smt2_pp.h"

View file

@ -16,6 +16,7 @@ Author:
Revision History:
--*/
// clang-format off
#pragma once
#include "util/numeral_buffer.h"

View file

@ -90,13 +90,11 @@ class theory_lra::imp {
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();
@ -123,7 +121,6 @@ class theory_lra::imp {
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); }
@ -345,18 +342,33 @@ class theory_lra::imp {
st.push(rhs, rational::minus_one());
linearize(st);
}
theory_var internalize_numeral(app* n, rational const& val) {
if (!ctx().e_internalized(n))
mk_enode(n);
theory_var v = mk_var(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;
}
void linearize(scoped_internalize_state& st) {
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;
while (index < terms.size()) {
SASSERT(index >= vars.size());
expr* n = terms[index].get();
expr* n = terms.get(index);
st.to_ensure_enode().push_back(n);
if (a.is_add(n)) {
for (expr* arg : *to_app(n)) {
@ -394,7 +406,9 @@ class theory_lra::imp {
++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)) {
@ -781,16 +795,9 @@ class theory_lra::imp {
}
bool is_unit_var(scoped_internalize_state& st) {
return st.offset().is_zero() && st.vars().size() == 1 && st.coeffs()[0].is_one();
return st.vars().size() == 1 && st.coeffs()[0].is_one();
}
bool is_one(scoped_internalize_state& st) {
return st.offset().is_one() && st.vars().empty();
}
bool is_zero(scoped_internalize_state& st) {
return st.offset().is_zero() && st.vars().empty();
}
theory_var internalize_def(app* term, scoped_internalize_state& st) {
TRACE("arith", tout << expr_ref(term, m) << "\n";);
@ -841,46 +848,29 @@ class theory_lra::imp {
theory_var v = mk_var(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";);
}
}
return v;
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;
}
@ -1017,12 +1007,16 @@ public:
}
void internalize_eq_eh(app * atom, bool_var) {
if (!ctx().get_fparams().m_arith_eager_eq_axioms)
return;
expr* lhs = nullptr, *rhs = nullptr;
VERIFY(m.is_eq(atom, lhs, rhs));
enode * n1 = get_enode(lhs);
enode * n2 = get_enode(rhs);
TRACE("arith_verbose", tout << mk_pp(atom, m) << " " << is_arith(n1) << " " << is_arith(n2) << "\n";);
if (is_arith(n1) && is_arith(n2) && n1 != n2)
if (is_arith(n1) && is_arith(n2) &&
n1->get_th_var(get_id()) != null_theory_var &&
n2->get_th_var(get_id()) != null_theory_var && n1 != n2)
m_arith_eq_adapter.mk_axioms(n1, n2);
}
@ -1665,10 +1659,7 @@ public:
unsigned old_idx = m_final_check_idx;
switch (is_sat) {
case l_true:
TRACE("arith", display(tout));
// if (lp().has_fixed_at_bound()) // explain and propagate.
TRACE("arith", display(tout));
#if 0
m_dist.reset();
m_dist.push(0, 1);
@ -3207,11 +3198,13 @@ public:
void fixed_var_eh(theory_var v, lp::tv t, lp::constraint_index ci1, lp::constraint_index ci2, rational const& bound) {
theory_var w = null_theory_var;
enode* x = get_enode(v);
if (bound.is_zero())
if (m_value2var.find(bound, w))
;
else if (bound.is_zero())
w = lp().local_to_external(get_zero(a.is_int(x->get_expr())));
else if (bound.is_one())
w = lp().local_to_external(get_one(a.is_int(x->get_expr())));
else if (!m_value2var.find(bound, w))
else
return;
enode* y = get_enode(w);
if (x->get_sort() != y->get_sort())

View file

@ -83,7 +83,7 @@ void theory_user_propagator::add_expr(expr* term, bool ensure_enode) {
}
void theory_user_propagator::propagate_cb(
bool theory_user_propagator::propagate_cb(
unsigned num_fixed, expr* const* fixed_ids,
unsigned num_eqs, expr* const* eq_lhs, expr* const* eq_rhs,
expr* conseq) {
@ -95,9 +95,10 @@ void theory_user_propagator::propagate_cb(
if (!ctx.get_manager().is_true(_conseq) && !ctx.get_manager().is_false(_conseq))
ctx.mark_as_relevant((expr*)_conseq);
if (ctx.lit_internalized(_conseq) && ctx.get_assignment(ctx.get_literal(_conseq)) == l_true)
return;
m_prop.push_back(prop_info(num_fixed, fixed_ids, num_eqs, eq_lhs, eq_rhs, _conseq));
if (ctx.lit_internalized(_conseq) && ctx.get_assignment(ctx.get_literal(_conseq)) == l_true)
return false;
m_prop.push_back(prop_info(num_fixed, fixed_ids, num_eqs, eq_lhs, eq_rhs, _conseq));
return true;
}
void theory_user_propagator::register_cb(expr* e) {
@ -386,7 +387,7 @@ bool theory_user_propagator::internalize_atom(app* atom, bool gate_ctx) {
return internalize_term(atom);
}
bool theory_user_propagator::internalize_term(app* term) {
bool theory_user_propagator::internalize_term(app* term) {
for (auto arg : *term)
ensure_enode(arg);
if (term->get_family_id() == get_id() && !ctx.e_internalized(term))

View file

@ -130,7 +130,7 @@ namespace smt {
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;