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-06-12 14:02:20 +02:00
commit 8bde66420a
36 changed files with 292 additions and 225 deletions

View file

@ -131,6 +131,8 @@ namespace smt {
// max_top_generation and min_top_generation are not available for computing inc_gen
set_values(q, nullptr, generation, 0, 0, cost);
float r = m_evaluator(m_new_gen_function, m_vals.size(), m_vals.data());
if (q->get_weight() > 0 || r > 0)
return static_cast<unsigned>(r);
return std::max(generation + 1, static_cast<unsigned>(r));
}

View file

@ -2918,7 +2918,9 @@ namespace smt {
bool context::has_split_candidate(bool_var& var, bool& is_pos) {
if (!m_user_propagator)
return false;
return m_user_propagator->get_case_split(var, is_pos);
if (!m_user_propagator->get_case_split(var, is_pos))
return false;
return get_assignment(var) == l_undef;
}
bool context::decide_user_interference(bool_var& var, bool& is_pos) {

View file

@ -635,7 +635,7 @@ namespace smt {
literal_vector lits;
const_cast<conflict_resolution&>(*m_conflict_resolution).justification2literals(j.get_justification(), lits);
out << "justification " << j.get_justification()->get_from_theory() << ": ";
// display_literals_smt2(out, lits);
display_literals_smt2(out, lits);
break;
}
default:

View file

@ -969,7 +969,6 @@ namespace smt {
}
model_value_proc * theory_array_base::mk_value(enode * n, model_generator & mg) {
SASSERT(ctx.is_relevant(n));
theory_var v = n->get_th_var(get_id());
SASSERT(v != null_theory_var);
sort * s = n->get_expr()->get_sort();

View file

@ -1889,21 +1889,14 @@ namespace smt {
return var_enode_pos(nullptr, UINT32_MAX);
}
bool_var theory_bv::get_first_unassigned(unsigned start_bit, enode* n) const {
bool_var theory_bv::get_bit(unsigned bit, enode* n) const {
theory_var v = n->get_th_var(get_family_id());
if (v == null_theory_var)
return null_bool_var;
auto& bits = m_bits[v];
unsigned sz = bits.size();
for (unsigned i = start_bit; i < sz; ++i) {
if (ctx.get_assignment(bits[i].var()) == l_undef)
return bits[i].var();
}
for (unsigned i = 0; i < start_bit; ++i) {
if (ctx.get_assignment(bits[i].var()) == l_undef)
return bits[i].var();
}
return null_bool_var;
if (bit >= bits.size())
return null_bool_var;
return bits[bit].var();
}
bool theory_bv::check_assignment(theory_var v) {

View file

@ -291,7 +291,7 @@ namespace smt {
bool is_fixed_propagated(theory_var v, expr_ref& val, literal_vector& explain) override;
var_enode_pos get_bv_with_theory(bool_var v, theory_id id) const;
bool_var get_first_unassigned(unsigned start_bit, enode* n) const;
bool_var get_bit(unsigned bit, enode* n) const;
bool check_assignment(theory_var v);
bool check_invariant();

View file

@ -888,9 +888,14 @@ namespace smt {
func_decl* memf, *nextf, *connectedf;
std::string member, next, connected_sym;
unsigned index = r.decl()->get_parameter(0).get_int();
member = "member" + std::to_string(index);
next = "next" + std::to_string(index);
connected_sym = "connected" + std::to_string(index);
{
sort* dom[2] = { s, listS };
recfun::promise_def mem = p.ensure_def(symbol("member"), 2, dom, m.mk_bool_sort(), true);
recfun::promise_def mem = p.ensure_def(symbol(member), 2, dom, m.mk_bool_sort(), true);
memf = mem.get_def()->get_decl();
var_ref xV(m.mk_var(1, s), m);
@ -913,7 +918,7 @@ namespace smt {
{
sort* dom[5] = { s, s, listS, listS, tup };
recfun::promise_def nxt = p.ensure_def(symbol("next"), 5, dom, tup, true);
recfun::promise_def nxt = p.ensure_def(symbol(next), 5, dom, tup, true);
nextf = nxt.get_def()->get_decl();
expr_ref next_body(m);
@ -934,7 +939,7 @@ namespace smt {
{
sort* dom[3] = { listS, s, listS };
recfun::promise_def connected = p.ensure_def(symbol("connected"), 3, dom, m.mk_bool_sort(), true);
recfun::promise_def connected = p.ensure_def(symbol(connected_sym), 3, dom, m.mk_bool_sort(), true);
connectedf = connected.get_def()->get_decl();
var_ref AV(m.mk_var(2, listS), m);
var_ref dstV(m.mk_var(1, s), m);

View file

@ -107,15 +107,18 @@ void theory_user_propagator::register_cb(expr* e) {
add_expr(e, true);
}
void theory_user_propagator::next_split_cb(expr* e, unsigned idx, lbool phase) {
bool theory_user_propagator::next_split_cb(expr* e, unsigned idx, lbool phase) {
if (e == nullptr) { // clear
m_next_split_expr = nullptr;
return;
m_next_split_var = null_bool_var;
return true;
}
ensure_enode(e);
m_next_split_expr = e;
m_next_split_idx = idx;
bool_var b = enode_to_bool(ctx.get_enode(e), idx);
if (b == null_bool_var || ctx.get_assignment(b) != l_undef)
return false;
m_next_split_var = b;
m_next_split_phase = phase;
return true;
}
theory * theory_user_propagator::mk_fresh(context * new_ctx) {
@ -174,18 +177,15 @@ void theory_user_propagator::new_fixed_eh(theory_var v, expr* value, unsigned nu
}
}
bool_var theory_user_propagator::enode_to_bool(enode* n, unsigned bit) {
bool_var theory_user_propagator::enode_to_bool(enode* n, unsigned idx) {
if (n->is_bool()) {
// expression is a boolean
bool_var new_var = ctx.enode2bool_var(n);
if (ctx.get_assignment(new_var) == l_undef)
return new_var;
return null_bool_var;
return ctx.enode2bool_var(n);
}
// expression is a bit-vector
bv_util bv(m);
auto th_bv = (theory_bv*)ctx.get_theory(bv.get_fid());
return th_bv->get_first_unassigned(bit, n);
return th_bv->get_bit(idx, n);
}
void theory_user_propagator::decide(bool_var& var, bool& is_pos) {
@ -225,7 +225,7 @@ void theory_user_propagator::decide(bool_var& var, bool& is_pos) {
if (v == null_theory_var) {
// it is not a registered boolean value but it is a bitvector
auto registered_bv = ((theory_bv*)th)->get_bv_with_theory(var, get_family_id());
auto registered_bv = ((theory_bv *) th)->get_bv_with_theory(var, get_family_id());
if (!registered_bv.first)
// there is no registered bv associated with the bit
return;
@ -236,47 +236,33 @@ void theory_user_propagator::decide(bool_var& var, bool& is_pos) {
// call the registered callback
unsigned new_bit = original_bit;
lbool phase = is_pos ? l_true : l_false;
expr* e = var2expr(v);
m_decide_eh(m_user_context, this, &e, &new_bit, &phase);
enode* new_enode = ctx.get_enode(e);
// check if the callback changed something
if (original_enode == new_enode && (new_enode->is_bool() || original_bit == new_bit)) {
if (phase != l_undef)
// it only affected the truth value
is_pos = phase == l_true;
expr *e = var2expr(v);
m_decide_eh(m_user_context, this, e, new_bit, is_pos);
bool_var new_var;
if (!get_case_split(new_var, is_pos) || new_var == var)
// The user did not interfere
return;
}
var = new_var;
// get unassigned variable from enode
var = enode_to_bool(new_enode, new_bit);
if (var == null_bool_var)
// selected variable is already assigned
// check if the new variable is unassigned
if (ctx.get_assignment(var) != l_undef)
throw default_exception("expression in \"decide\" is already assigned");
// in case the callback did not decide on a truth value -> let Z3 decide
is_pos = ctx.guess(var, phase);
}
bool theory_user_propagator::get_case_split(bool_var& var, bool& is_pos){
if (!m_next_split_expr)
bool theory_user_propagator::get_case_split(bool_var& var, bool& is_pos) {
if (m_next_split_var == null_bool_var)
return false;
enode* n = ctx.get_enode(m_next_split_expr);
var = enode_to_bool(n, m_next_split_idx);
if (var == null_bool_var)
return false;
var = m_next_split_var;
is_pos = ctx.guess(var, m_next_split_phase);
m_next_split_expr = nullptr;
m_next_split_var = null_bool_var;
m_next_split_phase = l_undef;
return true;
}
void theory_user_propagator::push_scope_eh() {
void theory_user_propagator::push_scope_eh() {
++m_num_scopes;
}
@ -421,9 +407,9 @@ bool theory_user_propagator::internalize_term(app* term) {
return true;
}
void theory_user_propagator::collect_statistics(::statistics & st) const {
void theory_user_propagator::collect_statistics(::statistics& st) const {
st.update("user-propagations", m_stats.m_num_propagations);
st.update("user-watched", get_num_vars());
st.update("user-watched", get_num_vars());
}

View file

@ -83,9 +83,8 @@ namespace smt {
expr_ref_vector m_to_add;
unsigned_vector m_to_add_lim;
unsigned m_to_add_qhead = 0;
expr* m_next_split_expr = nullptr;
unsigned m_next_split_idx;
lbool m_next_split_phase;
bool_var m_next_split_var = null_bool_var;
lbool m_next_split_phase = l_undef;
expr* var2expr(theory_var v) { return m_var2expr.get(v); }
theory_var expr2var(expr* e) { check_defined(e); return m_expr2var[e->get_id()]; }
@ -133,7 +132,7 @@ namespace smt {
void 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;
void next_split_cb(expr* e, unsigned idx, lbool phase) override;
bool next_split_cb(expr* e, unsigned idx, lbool phase) override;
void new_fixed_eh(theory_var v, expr* value, unsigned num_lits, literal const* jlits);
void decide(bool_var& var, bool& is_pos);