mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 12:08:18 +00:00
fixes to bv/dual-solver,
This commit is contained in:
parent
a4354c960c
commit
89ffb45c4f
|
@ -245,7 +245,7 @@ public:
|
||||||
bool is_unsigned(expr const * n, unsigned& u) const {
|
bool is_unsigned(expr const * n, unsigned& u) const {
|
||||||
rational val;
|
rational val;
|
||||||
bool is_int = true;
|
bool is_int = true;
|
||||||
return is_numeral(n, val, is_int) && is_int && val.is_unsigned(), u = val.get_unsigned(), true;
|
return is_numeral(n, val, is_int) && is_int && val.is_unsigned() && (u = val.get_unsigned(), true);
|
||||||
}
|
}
|
||||||
bool is_numeral(expr const * n, rational & val, bool & is_int) const;
|
bool is_numeral(expr const * n, rational & val, bool & is_int) const;
|
||||||
bool is_numeral(expr const * n, rational & val) const { bool is_int; return is_numeral(n, val, is_int); }
|
bool is_numeral(expr const * n, rational & val) const { bool is_int; return is_numeral(n, val, is_int); }
|
||||||
|
|
|
@ -95,7 +95,7 @@ unmerge(a,a')
|
||||||
- n1 is reinserted. It used to be a root.
|
- n1 is reinserted. It used to be a root.
|
||||||
|
|
||||||
|
|
||||||
--*/
|
*/
|
||||||
|
|
||||||
#include "ast/euf/euf_egraph.h"
|
#include "ast/euf/euf_egraph.h"
|
||||||
#include "ast/ast_pp.h"
|
#include "ast/ast_pp.h"
|
||||||
|
@ -317,11 +317,22 @@ namespace euf {
|
||||||
|
|
||||||
void egraph::set_merge_enabled(enode* n, bool enable_merge) {
|
void egraph::set_merge_enabled(enode* n, bool enable_merge) {
|
||||||
if (enable_merge != n->merge_enabled()) {
|
if (enable_merge != n->merge_enabled()) {
|
||||||
|
toggle_merge_enabled(n);
|
||||||
m_updates.push_back(update_record(n, update_record::toggle_merge()));
|
m_updates.push_back(update_record(n, update_record::toggle_merge()));
|
||||||
n->set_merge_enabled(enable_merge);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void egraph::toggle_merge_enabled(enode* n) {
|
||||||
|
bool enable_merge = !n->merge_enabled();
|
||||||
|
n->set_merge_enabled(enable_merge);
|
||||||
|
if (n->num_args() > 0) {
|
||||||
|
if (enable_merge)
|
||||||
|
insert_table(n);
|
||||||
|
else
|
||||||
|
m_table.erase(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void egraph::set_value(enode* n, lbool value) {
|
void egraph::set_value(enode* n, lbool value) {
|
||||||
force_push();
|
force_push();
|
||||||
TRACE("euf", tout << bpp(n) << "\n";);
|
TRACE("euf", tout << bpp(n) << "\n";);
|
||||||
|
@ -362,7 +373,7 @@ namespace euf {
|
||||||
undo_node();
|
undo_node();
|
||||||
break;
|
break;
|
||||||
case update_record::tag_t::is_toggle_merge:
|
case update_record::tag_t::is_toggle_merge:
|
||||||
p.r1->set_merge_enabled(!p.r1->merge_enabled());
|
toggle_merge_enabled(p.r1);
|
||||||
break;
|
break;
|
||||||
case update_record::tag_t::is_set_parent:
|
case update_record::tag_t::is_set_parent:
|
||||||
undo_eq(p.r1, p.n1, p.r2_num_parents);
|
undo_eq(p.r1, p.n1, p.r2_num_parents);
|
||||||
|
@ -520,6 +531,12 @@ namespace euf {
|
||||||
for (enode* c : enode_class(r1))
|
for (enode* c : enode_class(r1))
|
||||||
c->m_root = r1;
|
c->m_root = r1;
|
||||||
|
|
||||||
|
for (enode* p : enode_parents(r1))
|
||||||
|
if (p->merge_enabled() && !p->is_cgr() && !p->m_cg) {
|
||||||
|
std::cout << bpp(p) << "\n";
|
||||||
|
SASSERT(false);
|
||||||
|
}
|
||||||
|
|
||||||
for (enode* p : enode_parents(r1))
|
for (enode* p : enode_parents(r1))
|
||||||
if (p->merge_enabled() && (p->is_cgr() || !p->congruent(p->m_cg)))
|
if (p->merge_enabled() && (p->is_cgr() || !p->congruent(p->m_cg)))
|
||||||
insert_table(p);
|
insert_table(p);
|
||||||
|
|
|
@ -196,6 +196,7 @@ namespace euf {
|
||||||
void push_to_lca(enode* a, enode* lca);
|
void push_to_lca(enode* a, enode* lca);
|
||||||
void push_congruence(enode* n1, enode* n2, bool commutative);
|
void push_congruence(enode* n1, enode* n2, bool commutative);
|
||||||
void push_todo(enode* n);
|
void push_todo(enode* n);
|
||||||
|
void toggle_merge_enabled(enode* n);
|
||||||
|
|
||||||
enode_bool_pair insert_table(enode* p);
|
enode_bool_pair insert_table(enode* p);
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,7 @@ namespace euf {
|
||||||
bool is_cgr() const { return this == m_cg; }
|
bool is_cgr() const { return this == m_cg; }
|
||||||
bool commutative() const { return m_commutative; }
|
bool commutative() const { return m_commutative; }
|
||||||
void mark_interpreted() { SASSERT(num_args() == 0); m_interpreted = true; }
|
void mark_interpreted() { SASSERT(num_args() == 0); m_interpreted = true; }
|
||||||
bool merge_enabled() { return m_merge_enabled; }
|
bool merge_enabled() const { return m_merge_enabled; }
|
||||||
|
|
||||||
enode* get_arg(unsigned i) const { SASSERT(i < num_args()); return m_args[i]; }
|
enode* get_arg(unsigned i) const { SASSERT(i < num_args()); return m_args[i]; }
|
||||||
unsigned hash() const { return m_expr->hash(); }
|
unsigned hash() const { return m_expr->hash(); }
|
||||||
|
|
|
@ -1192,10 +1192,10 @@ namespace lp {
|
||||||
|
|
||||||
impq lar_solver::get_tv_ivalue(tv const& t) const {
|
impq lar_solver::get_tv_ivalue(tv const& t) const {
|
||||||
if (t.is_var())
|
if (t.is_var())
|
||||||
return get_ivalue(t.column());
|
return get_column_value(t.column());
|
||||||
impq r;
|
impq r;
|
||||||
for (const auto& p : get_term(t))
|
for (const auto& p : get_term(t))
|
||||||
r += p.coeff() * get_ivalue(p.column());
|
r += p.coeff() * get_column_value(p.column());
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1317,9 +1317,8 @@ namespace lp {
|
||||||
|
|
||||||
void lar_solver::mark_rows_for_bound_prop(lpvar j) {
|
void lar_solver::mark_rows_for_bound_prop(lpvar j) {
|
||||||
auto& column = A_r().m_columns[j];
|
auto& column = A_r().m_columns[j];
|
||||||
for (auto const& r : column) {
|
for (auto const& r : column)
|
||||||
m_rows_with_changed_bounds.insert(r.var());
|
m_rows_with_changed_bounds.insert(r.var());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -638,7 +638,7 @@ public:
|
||||||
inline const static_matrix<mpq, impq> & A_r() const { return m_mpq_lar_core_solver.m_r_A; }
|
inline const static_matrix<mpq, impq> & A_r() const { return m_mpq_lar_core_solver.m_r_A; }
|
||||||
// columns
|
// columns
|
||||||
bool column_is_int(column_index const& j) const { return column_is_int((unsigned)j); }
|
bool column_is_int(column_index const& j) const { return column_is_int((unsigned)j); }
|
||||||
const impq& get_ivalue(column_index const& j) const { return get_column_value(j); }
|
// const impq& get_ivalue(column_index const& j) const { return get_column_value(j); }
|
||||||
const impq& get_column_value(column_index const& j) const { return m_mpq_lar_core_solver.m_r_x[j]; }
|
const impq& get_column_value(column_index const& j) const { return m_mpq_lar_core_solver.m_r_x[j]; }
|
||||||
inline
|
inline
|
||||||
var_index external_to_local(unsigned j) const {
|
var_index external_to_local(unsigned j) const {
|
||||||
|
|
|
@ -51,7 +51,6 @@ namespace arith {
|
||||||
|
|
||||||
solver::~solver() {
|
solver::~solver() {
|
||||||
del_bounds(0);
|
del_bounds(0);
|
||||||
std::for_each(m_internalize_states.begin(), m_internalize_states.end(), delete_proc<internalize_state>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::asserted(literal l) {
|
void solver::asserted(literal l) {
|
||||||
|
|
|
@ -111,7 +111,7 @@ namespace arith {
|
||||||
m_to_ensure_var.reset();
|
m_to_ensure_var.reset();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ptr_vector<internalize_state> m_internalize_states;
|
scoped_ptr_vector<internalize_state> m_internalize_states;
|
||||||
unsigned m_internalize_head{ 0 };
|
unsigned m_internalize_head{ 0 };
|
||||||
|
|
||||||
class scoped_internalize_state {
|
class scoped_internalize_state {
|
||||||
|
|
|
@ -223,6 +223,9 @@ namespace array {
|
||||||
args1.push_back(k);
|
args1.push_back(k);
|
||||||
args2.push_back(k);
|
args2.push_back(k);
|
||||||
}
|
}
|
||||||
|
std::cout << "e1: " << mk_pp(e1, m) << "\n";
|
||||||
|
std::cout << "e2: " << mk_pp(e2, m) << "\n";
|
||||||
|
std::cout << "funcs: " << funcs << "\n";
|
||||||
expr_ref sel1(a.mk_select(args1), m);
|
expr_ref sel1(a.mk_select(args1), m);
|
||||||
expr_ref sel2(a.mk_select(args2), m);
|
expr_ref sel2(a.mk_select(args2), m);
|
||||||
literal lit1 = eq_internalize(e1, e2);
|
literal lit1 = eq_internalize(e1, e2);
|
||||||
|
@ -521,13 +524,11 @@ namespace array {
|
||||||
for (unsigned i = 0; i < num_vars; i++) {
|
for (unsigned i = 0; i < num_vars; i++) {
|
||||||
euf::enode * n = var2enode(i);
|
euf::enode * n = var2enode(i);
|
||||||
|
|
||||||
if (!a.is_array(n->get_expr())) {
|
if (!is_array(n))
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
euf::enode * r = n->get_root();
|
euf::enode * r = n->get_root();
|
||||||
if (r->is_marked1()) {
|
if (r->is_marked1())
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
// arrays used as indices in other arrays have to be treated as shared issue #3532, #3529
|
// arrays used as indices in other arrays have to be treated as shared issue #3532, #3529
|
||||||
if (ctx.is_shared(r) || is_select_arg(r))
|
if (ctx.is_shared(r) || is_select_arg(r))
|
||||||
roots.push_back(r->get_th_var(get_id()));
|
roots.push_back(r->get_th_var(get_id()));
|
||||||
|
|
|
@ -86,6 +86,7 @@ namespace array {
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::internalize_ext(euf::enode* n) {
|
void solver::internalize_ext(euf::enode* n) {
|
||||||
|
SASSERT(is_array(n->get_arg(0)));
|
||||||
push_axiom(extensionality_axiom(n->get_arg(0), n->get_arg(1)));
|
push_axiom(extensionality_axiom(n->get_arg(0), n->get_arg(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,10 @@ namespace array {
|
||||||
|
|
||||||
void solver::new_diseq_eh(euf::th_eq const& eq) {
|
void solver::new_diseq_eh(euf::th_eq const& eq) {
|
||||||
force_push();
|
force_push();
|
||||||
push_axiom(extensionality_axiom(var2enode(eq.v1()), var2enode(eq.v2())));
|
euf::enode* n1 = var2enode(eq.v1());
|
||||||
|
euf::enode* n2 = var2enode(eq.v2());
|
||||||
|
if (is_array(n1))
|
||||||
|
push_axiom(extensionality_axiom(n1, n2));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool solver::unit_propagate() {
|
bool solver::unit_propagate() {
|
||||||
|
|
|
@ -158,6 +158,7 @@ namespace array {
|
||||||
void collect_shared_vars(sbuffer<theory_var>& roots);
|
void collect_shared_vars(sbuffer<theory_var>& roots);
|
||||||
bool add_interface_equalities();
|
bool add_interface_equalities();
|
||||||
bool is_select_arg(euf::enode* r);
|
bool is_select_arg(euf::enode* r);
|
||||||
|
bool is_array(euf::enode* n) const { return a.is_array(n->get_expr()); }
|
||||||
|
|
||||||
// solving
|
// solving
|
||||||
void add_parent_select(theory_var v_child, euf::enode* select);
|
void add_parent_select(theory_var v_child, euf::enode* select);
|
||||||
|
|
|
@ -176,10 +176,10 @@ namespace bv {
|
||||||
args[i] = arg_value;
|
args[i] = arg_value;
|
||||||
expr_ref r(m.mk_app(n->get_decl(), args), m);
|
expr_ref r(m.mk_app(n->get_decl(), args), m);
|
||||||
set_delay_internalize(r, internalize_mode::init_bits_only_i); // do not bit-blast this multiplier.
|
set_delay_internalize(r, internalize_mode::init_bits_only_i); // do not bit-blast this multiplier.
|
||||||
args[i] = n->get_arg(i);
|
args[i] = n->get_arg(i);
|
||||||
std::cout << "@" << s().scope_lvl() << "\n";
|
|
||||||
add_unit(eq_internalize(r, arg_value));
|
add_unit(eq_internalize(r, arg_value));
|
||||||
}
|
}
|
||||||
|
IF_VERBOSE(0, verbose_stream() << "delay internalize @" << s().scope_lvl() << "\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (bv.is_zero(mul_value)) {
|
if (bv.is_zero(mul_value)) {
|
||||||
|
|
|
@ -133,6 +133,9 @@ namespace bv {
|
||||||
euf::enode* n = expr2enode(e);
|
euf::enode* n = expr2enode(e);
|
||||||
app* a = to_app(e);
|
app* a = to_app(e);
|
||||||
|
|
||||||
|
if (visited(e))
|
||||||
|
return true;
|
||||||
|
|
||||||
SASSERT(!n || !n->is_attached_to(get_id()));
|
SASSERT(!n || !n->is_attached_to(get_id()));
|
||||||
bool suppress_args = !get_config().m_bv_reflect && !m.is_considered_uninterpreted(a->get_decl());
|
bool suppress_args = !get_config().m_bv_reflect && !m.is_considered_uninterpreted(a->get_decl());
|
||||||
if (!n)
|
if (!n)
|
||||||
|
@ -294,27 +297,12 @@ namespace bv {
|
||||||
atom* a = get_bv2a(bv);
|
atom* a = get_bv2a(bv);
|
||||||
if (a)
|
if (a)
|
||||||
return a;
|
return a;
|
||||||
a = new (get_region()) atom();
|
a = new (get_region()) atom(bv);
|
||||||
insert_bv2a(bv, a);
|
insert_bv2a(bv, a);
|
||||||
ctx.push(mk_atom_trail(bv, *this));
|
ctx.push(mk_atom_trail(bv, *this));
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
solver::eq_atom* solver::mk_eq_atom(sat::bool_var bv) {
|
|
||||||
atom* a = get_bv2a(bv);
|
|
||||||
if (a)
|
|
||||||
return a->is_eq() ? &a->to_eq() : nullptr;
|
|
||||||
else {
|
|
||||||
eq_atom* b = new (get_region()) eq_atom();
|
|
||||||
insert_bv2a(bv, b);
|
|
||||||
ctx.push(mk_atom_trail(bv, *this));
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void solver::set_bit_eh(theory_var v, literal l, unsigned idx) {
|
void solver::set_bit_eh(theory_var v, literal l, unsigned idx) {
|
||||||
SASSERT(m_bits[v][idx] == l);
|
SASSERT(m_bits[v][idx] == l);
|
||||||
if (s().value(l) != l_undef && s().lvl(l) == 0)
|
if (s().value(l) != l_undef && s().lvl(l) == 0)
|
||||||
|
@ -323,8 +311,7 @@ namespace bv {
|
||||||
atom* b = mk_atom(l.var());
|
atom* b = mk_atom(l.var());
|
||||||
if (b->m_occs)
|
if (b->m_occs)
|
||||||
find_new_diseq_axioms(*b, v, idx);
|
find_new_diseq_axioms(*b, v, idx);
|
||||||
if (!b->is_fresh())
|
ctx.push(add_var_pos_trail(b));
|
||||||
ctx.push(add_var_pos_trail(b));
|
|
||||||
b->m_occs = new (get_region()) var_pos_occ(v, idx, b->m_occs);
|
b->m_occs = new (get_region()) var_pos_occ(v, idx, b->m_occs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -586,7 +573,7 @@ namespace bv {
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::add_def(sat::literal def, sat::literal l) {
|
void solver::add_def(sat::literal def, sat::literal l) {
|
||||||
atom* a = new (get_region()) atom();
|
atom* a = new (get_region()) atom(l.var());
|
||||||
a->m_var = l;
|
a->m_var = l;
|
||||||
a->m_def = def;
|
a->m_def = def;
|
||||||
insert_bv2a(l.var(), a);
|
insert_bv2a(l.var(), a);
|
||||||
|
@ -648,7 +635,7 @@ namespace bv {
|
||||||
m_bits[v_arg][idx] = lit;
|
m_bits[v_arg][idx] = lit;
|
||||||
TRACE("bv", tout << "add-bit: " << lit << " " << literal2expr(lit) << "\n";);
|
TRACE("bv", tout << "add-bit: " << lit << " " << literal2expr(lit) << "\n";);
|
||||||
if (arg_sz > 1) {
|
if (arg_sz > 1) {
|
||||||
atom* a = new (get_region()) atom();
|
atom* a = new (get_region()) atom(lit.var());
|
||||||
a->m_occs = new (get_region()) var_pos_occ(v_arg, idx);
|
a->m_occs = new (get_region()) var_pos_occ(v_arg, idx);
|
||||||
insert_bv2a(lit.var(), a);
|
insert_bv2a(lit.var(), a);
|
||||||
ctx.push(mk_atom_trail(lit.var(), *this));
|
ctx.push(mk_atom_trail(lit.var(), *this));
|
||||||
|
@ -713,20 +700,12 @@ namespace bv {
|
||||||
|
|
||||||
void solver::eq_internalized(sat::bool_var b1, sat::bool_var b2, unsigned idx, theory_var v1, theory_var v2, literal lit, euf::enode* n) {
|
void solver::eq_internalized(sat::bool_var b1, sat::bool_var b2, unsigned idx, theory_var v1, theory_var v2, literal lit, euf::enode* n) {
|
||||||
atom* a = mk_atom(b1);
|
atom* a = mk_atom(b1);
|
||||||
// eq_atom* b = mk_eq_atom(lit.var());
|
|
||||||
if (a) {
|
if (a) {
|
||||||
if (!a->is_fresh())
|
ctx.push(add_eq_occurs_trail(a));
|
||||||
ctx.push(add_eq_occurs_trail(a));
|
|
||||||
auto* next = a->m_eqs;
|
auto* next = a->m_eqs;
|
||||||
a->m_eqs = new (get_region()) eq_occurs(b1, b2, idx, v1, v2, lit, n, next);
|
a->m_eqs = new (get_region()) eq_occurs(b1, b2, idx, v1, v2, lit, n, next);
|
||||||
if (next)
|
if (next)
|
||||||
next->m_prev = a->m_eqs;
|
next->m_prev = a->m_eqs;
|
||||||
#if 0
|
|
||||||
if (b) {
|
|
||||||
b->m_eqs.push_back(std::make_pair(a, a->m_eqs));
|
|
||||||
ctx.push(push_back_vector<euf::solver, svector<std::pair<bit_atom*,eq_occurs*>>>(b->m_eqs));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,6 @@ namespace bv {
|
||||||
bit_occs_trail(solver& s, atom& a): a(a), m_occs(a.m_occs) {}
|
bit_occs_trail(solver& s, atom& a): a(a), m_occs(a.m_occs) {}
|
||||||
|
|
||||||
virtual void undo(euf::solver& euf) {
|
virtual void undo(euf::solver& euf) {
|
||||||
IF_VERBOSE(1, verbose_stream() << "add back occurrences " << & a << "\n");
|
|
||||||
a.m_occs = m_occs;
|
a.m_occs = m_occs;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -400,20 +399,10 @@ namespace bv {
|
||||||
for (; m_prop_queue_head < m_prop_queue.size() && !s().inconsistent(); ++m_prop_queue_head) {
|
for (; m_prop_queue_head < m_prop_queue.size() && !s().inconsistent(); ++m_prop_queue_head) {
|
||||||
auto const p = m_prop_queue[m_prop_queue_head];
|
auto const p = m_prop_queue[m_prop_queue_head];
|
||||||
if (p.m_atom) {
|
if (p.m_atom) {
|
||||||
unsigned num_atoms = 0, num_eqs = 0, num_assigned = 0, num_eq_assigned = 0, num_lit_assigned = 0;
|
for (auto vp : *p.m_atom)
|
||||||
for (auto vp : *p.m_atom) {
|
propagate_bits(vp);
|
||||||
if (propagate_bits(vp))
|
for (auto const& eq : p.m_atom->eqs())
|
||||||
++num_assigned;
|
propagate_eq_occurs(eq);
|
||||||
++num_atoms;
|
|
||||||
}
|
|
||||||
for (auto const& eq : p.m_atom->eqs()) {
|
|
||||||
++num_eqs;
|
|
||||||
if (s().value(eq.m_literal) != l_undef)
|
|
||||||
++num_lit_assigned;
|
|
||||||
if (propagate_eq_occurs(eq)) {
|
|
||||||
++num_eq_assigned;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
propagate_bits(p.m_vp);
|
propagate_bits(p.m_vp);
|
||||||
|
@ -669,7 +658,7 @@ namespace bv {
|
||||||
if (!a)
|
if (!a)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
atom* new_a = new (result->get_region()) atom();
|
atom* new_a = new (result->get_region()) atom(i);
|
||||||
m_bool_var2atom.setx(i, new_a, nullptr);
|
m_bool_var2atom.setx(i, new_a, nullptr);
|
||||||
for (auto vp : *a)
|
for (auto vp : *a)
|
||||||
new_a->m_occs = new (result->get_region()) var_pos_occ(vp.first, vp.second, new_a->m_occs);
|
new_a->m_occs = new (result->get_region()) var_pos_occ(vp.first, vp.second, new_a->m_occs);
|
||||||
|
@ -800,6 +789,7 @@ namespace bv {
|
||||||
find_wpos(v2);
|
find_wpos(v2);
|
||||||
bool_var cv = consequent.var();
|
bool_var cv = consequent.var();
|
||||||
atom* a = get_bv2a(cv);
|
atom* a = get_bv2a(cv);
|
||||||
|
force_push();
|
||||||
if (a)
|
if (a)
|
||||||
for (auto curr : *a)
|
for (auto curr : *a)
|
||||||
if (propagate_eqc || find(curr.first) != find(v2) || curr.second != idx)
|
if (propagate_eqc || find(curr.first) != find(v2) || curr.second != idx)
|
||||||
|
|
|
@ -126,7 +126,7 @@ namespace bv {
|
||||||
eq_occurs_it(eq_occurs* c) : m_first(c) {}
|
eq_occurs_it(eq_occurs* c) : m_first(c) {}
|
||||||
eq_occurs operator*() { return *m_first; }
|
eq_occurs operator*() { return *m_first; }
|
||||||
eq_occurs_it& operator++() { m_first = m_first->m_next; return *this; }
|
eq_occurs_it& operator++() { m_first = m_first->m_next; return *this; }
|
||||||
eq_occurs_it operator++(int) { eq_occurs_it tmp = *this; ++* this; return tmp; }
|
eq_occurs_it operator++(int) { eq_occurs_it tmp = *this; ++*this; return tmp; }
|
||||||
bool operator==(eq_occurs_it const& other) const { return m_first == other.m_first; }
|
bool operator==(eq_occurs_it const& other) const { return m_first == other.m_first; }
|
||||||
bool operator!=(eq_occurs_it const& other) const { return !(*this == other); }
|
bool operator!=(eq_occurs_it const& other) const { return !(*this == other); }
|
||||||
};
|
};
|
||||||
|
@ -157,16 +157,16 @@ namespace bv {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct atom {
|
struct atom {
|
||||||
|
bool_var m_bv;
|
||||||
eq_occurs* m_eqs;
|
eq_occurs* m_eqs;
|
||||||
var_pos_occ * m_occs;
|
var_pos_occ * m_occs;
|
||||||
svector<std::pair<atom*, eq_occurs*>> m_bit2occ;
|
svector<std::pair<atom*, eq_occurs*>> m_bit2occ;
|
||||||
literal m_var { sat::null_literal };
|
literal m_var { sat::null_literal };
|
||||||
literal m_def { sat::null_literal };
|
literal m_def { sat::null_literal };
|
||||||
atom() :m_eqs(nullptr), m_occs(nullptr) {}
|
atom(bool_var b) :m_bv(b), m_eqs(nullptr), m_occs(nullptr) {}
|
||||||
~atom() { m_bit2occ.clear(); }
|
~atom() { m_bit2occ.clear(); }
|
||||||
var_pos_it begin() const { return var_pos_it(m_occs); }
|
var_pos_it begin() const { return var_pos_it(m_occs); }
|
||||||
var_pos_it end() const { return var_pos_it(nullptr); }
|
var_pos_it end() const { return var_pos_it(nullptr); }
|
||||||
bool is_fresh() const { return !m_occs && !m_eqs; }
|
|
||||||
eqs_iterator eqs() const { return eqs_iterator(m_eqs); }
|
eqs_iterator eqs() const { return eqs_iterator(m_eqs); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ namespace euf {
|
||||||
sat::literal lit;
|
sat::literal lit;
|
||||||
if (!m.is_bool(e))
|
if (!m.is_bool(e))
|
||||||
drat_log_node(e);
|
drat_log_node(e);
|
||||||
else
|
else
|
||||||
lit = attach_lit(literal(si.add_bool_var(e), false), e);
|
lit = attach_lit(literal(si.add_bool_var(e), false), e);
|
||||||
|
|
||||||
if (!m.is_bool(e) && m.get_sort(e)->get_family_id() != null_family_id) {
|
if (!m.is_bool(e) && m.get_sort(e)->get_family_id() != null_family_id) {
|
||||||
|
@ -153,6 +153,8 @@ namespace euf {
|
||||||
m_egraph.set_bool_var(n, v);
|
m_egraph.set_bool_var(n, v);
|
||||||
if (m.is_eq(e) || m.is_or(e) || m.is_and(e) || m.is_not(e))
|
if (m.is_eq(e) || m.is_or(e) || m.is_and(e) || m.is_not(e))
|
||||||
m_egraph.set_merge_enabled(n, false);
|
m_egraph.set_merge_enabled(n, false);
|
||||||
|
if (!si.is_bool_op(e))
|
||||||
|
track_relevancy(lit.var());
|
||||||
return lit;
|
return lit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,19 +90,42 @@ namespace sat {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dual_solver::operator()(solver const& s) {
|
bool dual_solver::operator()(solver const& s) {
|
||||||
|
m_core.reset();
|
||||||
|
m_core.append(m_units);
|
||||||
|
if (m_roots.empty())
|
||||||
|
return true;
|
||||||
m_solver.user_push();
|
m_solver.user_push();
|
||||||
m_solver.add_clause(m_roots.size(), m_roots.c_ptr(), status::input());
|
m_solver.add_clause(m_roots.size(), m_roots.c_ptr(), status::input());
|
||||||
m_lits.reset();
|
m_lits.reset();
|
||||||
for (bool_var v : m_tracked_vars)
|
for (bool_var v : m_tracked_vars)
|
||||||
m_lits.push_back(literal(v, l_false == s.value(m_var2ext[v])));
|
m_lits.push_back(literal(v, l_false == s.value(m_var2ext[v])));
|
||||||
lbool is_sat = m_solver.check(m_lits.size(), m_lits.c_ptr());
|
lbool is_sat = m_solver.check(m_lits.size(), m_lits.c_ptr());
|
||||||
m_core.reset();
|
|
||||||
m_core.append(m_units);
|
|
||||||
if (is_sat == l_false)
|
if (is_sat == l_false)
|
||||||
for (literal lit : m_solver.get_core())
|
for (literal lit : m_solver.get_core())
|
||||||
m_core.push_back(lit2ext(lit));
|
m_core.push_back(lit2ext(lit));
|
||||||
TRACE("euf", m_solver.display(tout << "is-sat: " << is_sat << " core: " << m_core << "\n"););
|
if (is_sat == l_true) {
|
||||||
|
IF_VERBOSE(0, display(s, verbose_stream()));
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
TRACE("dual", m_solver.display(tout << "is-sat: " << is_sat << " core: " << m_core << "\n"););
|
||||||
m_solver.user_pop(1);
|
m_solver.user_pop(1);
|
||||||
return is_sat == l_false;
|
return is_sat == l_false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::ostream& dual_solver::display(solver const& s, std::ostream& out) const {
|
||||||
|
for (auto r : m_roots)
|
||||||
|
out << r << " " << m_solver.value(r) << "\n";
|
||||||
|
for (unsigned v = 0; v < m_solver.num_vars(); ++v) {
|
||||||
|
bool_var w = m_var2ext.get(v, null_bool_var);
|
||||||
|
if (w == null_bool_var)
|
||||||
|
continue;
|
||||||
|
lbool v1 = m_solver.value(v);
|
||||||
|
lbool v2 = s.value(w);
|
||||||
|
if (v1 == v2)
|
||||||
|
continue;
|
||||||
|
out << w << " " << v1 << " " << v2 << "\n";
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,9 @@ namespace sat {
|
||||||
bool_var var2ext(bool_var v);
|
bool_var var2ext(bool_var v);
|
||||||
literal ext2lit(literal lit);
|
literal ext2lit(literal lit);
|
||||||
literal lit2ext(literal lit);
|
literal lit2ext(literal lit);
|
||||||
|
|
||||||
|
std::ostream& display(solver const& s, std::ostream& out) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
dual_solver(reslimit& l);
|
dual_solver(reslimit& l);
|
||||||
void push();
|
void push();
|
||||||
|
|
Loading…
Reference in a new issue