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:
commit
8bde66420a
36 changed files with 292 additions and 225 deletions
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue