mirror of
https://github.com/Z3Prover/z3
synced 2025-07-02 19:08:47 +00:00
#6364 - remove option of redundant clauses from internalization
gc-ing definitions leads to unsoundness when they are not replayed. Instead of attempting to replay definitions theory internalization is irredundant by default. This is also the old solver behavior where TH_LEMMA is essentially never used, but is valid for top-level theory lemmas.
This commit is contained in:
parent
c8e1e180ea
commit
5c7eaec566
29 changed files with 133 additions and 147 deletions
|
@ -20,9 +20,8 @@ Author:
|
||||||
|
|
||||||
namespace arith {
|
namespace arith {
|
||||||
|
|
||||||
sat::literal solver::internalize(expr* e, bool sign, bool root, bool learned) {
|
sat::literal solver::internalize(expr* e, bool sign, bool root) {
|
||||||
init_internalize();
|
init_internalize();
|
||||||
flet<bool> _is_learned(m_is_redundant, learned);
|
|
||||||
internalize_atom(e);
|
internalize_atom(e);
|
||||||
literal lit = ctx.expr2literal(e);
|
literal lit = ctx.expr2literal(e);
|
||||||
if (sign)
|
if (sign)
|
||||||
|
@ -30,9 +29,8 @@ namespace arith {
|
||||||
return lit;
|
return lit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::internalize(expr* e, bool redundant) {
|
void solver::internalize(expr* e) {
|
||||||
init_internalize();
|
init_internalize();
|
||||||
flet<bool> _is_learned(m_is_redundant, redundant);
|
|
||||||
if (m.is_bool(e))
|
if (m.is_bool(e))
|
||||||
internalize_atom(e);
|
internalize_atom(e);
|
||||||
else
|
else
|
||||||
|
@ -247,7 +245,7 @@ namespace arith {
|
||||||
ctx.push(push_back_vector(m_idiv_terms));
|
ctx.push(push_back_vector(m_idiv_terms));
|
||||||
m_idiv_terms.push_back(n);
|
m_idiv_terms.push_back(n);
|
||||||
app_ref mod(a.mk_mod(n1, n2), m);
|
app_ref mod(a.mk_mod(n1, n2), m);
|
||||||
internalize(mod, m_is_redundant);
|
internalize(mod);
|
||||||
st.to_ensure_var().push_back(n1);
|
st.to_ensure_var().push_back(n1);
|
||||||
st.to_ensure_var().push_back(n2);
|
st.to_ensure_var().push_back(n2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -952,7 +952,6 @@ namespace arith {
|
||||||
sat::check_result solver::check() {
|
sat::check_result solver::check() {
|
||||||
force_push();
|
force_push();
|
||||||
m_model_is_initialized = false;
|
m_model_is_initialized = false;
|
||||||
flet<bool> _is_learned(m_is_redundant, true);
|
|
||||||
IF_VERBOSE(12, verbose_stream() << "final-check " << lp().get_status() << "\n");
|
IF_VERBOSE(12, verbose_stream() << "final-check " << lp().get_status() << "\n");
|
||||||
SASSERT(lp().ax_is_correct());
|
SASSERT(lp().ax_is_correct());
|
||||||
|
|
||||||
|
@ -1174,7 +1173,7 @@ namespace arith {
|
||||||
for (auto const& c : core)
|
for (auto const& c : core)
|
||||||
m_core2.push_back(~c);
|
m_core2.push_back(~c);
|
||||||
m_core2.push_back(lit);
|
m_core2.push_back(lit);
|
||||||
add_clause(m_core2, pma);
|
add_redundant(m_core2, pma);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto* jst = euf::th_explain::propagate(*this, core, eqs, lit, pma);
|
auto* jst = euf::th_explain::propagate(*this, core, eqs, lit, pma);
|
||||||
|
@ -1215,7 +1214,7 @@ namespace arith {
|
||||||
for (literal& c : m_core)
|
for (literal& c : m_core)
|
||||||
c.neg();
|
c.neg();
|
||||||
|
|
||||||
add_clause(m_core, explain(hint_type::farkas_h));
|
add_redundant(m_core, explain(hint_type::farkas_h));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool solver::is_infeasible() const {
|
bool solver::is_infeasible() const {
|
||||||
|
|
|
@ -504,8 +504,8 @@ namespace arith {
|
||||||
void finalize_model(model& mdl) override { DEBUG_CODE(dbg_finalize_model(mdl);); }
|
void finalize_model(model& mdl) override { DEBUG_CODE(dbg_finalize_model(mdl);); }
|
||||||
void add_value(euf::enode* n, model& mdl, expr_ref_vector& values) override;
|
void add_value(euf::enode* n, model& mdl, expr_ref_vector& values) override;
|
||||||
bool add_dep(euf::enode* n, top_sort<euf::enode>& dep) override;
|
bool add_dep(euf::enode* n, top_sort<euf::enode>& dep) override;
|
||||||
sat::literal internalize(expr* e, bool sign, bool root, bool learned) override;
|
sat::literal internalize(expr* e, bool sign, bool root) override;
|
||||||
void internalize(expr* e, bool redundant) override;
|
void internalize(expr* e) override;
|
||||||
void eq_internalized(euf::enode* n) override;
|
void eq_internalized(euf::enode* n) override;
|
||||||
void apply_sort_cnstr(euf::enode* n, sort* s) override {}
|
void apply_sort_cnstr(euf::enode* n, sort* s) override {}
|
||||||
bool is_shared(theory_var v) const override;
|
bool is_shared(theory_var v) const override;
|
||||||
|
|
|
@ -20,9 +20,9 @@ Author:
|
||||||
|
|
||||||
namespace array {
|
namespace array {
|
||||||
|
|
||||||
sat::literal solver::internalize(expr* e, bool sign, bool root, bool redundant) {
|
sat::literal solver::internalize(expr* e, bool sign, bool root) {
|
||||||
SASSERT(m.is_bool(e));
|
SASSERT(m.is_bool(e));
|
||||||
if (!visit_rec(m, e, sign, root, redundant)) {
|
if (!visit_rec(m, e, sign, root)) {
|
||||||
TRACE("array", tout << mk_pp(e, m) << "\n";);
|
TRACE("array", tout << mk_pp(e, m) << "\n";);
|
||||||
return sat::null_literal;
|
return sat::null_literal;
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,8 @@ namespace array {
|
||||||
return lit;
|
return lit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::internalize(expr* e, bool redundant) {
|
void solver::internalize(expr* e) {
|
||||||
visit_rec(m, e, false, false, redundant);
|
visit_rec(m, e, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
euf::theory_var solver::mk_var(euf::enode* n) {
|
euf::theory_var solver::mk_var(euf::enode* n) {
|
||||||
|
@ -66,7 +66,7 @@ namespace array {
|
||||||
if (visited(e))
|
if (visited(e))
|
||||||
return true;
|
return true;
|
||||||
if (!is_app(e) || to_app(e)->get_family_id() != get_id()) {
|
if (!is_app(e) || to_app(e)->get_family_id() != get_id()) {
|
||||||
ctx.internalize(e, m_is_redundant);
|
ctx.internalize(e);
|
||||||
euf::enode* n = expr2enode(e);
|
euf::enode* n = expr2enode(e);
|
||||||
ensure_var(n);
|
ensure_var(n);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -296,8 +296,8 @@ namespace array {
|
||||||
bool include_func_interp(func_decl* f) const override { return a.is_ext(f); }
|
bool include_func_interp(func_decl* f) const override { return a.is_ext(f); }
|
||||||
void add_value(euf::enode* n, model& mdl, expr_ref_vector& values) override;
|
void add_value(euf::enode* n, model& mdl, expr_ref_vector& values) override;
|
||||||
bool add_dep(euf::enode* n, top_sort<euf::enode>& dep) override;
|
bool add_dep(euf::enode* n, top_sort<euf::enode>& dep) override;
|
||||||
sat::literal internalize(expr* e, bool sign, bool root, bool learned) override;
|
sat::literal internalize(expr* e, bool sign, bool root) override;
|
||||||
void internalize(expr* e, bool redundant) override;
|
void internalize(expr* e) override;
|
||||||
euf::theory_var mk_var(euf::enode* n) override;
|
euf::theory_var mk_var(euf::enode* n) override;
|
||||||
void apply_sort_cnstr(euf::enode* n, sort* s) override;
|
void apply_sort_cnstr(euf::enode* n, sort* s) override;
|
||||||
bool is_shared(theory_var v) const override;
|
bool is_shared(theory_var v) const override;
|
||||||
|
|
|
@ -99,10 +99,10 @@ namespace bv {
|
||||||
get_var(n);
|
get_var(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
sat::literal solver::internalize(expr* e, bool sign, bool root, bool redundant) {
|
sat::literal solver::internalize(expr* e, bool sign, bool root) {
|
||||||
force_push();
|
force_push();
|
||||||
SASSERT(m.is_bool(e));
|
SASSERT(m.is_bool(e));
|
||||||
if (!visit_rec(m, e, sign, root, redundant))
|
if (!visit_rec(m, e, sign, root))
|
||||||
return sat::null_literal;
|
return sat::null_literal;
|
||||||
sat::literal lit = expr2literal(e);
|
sat::literal lit = expr2literal(e);
|
||||||
if (sign)
|
if (sign)
|
||||||
|
@ -110,14 +110,14 @@ namespace bv {
|
||||||
return lit;
|
return lit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::internalize(expr* e, bool redundant) {
|
void solver::internalize(expr* e) {
|
||||||
force_push();
|
force_push();
|
||||||
visit_rec(m, e, false, false, redundant);
|
visit_rec(m, e, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool solver::visit(expr* e) {
|
bool solver::visit(expr* e) {
|
||||||
if (!is_app(e) || to_app(e)->get_family_id() != get_id()) {
|
if (!is_app(e) || to_app(e)->get_family_id() != get_id()) {
|
||||||
ctx.internalize(e, m_is_redundant);
|
ctx.internalize(e);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
m_stack.push_back(sat::eframe(e));
|
m_stack.push_back(sat::eframe(e));
|
||||||
|
@ -246,7 +246,7 @@ namespace bv {
|
||||||
for (unsigned i = 0; i < bv_size; i++) {
|
for (unsigned i = 0; i < bv_size; i++) {
|
||||||
expr_ref b2b(bv.mk_bit2bool(e, i), m);
|
expr_ref b2b(bv.mk_bit2bool(e, i), m);
|
||||||
m_bits[v].push_back(sat::null_literal);
|
m_bits[v].push_back(sat::null_literal);
|
||||||
sat::literal lit = ctx.internalize(b2b, false, false, m_is_redundant);
|
sat::literal lit = ctx.internalize(b2b, false, false);
|
||||||
TRACE("bv", tout << "add-bit: " << lit << " " << literal2expr(lit) << "\n";);
|
TRACE("bv", tout << "add-bit: " << lit << " " << literal2expr(lit) << "\n";);
|
||||||
if (m_bits[v].back() == sat::null_literal)
|
if (m_bits[v].back() == sat::null_literal)
|
||||||
m_bits[v].back() = lit;
|
m_bits[v].back() = lit;
|
||||||
|
@ -344,7 +344,7 @@ namespace bv {
|
||||||
SASSERT(bits.size() == m_bits[v].size());
|
SASSERT(bits.size() == m_bits[v].size());
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for (expr* bit : bits) {
|
for (expr* bit : bits) {
|
||||||
sat::literal lit = ctx.internalize(bit, false, false, m_is_redundant);
|
sat::literal lit = ctx.internalize(bit, false, false);
|
||||||
TRACE("bv", tout << "set " << m_bits[v][i] << " == " << lit << "\n";);
|
TRACE("bv", tout << "set " << m_bits[v][i] << " == " << lit << "\n";);
|
||||||
add_clause(~lit, m_bits[v][i]);
|
add_clause(~lit, m_bits[v][i]);
|
||||||
add_clause(lit, ~m_bits[v][i]);
|
add_clause(lit, ~m_bits[v][i]);
|
||||||
|
@ -353,7 +353,7 @@ namespace bv {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (expr* bit : bits)
|
for (expr* bit : bits)
|
||||||
add_bit(v, ctx.internalize(bit, false, false, m_is_redundant));
|
add_bit(v, ctx.internalize(bit, false, false));
|
||||||
for (expr* bit : bits)
|
for (expr* bit : bits)
|
||||||
get_var(expr2enode(bit));
|
get_var(expr2enode(bit));
|
||||||
SASSERT(get_bv_size(n) == bits.size());
|
SASSERT(get_bv_size(n) == bits.size());
|
||||||
|
@ -371,7 +371,7 @@ namespace bv {
|
||||||
sat::literal solver::mk_true() {
|
sat::literal solver::mk_true() {
|
||||||
if (m_true == sat::null_literal) {
|
if (m_true == sat::null_literal) {
|
||||||
ctx.push(value_trail<sat::literal>(m_true));
|
ctx.push(value_trail<sat::literal>(m_true));
|
||||||
m_true = ctx.internalize(m.mk_true(), false, true, false);
|
m_true = ctx.internalize(m.mk_true(), false, true);
|
||||||
s().assign_unit(m_true);
|
s().assign_unit(m_true);
|
||||||
}
|
}
|
||||||
return m_true;
|
return m_true;
|
||||||
|
@ -493,7 +493,7 @@ namespace bv {
|
||||||
m_bb.mk_sle(arg1_bits.size(), arg1_bits.data(), arg2_bits.data(), le);
|
m_bb.mk_sle(arg1_bits.size(), arg1_bits.data(), arg2_bits.data(), le);
|
||||||
else
|
else
|
||||||
m_bb.mk_ule(arg1_bits.size(), arg1_bits.data(), arg2_bits.data(), le);
|
m_bb.mk_ule(arg1_bits.size(), arg1_bits.data(), arg2_bits.data(), le);
|
||||||
literal def = ctx.internalize(le, false, false, m_is_redundant);
|
literal def = ctx.internalize(le, false, false);
|
||||||
if (Negated)
|
if (Negated)
|
||||||
def.neg();
|
def.neg();
|
||||||
add_def(def, expr2literal(n));
|
add_def(def, expr2literal(n));
|
||||||
|
@ -598,7 +598,7 @@ namespace bv {
|
||||||
get_arg_bits(n, 1, arg2_bits);
|
get_arg_bits(n, 1, arg2_bits);
|
||||||
expr_ref out(m);
|
expr_ref out(m);
|
||||||
fn(arg1_bits.size(), arg1_bits.data(), arg2_bits.data(), out);
|
fn(arg1_bits.size(), arg1_bits.data(), arg2_bits.data(), out);
|
||||||
sat::literal def = ctx.internalize(out, false, false, m_is_redundant);
|
sat::literal def = ctx.internalize(out, false, false);
|
||||||
add_def(def, expr2literal(n));
|
add_def(def, expr2literal(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -753,12 +753,11 @@ namespace bv {
|
||||||
return;
|
return;
|
||||||
if (v1 > v2)
|
if (v1 > v2)
|
||||||
std::swap(v1, v2);
|
std::swap(v1, v2);
|
||||||
flet<bool> _red(m_is_redundant, true);
|
|
||||||
++m_stats.m_ackerman;
|
++m_stats.m_ackerman;
|
||||||
expr* o1 = var2expr(v1);
|
expr* o1 = var2expr(v1);
|
||||||
expr* o2 = var2expr(v2);
|
expr* o2 = var2expr(v2);
|
||||||
expr_ref oe = mk_var_eq(v1, v2);
|
expr_ref oe = mk_var_eq(v1, v2);
|
||||||
literal oeq = ctx.internalize(oe, false, false, m_is_redundant);
|
literal oeq = ctx.internalize(oe, false, false);
|
||||||
unsigned sz = m_bits[v1].size();
|
unsigned sz = m_bits[v1].size();
|
||||||
TRACE("bv", tout << "ackerman-eq: " << s().scope_lvl() << " " << oe << "\n";);
|
TRACE("bv", tout << "ackerman-eq: " << s().scope_lvl() << " " << oe << "\n";);
|
||||||
literal_vector eqs;
|
literal_vector eqs;
|
||||||
|
@ -772,6 +771,7 @@ namespace bv {
|
||||||
eqs.push_back(~eq);
|
eqs.push_back(~eq);
|
||||||
}
|
}
|
||||||
TRACE("bv", for (auto l : eqs) tout << mk_bounded_pp(literal2expr(l), m) << " "; tout << "\n";);
|
TRACE("bv", for (auto l : eqs) tout << mk_bounded_pp(literal2expr(l), m) << " "; tout << "\n";);
|
||||||
add_clause(eqs);
|
euf::th_proof_hint* ph = ctx.mk_smt_clause(name(), eqs.size(), eqs.data());
|
||||||
|
s().mk_clause(eqs, sat::status::th(true, m.get_basic_family_id(), ph));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,7 +168,7 @@ namespace bv {
|
||||||
TRACE("bv", tout << "found new diseq axiom\n" << pp(v1) << pp(v2););
|
TRACE("bv", tout << "found new diseq axiom\n" << pp(v1) << pp(v2););
|
||||||
m_stats.m_num_diseq_static++;
|
m_stats.m_num_diseq_static++;
|
||||||
expr_ref eq(m.mk_eq(var2expr(v1), var2expr(v2)), m);
|
expr_ref eq(m.mk_eq(var2expr(v1), var2expr(v2)), m);
|
||||||
add_unit(~ctx.internalize(eq, false, false, m_is_redundant));
|
add_unit(~ctx.internalize(eq, false, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& solver::display(std::ostream& out, theory_var v) const {
|
std::ostream& solver::display(std::ostream& out, theory_var v) const {
|
||||||
|
@ -464,7 +464,7 @@ namespace bv {
|
||||||
m_lit_head = m_lit_tail;
|
m_lit_head = m_lit_tail;
|
||||||
m_lit_tail = m_proof_literals.size();
|
m_lit_tail = m_proof_literals.size();
|
||||||
proof_hint* ph = new (get_region()) proof_hint(c.m_kind, m_proof_literals, m_lit_head, m_lit_tail, a1, a2, b1, b2);
|
proof_hint* ph = new (get_region()) proof_hint(c.m_kind, m_proof_literals, m_lit_head, m_lit_tail, a1, a2, b1, b2);
|
||||||
auto st = sat::status::th(m_is_redundant, m.get_basic_family_id(), ph);
|
auto st = sat::status::th(false, m.get_basic_family_id(), ph);
|
||||||
ctx.get_drat().add(lits, st);
|
ctx.get_drat().add(lits, st);
|
||||||
m_lit_head = m_lit_tail;
|
m_lit_head = m_lit_tail;
|
||||||
// TBD, a proper way would be to delete the lemma after use.
|
// TBD, a proper way would be to delete the lemma after use.
|
||||||
|
|
|
@ -385,8 +385,8 @@ namespace bv {
|
||||||
std::function<void(unsigned sz, literal const* c, unsigned const* coeffs, unsigned k)>& pb) override { return false; }
|
std::function<void(unsigned sz, literal const* c, unsigned const* coeffs, unsigned k)>& pb) override { return false; }
|
||||||
|
|
||||||
bool to_formulas(std::function<expr_ref(sat::literal)>& l2e, expr_ref_vector& fmls) override { return false; }
|
bool to_formulas(std::function<expr_ref(sat::literal)>& l2e, expr_ref_vector& fmls) override { return false; }
|
||||||
sat::literal internalize(expr* e, bool sign, bool root, bool learned) override;
|
sat::literal internalize(expr* e, bool sign, bool root) override;
|
||||||
void internalize(expr* e, bool redundant) override;
|
void internalize(expr* e) override;
|
||||||
void eq_internalized(euf::enode* n) override;
|
void eq_internalized(euf::enode* n) override;
|
||||||
euf::theory_var mk_var(euf::enode* n) override;
|
euf::theory_var mk_var(euf::enode* n) override;
|
||||||
void apply_sort_cnstr(euf::enode * n, sort * s) override;
|
void apply_sort_cnstr(euf::enode * n, sort * s) override;
|
||||||
|
|
|
@ -804,8 +804,8 @@ namespace dt {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sat::literal solver::internalize(expr* e, bool sign, bool root, bool redundant) {
|
sat::literal solver::internalize(expr* e, bool sign, bool root) {
|
||||||
if (!visit_rec(m, e, sign, root, redundant))
|
if (!visit_rec(m, e, sign, root))
|
||||||
return sat::null_literal;
|
return sat::null_literal;
|
||||||
auto lit = ctx.expr2literal(e);
|
auto lit = ctx.expr2literal(e);
|
||||||
if (sign)
|
if (sign)
|
||||||
|
@ -813,15 +813,15 @@ namespace dt {
|
||||||
return lit;
|
return lit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::internalize(expr* e, bool redundant) {
|
void solver::internalize(expr* e) {
|
||||||
visit_rec(m, e, false, false, redundant);
|
visit_rec(m, e, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool solver::visit(expr* e) {
|
bool solver::visit(expr* e) {
|
||||||
if (visited(e))
|
if (visited(e))
|
||||||
return true;
|
return true;
|
||||||
if (!is_app(e) || to_app(e)->get_family_id() != get_id()) {
|
if (!is_app(e) || to_app(e)->get_family_id() != get_id()) {
|
||||||
ctx.internalize(e, m_is_redundant);
|
ctx.internalize(e);
|
||||||
if (is_datatype(e))
|
if (is_datatype(e))
|
||||||
mk_var(expr2enode(e));
|
mk_var(expr2enode(e));
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -154,8 +154,8 @@ namespace dt {
|
||||||
void add_value(euf::enode* n, model& mdl, expr_ref_vector& values) override;
|
void add_value(euf::enode* n, model& mdl, expr_ref_vector& values) override;
|
||||||
bool add_dep(euf::enode* n, top_sort<euf::enode>& dep) override;
|
bool add_dep(euf::enode* n, top_sort<euf::enode>& dep) override;
|
||||||
bool include_func_interp(func_decl* f) const override;
|
bool include_func_interp(func_decl* f) const override;
|
||||||
sat::literal internalize(expr* e, bool sign, bool root, bool redundant) override;
|
sat::literal internalize(expr* e, bool sign, bool root) override;
|
||||||
void internalize(expr* e, bool redundant) override;
|
void internalize(expr* e) override;
|
||||||
euf::theory_var mk_var(euf::enode* n) override;
|
euf::theory_var mk_var(euf::enode* n) override;
|
||||||
void apply_sort_cnstr(euf::enode* n, sort* s) override;
|
void apply_sort_cnstr(euf::enode* n, sort* s) override;
|
||||||
bool is_shared(theory_var v) const override { return false; }
|
bool is_shared(theory_var v) const override { return false; }
|
||||||
|
|
|
@ -189,7 +189,6 @@ namespace euf {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ackerman::add_cc(expr* _a, expr* _b) {
|
void ackerman::add_cc(expr* _a, expr* _b) {
|
||||||
flet<bool> _is_redundant(ctx.m_is_redundant, true);
|
|
||||||
app* a = to_app(_a);
|
app* a = to_app(_a);
|
||||||
app* b = to_app(_b);
|
app* b = to_app(_b);
|
||||||
TRACE("ack", tout << mk_pp(a, m) << " " << mk_pp(b, m) << "\n";);
|
TRACE("ack", tout << mk_pp(a, m) << " " << mk_pp(b, m) << "\n";);
|
||||||
|
@ -213,7 +212,6 @@ namespace euf {
|
||||||
void ackerman::add_eq(expr* a, expr* b, expr* c) {
|
void ackerman::add_eq(expr* a, expr* b, expr* c) {
|
||||||
if (a == c || b == c)
|
if (a == c || b == c)
|
||||||
return;
|
return;
|
||||||
flet<bool> _is_redundant(ctx.m_is_redundant, true);
|
|
||||||
sat::literal lits[3];
|
sat::literal lits[3];
|
||||||
expr_ref eq1(ctx.mk_eq(a, c), m);
|
expr_ref eq1(ctx.mk_eq(a, c), m);
|
||||||
expr_ref eq2(ctx.mk_eq(b, c), m);
|
expr_ref eq2(ctx.mk_eq(b, c), m);
|
||||||
|
@ -223,7 +221,7 @@ namespace euf {
|
||||||
lits[1] = ~ctx.mk_literal(eq2);
|
lits[1] = ~ctx.mk_literal(eq2);
|
||||||
lits[2] = ctx.mk_literal(eq3);
|
lits[2] = ctx.mk_literal(eq3);
|
||||||
th_proof_hint* ph = ctx.mk_tc_proof_hint(lits);
|
th_proof_hint* ph = ctx.mk_tc_proof_hint(lits);
|
||||||
ctx.s().mk_clause(3, lits, sat::status::th(true, m.get_basic_family_id(), ph));
|
ctx.s().add_clause(3, lits, sat::status::th(true, m.get_basic_family_id(), ph));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,28 +34,28 @@ Notes:
|
||||||
|
|
||||||
namespace euf {
|
namespace euf {
|
||||||
|
|
||||||
void solver::internalize(expr* e, bool redundant) {
|
void solver::internalize(expr* e) {
|
||||||
if (get_enode(e))
|
if (get_enode(e))
|
||||||
return;
|
return;
|
||||||
if (si.is_bool_op(e))
|
if (si.is_bool_op(e))
|
||||||
attach_lit(si.internalize(e, redundant), e);
|
attach_lit(si.internalize(e), e);
|
||||||
else if (auto* ext = expr2solver(e))
|
else if (auto* ext = expr2solver(e))
|
||||||
ext->internalize(e, redundant);
|
ext->internalize(e);
|
||||||
else
|
else
|
||||||
visit_rec(m, e, false, false, redundant);
|
visit_rec(m, e, false, false);
|
||||||
SASSERT(m_egraph.find(e));
|
SASSERT(m_egraph.find(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
sat::literal solver::mk_literal(expr* e) {
|
sat::literal solver::mk_literal(expr* e) {
|
||||||
expr_ref _e(e, m);
|
expr_ref _e(e, m);
|
||||||
bool is_not = m.is_not(e, e);
|
bool is_not = m.is_not(e, e);
|
||||||
sat::literal lit = internalize(e, false, false, m_is_redundant);
|
sat::literal lit = internalize(e, false, false);
|
||||||
if (is_not)
|
if (is_not)
|
||||||
lit.neg();
|
lit.neg();
|
||||||
return lit;
|
return lit;
|
||||||
}
|
}
|
||||||
|
|
||||||
sat::literal solver::internalize(expr* e, bool sign, bool root, bool redundant) {
|
sat::literal solver::internalize(expr* e, bool sign, bool root) {
|
||||||
euf::enode* n = get_enode(e);
|
euf::enode* n = get_enode(e);
|
||||||
if (n) {
|
if (n) {
|
||||||
if (m.is_bool(e)) {
|
if (m.is_bool(e)) {
|
||||||
|
@ -67,14 +67,14 @@ namespace euf {
|
||||||
return sat::null_literal;
|
return sat::null_literal;
|
||||||
}
|
}
|
||||||
if (si.is_bool_op(e)) {
|
if (si.is_bool_op(e)) {
|
||||||
sat::literal lit = attach_lit(si.internalize(e, redundant), e);
|
sat::literal lit = attach_lit(si.internalize(e), e);
|
||||||
if (sign)
|
if (sign)
|
||||||
lit.neg();
|
lit.neg();
|
||||||
return lit;
|
return lit;
|
||||||
}
|
}
|
||||||
if (auto* ext = expr2solver(e))
|
if (auto* ext = expr2solver(e))
|
||||||
return ext->internalize(e, sign, root, redundant);
|
return ext->internalize(e, sign, root);
|
||||||
if (!visit_rec(m, e, sign, root, redundant)) {
|
if (!visit_rec(m, e, sign, root)) {
|
||||||
TRACE("euf", tout << "visit-rec\n";);
|
TRACE("euf", tout << "visit-rec\n";);
|
||||||
return sat::null_literal;
|
return sat::null_literal;
|
||||||
}
|
}
|
||||||
|
@ -89,13 +89,13 @@ namespace euf {
|
||||||
th_solver* s = nullptr;
|
th_solver* s = nullptr;
|
||||||
if (n && !si.is_bool_op(e) && (s = expr2solver(e), s && euf::null_theory_var == n->get_th_var(s->get_id()))) {
|
if (n && !si.is_bool_op(e) && (s = expr2solver(e), s && euf::null_theory_var == n->get_th_var(s->get_id()))) {
|
||||||
// ensure that theory variables are attached in shared contexts. See notes (*)
|
// ensure that theory variables are attached in shared contexts. See notes (*)
|
||||||
s->internalize(e, false);
|
s->internalize(e);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (n)
|
if (n)
|
||||||
return true;
|
return true;
|
||||||
if (si.is_bool_op(e)) {
|
if (si.is_bool_op(e)) {
|
||||||
attach_lit(si.internalize(e, m_is_redundant), e);
|
attach_lit(si.internalize(e), e);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (is_app(e) && to_app(e)->get_num_args() > 0) {
|
if (is_app(e) && to_app(e)->get_num_args() > 0) {
|
||||||
|
@ -103,7 +103,7 @@ namespace euf {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (auto* s = expr2solver(e))
|
if (auto* s = expr2solver(e))
|
||||||
s->internalize(e, m_is_redundant);
|
s->internalize(e);
|
||||||
else
|
else
|
||||||
attach_node(mk_enode(e, 0, nullptr));
|
attach_node(mk_enode(e, 0, nullptr));
|
||||||
return true;
|
return true;
|
||||||
|
@ -118,7 +118,7 @@ namespace euf {
|
||||||
return false;
|
return false;
|
||||||
SASSERT(!get_enode(e));
|
SASSERT(!get_enode(e));
|
||||||
if (auto* s = expr2solver(e))
|
if (auto* s = expr2solver(e))
|
||||||
s->internalize(e, m_is_redundant);
|
s->internalize(e);
|
||||||
else
|
else
|
||||||
attach_node(mk_enode(e, num, m_args.data()));
|
attach_node(mk_enode(e, num, m_args.data()));
|
||||||
return true;
|
return true;
|
||||||
|
@ -167,8 +167,8 @@ namespace euf {
|
||||||
ph1 = mk_smt_hint(symbol("tseitin"), ~lit, lit2);
|
ph1 = mk_smt_hint(symbol("tseitin"), ~lit, lit2);
|
||||||
ph2 = mk_smt_hint(symbol("tseitin"), lit, ~lit2);
|
ph2 = mk_smt_hint(symbol("tseitin"), lit, ~lit2);
|
||||||
}
|
}
|
||||||
s().mk_clause(~lit, lit2, sat::status::th(m_is_redundant, m.get_basic_family_id(), ph1));
|
s().mk_clause(~lit, lit2, sat::status::th(false, m.get_basic_family_id(), ph1));
|
||||||
s().mk_clause(lit, ~lit2, sat::status::th(m_is_redundant, m.get_basic_family_id(), ph2));
|
s().mk_clause(lit, ~lit2, sat::status::th(false, m.get_basic_family_id(), ph2));
|
||||||
add_aux(~lit, lit2);
|
add_aux(~lit, lit2);
|
||||||
add_aux(lit, ~lit2);
|
add_aux(lit, ~lit2);
|
||||||
lit = lit2;
|
lit = lit2;
|
||||||
|
@ -258,7 +258,7 @@ namespace euf {
|
||||||
}
|
}
|
||||||
pb_util pb(m);
|
pb_util pb(m);
|
||||||
expr_ref at_least2(pb.mk_at_least_k(eqs.size(), eqs.data(), 2), m);
|
expr_ref at_least2(pb.mk_at_least_k(eqs.size(), eqs.data(), 2), m);
|
||||||
sat::literal lit = si.internalize(at_least2, m_is_redundant);
|
sat::literal lit = si.internalize(at_least2);
|
||||||
s().add_clause(lit, mk_distinct_status(lit));
|
s().add_clause(lit, mk_distinct_status(lit));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,7 +331,7 @@ namespace euf {
|
||||||
}
|
}
|
||||||
expr_ref fml = mk_or(eqs);
|
expr_ref fml = mk_or(eqs);
|
||||||
sat::literal dist(si.to_bool_var(e), false);
|
sat::literal dist(si.to_bool_var(e), false);
|
||||||
sat::literal some_eq = si.internalize(fml, m_is_redundant);
|
sat::literal some_eq = si.internalize(fml);
|
||||||
add_root(~dist, ~some_eq);
|
add_root(~dist, ~some_eq);
|
||||||
add_root(dist, some_eq);
|
add_root(dist, some_eq);
|
||||||
s().add_clause(~dist, ~some_eq, mk_distinct_status(~dist, ~some_eq));
|
s().add_clause(~dist, ~some_eq, mk_distinct_status(~dist, ~some_eq));
|
||||||
|
@ -461,7 +461,7 @@ namespace euf {
|
||||||
euf::enode* solver::e_internalize(expr* e) {
|
euf::enode* solver::e_internalize(expr* e) {
|
||||||
euf::enode* n = m_egraph.find(e);
|
euf::enode* n = m_egraph.find(e);
|
||||||
if (!n) {
|
if (!n) {
|
||||||
internalize(e, m_is_redundant);
|
internalize(e);
|
||||||
n = m_egraph.find(e);
|
n = m_egraph.find(e);
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
|
|
|
@ -238,12 +238,12 @@ namespace euf {
|
||||||
|
|
||||||
sat::status solver::mk_tseitin_status(unsigned n, sat::literal const* lits) {
|
sat::status solver::mk_tseitin_status(unsigned n, sat::literal const* lits) {
|
||||||
th_proof_hint* ph = use_drat() ? mk_smt_hint(symbol("tseitin"), n, lits) : nullptr;
|
th_proof_hint* ph = use_drat() ? mk_smt_hint(symbol("tseitin"), n, lits) : nullptr;
|
||||||
return sat::status::th(m_is_redundant, m.get_basic_family_id(), ph);
|
return sat::status::th(false, m.get_basic_family_id(), ph);
|
||||||
}
|
}
|
||||||
|
|
||||||
sat::status solver::mk_distinct_status(unsigned n, sat::literal const* lits) {
|
sat::status solver::mk_distinct_status(unsigned n, sat::literal const* lits) {
|
||||||
th_proof_hint* ph = use_drat() ? mk_smt_hint(symbol("alldiff"), n, lits) : nullptr;
|
th_proof_hint* ph = use_drat() ? mk_smt_hint(symbol("alldiff"), n, lits) : nullptr;
|
||||||
return sat::status::th(m_is_redundant, m.get_basic_family_id(), ph);
|
return sat::status::th(false, m.get_basic_family_id(), ph);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr* smt_proof_hint::get_hint(euf::solver& s) const {
|
expr* smt_proof_hint::get_hint(euf::solver& s) const {
|
||||||
|
@ -294,7 +294,7 @@ namespace euf {
|
||||||
lits.push_back(jst.lit_consequent());
|
lits.push_back(jst.lit_consequent());
|
||||||
if (jst.eq_consequent().first != nullptr)
|
if (jst.eq_consequent().first != nullptr)
|
||||||
lits.push_back(add_lit(jst.eq_consequent()));
|
lits.push_back(add_lit(jst.eq_consequent()));
|
||||||
get_drat().add(lits, sat::status::th(m_is_redundant, jst.ext().get_id(), jst.get_pragma()));
|
get_drat().add(lits, sat::status::th(false, jst.ext().get_id(), jst.get_pragma()));
|
||||||
for (unsigned i = s().num_vars(); i < nv; ++i)
|
for (unsigned i = s().num_vars(); i < nv; ++i)
|
||||||
set_tmp_bool_var(i, nullptr);
|
set_tmp_bool_var(i, nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -655,14 +655,14 @@ namespace euf {
|
||||||
if (si.is_bool_op(e))
|
if (si.is_bool_op(e))
|
||||||
lit = literal(replay.m[e], false);
|
lit = literal(replay.m[e], false);
|
||||||
else
|
else
|
||||||
lit = si.internalize(e, false);
|
lit = si.internalize(e);
|
||||||
VERIFY(lit.var() == v);
|
VERIFY(lit.var() == v);
|
||||||
if (!m_egraph.find(e) && !m.is_iff(e) && !m.is_or(e) && !m.is_and(e) && !m.is_not(e) && !m.is_implies(e) && !m.is_xor(e)) {
|
if (!m_egraph.find(e) && !m.is_iff(e) && !m.is_or(e) && !m.is_and(e) && !m.is_not(e) && !m.is_implies(e) && !m.is_xor(e)) {
|
||||||
ptr_buffer<euf::enode> args;
|
ptr_buffer<euf::enode> args;
|
||||||
if (is_app(e))
|
if (is_app(e))
|
||||||
for (expr* arg : *to_app(e))
|
for (expr* arg : *to_app(e))
|
||||||
args.push_back(e_internalize(arg));
|
args.push_back(e_internalize(arg));
|
||||||
internalize(e, true);
|
internalize(e);
|
||||||
if (!m_egraph.find(e))
|
if (!m_egraph.find(e))
|
||||||
mk_enode(e, args.size(), args.data());
|
mk_enode(e, args.size(), args.data());
|
||||||
}
|
}
|
||||||
|
@ -692,10 +692,10 @@ namespace euf {
|
||||||
disable_relevancy(e);
|
disable_relevancy(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto lit = si.internalize(e, true);
|
auto lit = si.internalize(e);
|
||||||
switch (to_app(e)->get_decl_kind()) {
|
switch (to_app(e)->get_decl_kind()) {
|
||||||
case OP_NOT: {
|
case OP_NOT: {
|
||||||
auto lit2 = si.internalize(to_app(e)->get_arg(0), true);
|
auto lit2 = si.internalize(to_app(e)->get_arg(0));
|
||||||
add_aux(lit, lit2);
|
add_aux(lit, lit2);
|
||||||
add_aux(~lit, ~lit2);
|
add_aux(~lit, ~lit2);
|
||||||
break;
|
break;
|
||||||
|
@ -705,8 +705,8 @@ namespace euf {
|
||||||
disable_relevancy(e);
|
disable_relevancy(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto lit1 = si.internalize(to_app(e)->get_arg(0), true);
|
auto lit1 = si.internalize(to_app(e)->get_arg(0));
|
||||||
auto lit2 = si.internalize(to_app(e)->get_arg(1), true);
|
auto lit2 = si.internalize(to_app(e)->get_arg(1));
|
||||||
add_aux(~lit, ~lit1, lit2);
|
add_aux(~lit, ~lit1, lit2);
|
||||||
add_aux(~lit, lit1, ~lit2);
|
add_aux(~lit, lit1, ~lit2);
|
||||||
add_aux(lit, lit1, lit2);
|
add_aux(lit, lit1, lit2);
|
||||||
|
@ -716,7 +716,7 @@ namespace euf {
|
||||||
case OP_OR: {
|
case OP_OR: {
|
||||||
sat::literal_vector lits;
|
sat::literal_vector lits;
|
||||||
for (expr* arg : *to_app(e))
|
for (expr* arg : *to_app(e))
|
||||||
lits.push_back(si.internalize(arg, true));
|
lits.push_back(si.internalize(arg));
|
||||||
for (auto lit2 : lits)
|
for (auto lit2 : lits)
|
||||||
add_aux(~lit2, lit);
|
add_aux(~lit2, lit);
|
||||||
lits.push_back(~lit);
|
lits.push_back(~lit);
|
||||||
|
@ -726,7 +726,7 @@ namespace euf {
|
||||||
case OP_AND: {
|
case OP_AND: {
|
||||||
sat::literal_vector lits;
|
sat::literal_vector lits;
|
||||||
for (expr* arg : *to_app(e))
|
for (expr* arg : *to_app(e))
|
||||||
lits.push_back(~si.internalize(arg, true));
|
lits.push_back(~si.internalize(arg));
|
||||||
for (auto nlit2 : lits)
|
for (auto nlit2 : lits)
|
||||||
add_aux(~lit, ~nlit2);
|
add_aux(~lit, ~nlit2);
|
||||||
lits.push_back(lit);
|
lits.push_back(lit);
|
||||||
|
@ -740,9 +740,9 @@ namespace euf {
|
||||||
add_aux(~lit);
|
add_aux(~lit);
|
||||||
break;
|
break;
|
||||||
case OP_ITE: {
|
case OP_ITE: {
|
||||||
auto lit1 = si.internalize(to_app(e)->get_arg(0), true);
|
auto lit1 = si.internalize(to_app(e)->get_arg(0));
|
||||||
auto lit2 = si.internalize(to_app(e)->get_arg(1), true);
|
auto lit2 = si.internalize(to_app(e)->get_arg(1));
|
||||||
auto lit3 = si.internalize(to_app(e)->get_arg(2), true);
|
auto lit3 = si.internalize(to_app(e)->get_arg(2));
|
||||||
add_aux(~lit, ~lit1, lit2);
|
add_aux(~lit, ~lit1, lit2);
|
||||||
add_aux(~lit, lit1, lit3);
|
add_aux(~lit, lit1, lit3);
|
||||||
add_aux(lit, ~lit1, ~lit2);
|
add_aux(lit, ~lit1, ~lit2);
|
||||||
|
@ -754,8 +754,8 @@ namespace euf {
|
||||||
disable_relevancy(e);
|
disable_relevancy(e);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto lit1 = si.internalize(to_app(e)->get_arg(0), true);
|
auto lit1 = si.internalize(to_app(e)->get_arg(0));
|
||||||
auto lit2 = si.internalize(to_app(e)->get_arg(1), true);
|
auto lit2 = si.internalize(to_app(e)->get_arg(1));
|
||||||
add_aux(lit, ~lit1, lit2);
|
add_aux(lit, ~lit1, lit2);
|
||||||
add_aux(lit, lit1, ~lit2);
|
add_aux(lit, lit1, ~lit2);
|
||||||
add_aux(~lit, lit1, lit2);
|
add_aux(~lit, lit1, lit2);
|
||||||
|
@ -767,8 +767,8 @@ namespace euf {
|
||||||
disable_relevancy(e);
|
disable_relevancy(e);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto lit1 = si.internalize(to_app(e)->get_arg(0), true);
|
auto lit1 = si.internalize(to_app(e)->get_arg(0));
|
||||||
auto lit2 = si.internalize(to_app(e)->get_arg(1), true);
|
auto lit2 = si.internalize(to_app(e)->get_arg(1));
|
||||||
add_aux(~lit, ~lit1, lit2);
|
add_aux(~lit, ~lit1, lit2);
|
||||||
add_aux(lit, lit1);
|
add_aux(lit, lit1);
|
||||||
add_aux(lit, ~lit2);
|
add_aux(lit, ~lit2);
|
||||||
|
|
|
@ -439,8 +439,8 @@ namespace euf {
|
||||||
bool to_formulas(std::function<expr_ref(sat::literal)>& l2e, expr_ref_vector& fmls) override;
|
bool to_formulas(std::function<expr_ref(sat::literal)>& l2e, expr_ref_vector& fmls) override;
|
||||||
|
|
||||||
// internalize
|
// internalize
|
||||||
sat::literal internalize(expr* e, bool sign, bool root, bool learned) override;
|
sat::literal internalize(expr* e, bool sign, bool root) override;
|
||||||
void internalize(expr* e, bool learned) override;
|
void internalize(expr* e) override;
|
||||||
sat::literal mk_literal(expr* e);
|
sat::literal mk_literal(expr* e);
|
||||||
void attach_th_var(enode* n, th_solver* th, theory_var v) { m_egraph.add_th_var(n, v, th->get_id()); }
|
void attach_th_var(enode* n, th_solver* th, theory_var v) { m_egraph.add_th_var(n, v, th->get_id()); }
|
||||||
void attach_node(euf::enode* n);
|
void attach_node(euf::enode* n);
|
||||||
|
|
|
@ -95,9 +95,9 @@ namespace fpa {
|
||||||
TRACE("t_fpa", tout << "new theory var: " << mk_ismt2_pp(n->get_expr(), m) << " := " << v << "\n";);
|
TRACE("t_fpa", tout << "new theory var: " << mk_ismt2_pp(n->get_expr(), m) << " := " << v << "\n";);
|
||||||
}
|
}
|
||||||
|
|
||||||
sat::literal solver::internalize(expr* e, bool sign, bool root, bool redundant) {
|
sat::literal solver::internalize(expr* e, bool sign, bool root) {
|
||||||
SASSERT(m.is_bool(e));
|
SASSERT(m.is_bool(e));
|
||||||
if (!visit_rec(m, e, sign, root, redundant))
|
if (!visit_rec(m, e, sign, root))
|
||||||
return sat::null_literal;
|
return sat::null_literal;
|
||||||
sat::literal lit = expr2literal(e);
|
sat::literal lit = expr2literal(e);
|
||||||
if (sign)
|
if (sign)
|
||||||
|
@ -105,8 +105,8 @@ namespace fpa {
|
||||||
return lit;
|
return lit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::internalize(expr* e, bool redundant) {
|
void solver::internalize(expr* e) {
|
||||||
visit_rec(m, e, false, false, redundant);
|
visit_rec(m, e, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool solver::visited(expr* e) {
|
bool solver::visited(expr* e) {
|
||||||
|
@ -118,7 +118,7 @@ namespace fpa {
|
||||||
if (visited(e))
|
if (visited(e))
|
||||||
return true;
|
return true;
|
||||||
if (!is_app(e) || to_app(e)->get_family_id() != get_id()) {
|
if (!is_app(e) || to_app(e)->get_family_id() != get_id()) {
|
||||||
ctx.internalize(e, m_is_redundant);
|
ctx.internalize(e);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
m_stack.push_back(sat::eframe(e));
|
m_stack.push_back(sat::eframe(e));
|
||||||
|
|
|
@ -59,8 +59,8 @@ namespace fpa {
|
||||||
bool use_diseqs() const override { return true; }
|
bool use_diseqs() const override { return true; }
|
||||||
void new_diseq_eh(euf::th_eq const& eq) override;
|
void new_diseq_eh(euf::th_eq const& eq) override;
|
||||||
|
|
||||||
sat::literal internalize(expr* e, bool sign, bool root, bool learned) override;
|
sat::literal internalize(expr* e, bool sign, bool root) override;
|
||||||
void internalize(expr* e, bool redundant) override;
|
void internalize(expr* e) override;
|
||||||
void apply_sort_cnstr(euf::enode* n, sort* s) override;
|
void apply_sort_cnstr(euf::enode* n, sort* s) override;
|
||||||
|
|
||||||
std::ostream& display(std::ostream& out) const override;
|
std::ostream& display(std::ostream& out) const override;
|
||||||
|
|
|
@ -22,12 +22,11 @@ Author:
|
||||||
|
|
||||||
namespace pb {
|
namespace pb {
|
||||||
|
|
||||||
void solver::internalize(expr* e, bool redundant) {
|
void solver::internalize(expr* e) {
|
||||||
internalize(e, false, false, redundant);
|
internalize(e, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
literal solver::internalize(expr* e, bool sign, bool root, bool redundant) {
|
literal solver::internalize(expr* e, bool sign, bool root) {
|
||||||
flet<bool> _redundant(m_is_redundant, redundant);
|
|
||||||
if (m_pb.is_pb(e)) {
|
if (m_pb.is_pb(e)) {
|
||||||
sat::literal lit = internalize_pb(e, sign, root);
|
sat::literal lit = internalize_pb(e, sign, root);
|
||||||
if (m_ctx && !root && lit != sat::null_literal)
|
if (m_ctx && !root && lit != sat::null_literal)
|
||||||
|
@ -84,7 +83,7 @@ namespace pb {
|
||||||
|
|
||||||
void solver::convert_pb_args(app* t, literal_vector& lits) {
|
void solver::convert_pb_args(app* t, literal_vector& lits) {
|
||||||
for (expr* arg : *t) {
|
for (expr* arg : *t) {
|
||||||
lits.push_back(si.internalize(arg, m_is_redundant));
|
lits.push_back(si.internalize(arg));
|
||||||
s().set_external(lits.back().var());
|
s().set_external(lits.back().var());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -402,8 +402,8 @@ namespace pb {
|
||||||
bool is_blocked(literal l, sat::ext_constraint_idx idx) override;
|
bool is_blocked(literal l, sat::ext_constraint_idx idx) override;
|
||||||
bool check_model(sat::model const& m) const override;
|
bool check_model(sat::model const& m) const override;
|
||||||
|
|
||||||
literal internalize(expr* e, bool sign, bool root, bool redundant) override;
|
literal internalize(expr* e, bool sign, bool root) override;
|
||||||
void internalize(expr* e, bool redundant) override;
|
void internalize(expr* e) override;
|
||||||
bool to_formulas(std::function<expr_ref(sat::literal)>& l2e, expr_ref_vector& fmls) override;
|
bool to_formulas(std::function<expr_ref(sat::literal)>& l2e, expr_ref_vector& fmls) override;
|
||||||
euf::th_solver* clone(euf::solver& ctx) override;
|
euf::th_solver* clone(euf::solver& ctx) override;
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace q {
|
||||||
if (!m_flat.find(q, q_flat)) {
|
if (!m_flat.find(q, q_flat)) {
|
||||||
if (expand(q)) {
|
if (expand(q)) {
|
||||||
for (expr* e : m_expanded) {
|
for (expr* e : m_expanded) {
|
||||||
sat::literal lit = ctx.internalize(e, l.sign(), false, false);
|
sat::literal lit = ctx.internalize(e, l.sign(), false);
|
||||||
add_clause(~l, lit);
|
add_clause(~l, lit);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -62,7 +62,7 @@ namespace q {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_ground(q_flat->get_expr())) {
|
if (is_ground(q_flat->get_expr())) {
|
||||||
auto lit = ctx.internalize(q_flat->get_expr(), l.sign(), false, false);
|
auto lit = ctx.internalize(q_flat->get_expr(), l.sign(), false);
|
||||||
add_clause(~l, lit);
|
add_clause(~l, lit);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -163,7 +163,7 @@ namespace q {
|
||||||
m_mbqi.init_search();
|
m_mbqi.init_search();
|
||||||
}
|
}
|
||||||
|
|
||||||
sat::literal solver::internalize(expr* e, bool sign, bool root, bool learned) {
|
sat::literal solver::internalize(expr* e, bool sign, bool root) {
|
||||||
SASSERT(is_forall(e) || is_exists(e));
|
SASSERT(is_forall(e) || is_exists(e));
|
||||||
sat::bool_var v = ctx.get_si().add_bool_var(e);
|
sat::bool_var v = ctx.get_si().add_bool_var(e);
|
||||||
sat::literal lit = ctx.attach_lit(sat::literal(v, false), e);
|
sat::literal lit = ctx.attach_lit(sat::literal(v, false), e);
|
||||||
|
|
|
@ -95,8 +95,8 @@ namespace q {
|
||||||
void collect_statistics(statistics& st) const override;
|
void collect_statistics(statistics& st) const override;
|
||||||
euf::th_solver* clone(euf::solver& ctx) override;
|
euf::th_solver* clone(euf::solver& ctx) override;
|
||||||
bool unit_propagate() override;
|
bool unit_propagate() override;
|
||||||
sat::literal internalize(expr* e, bool sign, bool root, bool learned) override;
|
sat::literal internalize(expr* e, bool sign, bool root) override;
|
||||||
void internalize(expr* e, bool redundant) override { internalize(e, false, false, redundant); }
|
void internalize(expr* e) override { internalize(e, false, false); }
|
||||||
euf::theory_var mk_var(euf::enode* n) override;
|
euf::theory_var mk_var(euf::enode* n) override;
|
||||||
void init_search() override;
|
void init_search() override;
|
||||||
void finalize_model(model& mdl) override;
|
void finalize_model(model& mdl) override;
|
||||||
|
|
|
@ -232,10 +232,10 @@ namespace recfun {
|
||||||
ctx.push(push_back_vector<scoped_ptr_vector<propagation_item>>(m_propagation_queue));
|
ctx.push(push_back_vector<scoped_ptr_vector<propagation_item>>(m_propagation_queue));
|
||||||
}
|
}
|
||||||
|
|
||||||
sat::literal solver::internalize(expr* e, bool sign, bool root, bool redundant) {
|
sat::literal solver::internalize(expr* e, bool sign, bool root) {
|
||||||
force_push();
|
force_push();
|
||||||
SASSERT(m.is_bool(e));
|
SASSERT(m.is_bool(e));
|
||||||
if (!visit_rec(m, e, sign, root, redundant)) {
|
if (!visit_rec(m, e, sign, root)) {
|
||||||
TRACE("array", tout << mk_pp(e, m) << "\n";);
|
TRACE("array", tout << mk_pp(e, m) << "\n";);
|
||||||
return sat::null_literal;
|
return sat::null_literal;
|
||||||
}
|
}
|
||||||
|
@ -245,9 +245,9 @@ namespace recfun {
|
||||||
return lit;
|
return lit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::internalize(expr* e, bool redundant) {
|
void solver::internalize(expr* e) {
|
||||||
force_push();
|
force_push();
|
||||||
visit_rec(m, e, false, false, redundant);
|
visit_rec(m, e, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool solver::visited(expr* e) {
|
bool solver::visited(expr* e) {
|
||||||
|
@ -259,7 +259,7 @@ namespace recfun {
|
||||||
if (visited(e))
|
if (visited(e))
|
||||||
return true;
|
return true;
|
||||||
if (!is_app(e) || to_app(e)->get_family_id() != get_id()) {
|
if (!is_app(e) || to_app(e)->get_family_id() != get_id()) {
|
||||||
ctx.internalize(e, m_is_redundant);
|
ctx.internalize(e);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
m_stack.push_back(sat::eframe(e));
|
m_stack.push_back(sat::eframe(e));
|
||||||
|
|
|
@ -101,8 +101,8 @@ namespace recfun {
|
||||||
void collect_statistics(statistics& st) const override;
|
void collect_statistics(statistics& st) const override;
|
||||||
euf::th_solver* clone(euf::solver& ctx) override;
|
euf::th_solver* clone(euf::solver& ctx) override;
|
||||||
bool unit_propagate() override;
|
bool unit_propagate() override;
|
||||||
sat::literal internalize(expr* e, bool sign, bool root, bool learned) override;
|
sat::literal internalize(expr* e, bool sign, bool root) override;
|
||||||
void internalize(expr* e, bool redundant) override;
|
void internalize(expr* e) override;
|
||||||
bool add_dep(euf::enode* n, top_sort<euf::enode>& dep) override;
|
bool add_dep(euf::enode* n, top_sort<euf::enode>& dep) override;
|
||||||
void add_value(euf::enode* n, model& mdl, expr_ref_vector& values) override;
|
void add_value(euf::enode* n, model& mdl, expr_ref_vector& values) override;
|
||||||
bool is_shared(euf::theory_var v) const override { return true; }
|
bool is_shared(euf::theory_var v) const override { return true; }
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace sat {
|
||||||
public:
|
public:
|
||||||
virtual ~sat_internalizer() = default;
|
virtual ~sat_internalizer() = default;
|
||||||
virtual bool is_bool_op(expr* e) const = 0;
|
virtual bool is_bool_op(expr* e) const = 0;
|
||||||
virtual literal internalize(expr* e, bool learned) = 0;
|
virtual literal internalize(expr* e) = 0;
|
||||||
virtual bool_var to_bool_var(expr* e) = 0;
|
virtual bool_var to_bool_var(expr* e) = 0;
|
||||||
virtual bool_var add_bool_var(expr* e) = 0;
|
virtual bool_var add_bool_var(expr* e) = 0;
|
||||||
virtual bool is_cached(app* t, literal l) const = 0;
|
virtual bool is_cached(app* t, literal l) const = 0;
|
||||||
|
|
|
@ -21,9 +21,8 @@ Author:
|
||||||
|
|
||||||
namespace euf {
|
namespace euf {
|
||||||
|
|
||||||
bool th_internalizer::visit_rec(ast_manager& m, expr* a, bool sign, bool root, bool redundant) {
|
bool th_internalizer::visit_rec(ast_manager& m, expr* a, bool sign, bool root) {
|
||||||
IF_VERBOSE(110, verbose_stream() << "internalize: " << mk_pp(a, m) << "\n");
|
IF_VERBOSE(110, verbose_stream() << "internalize: " << mk_pp(a, m) << "\n");
|
||||||
flet<bool> _is_learned(m_is_redundant, redundant);
|
|
||||||
svector<sat::eframe>::scoped_stack _sc(m_stack);
|
svector<sat::eframe>::scoped_stack _sc(m_stack);
|
||||||
unsigned sz = m_stack.size();
|
unsigned sz = m_stack.size();
|
||||||
visit(a);
|
visit(a);
|
||||||
|
@ -125,15 +124,11 @@ namespace euf {
|
||||||
pop_core(n);
|
pop_core(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
sat::status th_euf_solver::mk_status(th_proof_hint const* ps) {
|
|
||||||
return sat::status::th(m_is_redundant, get_id(), ps);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool th_euf_solver::add_unit(sat::literal lit, th_proof_hint const* ps) {
|
bool th_euf_solver::add_unit(sat::literal lit, th_proof_hint const* ps) {
|
||||||
if (ctx.use_drat() && !ps)
|
if (ctx.use_drat() && !ps)
|
||||||
ps = ctx.mk_smt_clause(name(), 1, &lit);
|
ps = ctx.mk_smt_clause(name(), 1, &lit);
|
||||||
bool was_true = is_true(lit);
|
bool was_true = is_true(lit);
|
||||||
ctx.s().add_clause(1, &lit, mk_status(ps));
|
ctx.s().add_clause(1, &lit, sat::status::th(false, get_id(), ps));
|
||||||
ctx.add_root(lit);
|
ctx.add_root(lit);
|
||||||
return !was_true;
|
return !was_true;
|
||||||
}
|
}
|
||||||
|
@ -161,7 +156,7 @@ namespace euf {
|
||||||
return add_clause(4, lits, ps);
|
return add_clause(4, lits, ps);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool th_euf_solver::add_clause(unsigned n, sat::literal* lits, th_proof_hint const* ps) {
|
bool th_euf_solver::add_clause(unsigned n, sat::literal* lits, th_proof_hint const* ps, bool is_redundant) {
|
||||||
if (ctx.use_drat() && !ps)
|
if (ctx.use_drat() && !ps)
|
||||||
ps = ctx.mk_smt_clause(name(), n, lits);
|
ps = ctx.mk_smt_clause(name(), n, lits);
|
||||||
|
|
||||||
|
@ -169,7 +164,7 @@ namespace euf {
|
||||||
for (unsigned i = 0; i < n; ++i)
|
for (unsigned i = 0; i < n; ++i)
|
||||||
was_true |= is_true(lits[i]);
|
was_true |= is_true(lits[i]);
|
||||||
ctx.add_root(n, lits);
|
ctx.add_root(n, lits);
|
||||||
s().add_clause(n, lits, mk_status(ps));
|
s().add_clause(n, lits, sat::status::th(is_redundant, get_id(), ps));
|
||||||
return !was_true;
|
return !was_true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,8 @@ namespace euf {
|
||||||
protected:
|
protected:
|
||||||
euf::enode_vector m_args;
|
euf::enode_vector m_args;
|
||||||
svector<sat::eframe> m_stack;
|
svector<sat::eframe> m_stack;
|
||||||
bool m_is_redundant{ false };
|
|
||||||
|
|
||||||
bool visit_rec(ast_manager& m, expr* e, bool sign, bool root, bool redundant);
|
bool visit_rec(ast_manager& m, expr* e, bool sign, bool root);
|
||||||
|
|
||||||
virtual bool visit(expr* e) { return false; }
|
virtual bool visit(expr* e) { return false; }
|
||||||
virtual bool visited(expr* e) { return false; }
|
virtual bool visited(expr* e) { return false; }
|
||||||
|
@ -41,9 +40,9 @@ namespace euf {
|
||||||
public:
|
public:
|
||||||
virtual ~th_internalizer() = default;
|
virtual ~th_internalizer() = default;
|
||||||
|
|
||||||
virtual sat::literal internalize(expr* e, bool sign, bool root, bool redundant) = 0;
|
virtual sat::literal internalize(expr* e, bool sign, bool root) = 0;
|
||||||
|
|
||||||
virtual void internalize(expr* e, bool redundant) = 0;
|
virtual void internalize(expr* e) = 0;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -135,7 +134,7 @@ namespace euf {
|
||||||
|
|
||||||
virtual bool is_beta_redex(euf::enode* p, euf::enode* n) const { return false; }
|
virtual bool is_beta_redex(euf::enode* p, euf::enode* n) const { return false; }
|
||||||
|
|
||||||
sat::status status() const { return sat::status::th(m_is_redundant, get_id()); }
|
sat::status status() const { return sat::status::th(false, get_id()); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -155,8 +154,6 @@ namespace euf {
|
||||||
sat::literal expr2literal(expr* e) const;
|
sat::literal expr2literal(expr* e) const;
|
||||||
region& get_region();
|
region& get_region();
|
||||||
|
|
||||||
|
|
||||||
sat::status mk_status(th_proof_hint const* ps = nullptr);
|
|
||||||
bool add_unit(sat::literal lit, th_proof_hint const* ps = nullptr);
|
bool add_unit(sat::literal lit, th_proof_hint const* ps = nullptr);
|
||||||
bool add_units(sat::literal_vector const& lits);
|
bool add_units(sat::literal_vector const& lits);
|
||||||
bool add_clause(sat::literal lit, th_proof_hint const* ps = nullptr) { return add_unit(lit, ps); }
|
bool add_clause(sat::literal lit, th_proof_hint const* ps = nullptr) { return add_unit(lit, ps); }
|
||||||
|
@ -164,9 +161,11 @@ namespace euf {
|
||||||
bool add_clause(sat::literal a, sat::literal b, sat::literal c, th_proof_hint const* ps = nullptr);
|
bool add_clause(sat::literal a, sat::literal b, sat::literal c, th_proof_hint const* ps = nullptr);
|
||||||
bool add_clause(sat::literal a, sat::literal b, sat::literal c, sat::literal d, th_proof_hint const* ps = nullptr);
|
bool add_clause(sat::literal a, sat::literal b, sat::literal c, sat::literal d, th_proof_hint const* ps = nullptr);
|
||||||
bool add_clause(sat::literal_vector const& lits, th_proof_hint const* ps = nullptr) { return add_clause(lits.size(), lits.data(), ps); }
|
bool add_clause(sat::literal_vector const& lits, th_proof_hint const* ps = nullptr) { return add_clause(lits.size(), lits.data(), ps); }
|
||||||
bool add_clause(unsigned n, sat::literal* lits, th_proof_hint const* ps = nullptr);
|
bool add_clause(unsigned n, sat::literal* lits, th_proof_hint const* ps, bool is_redundant = false);
|
||||||
void add_equiv(sat::literal a, sat::literal b);
|
void add_equiv(sat::literal a, sat::literal b);
|
||||||
void add_equiv_and(sat::literal a, sat::literal_vector const& bs);
|
void add_equiv_and(sat::literal a, sat::literal_vector const& bs);
|
||||||
|
bool add_redundant(sat::literal_vector const& lits, th_proof_hint const* ps) { return add_clause(lits.size(), lits.data(), ps, true); }
|
||||||
|
bool add_redundant(unsigned n, sat::literal* lits, th_proof_hint const* ps);
|
||||||
|
|
||||||
|
|
||||||
bool is_true(sat::literal lit);
|
bool is_true(sat::literal lit);
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace user_solver {
|
||||||
|
|
||||||
void solver::add_expr(expr* e) {
|
void solver::add_expr(expr* e) {
|
||||||
force_push();
|
force_push();
|
||||||
ctx.internalize(e, false);
|
ctx.internalize(e);
|
||||||
euf::enode* n = expr2enode(e);
|
euf::enode* n = expr2enode(e);
|
||||||
if (is_attached_to_var(n))
|
if (is_attached_to_var(n))
|
||||||
return;
|
return;
|
||||||
|
@ -63,7 +63,7 @@ namespace user_solver {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
force_push();
|
force_push();
|
||||||
ctx.internalize(e, false);
|
ctx.internalize(e);
|
||||||
m_next_split_expr = e;
|
m_next_split_expr = e;
|
||||||
m_next_split_idx = idx;
|
m_next_split_idx = idx;
|
||||||
m_next_split_phase = phase;
|
m_next_split_phase = phase;
|
||||||
|
@ -162,7 +162,7 @@ namespace user_solver {
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::propagate_consequence(prop_info const& prop) {
|
void solver::propagate_consequence(prop_info const& prop) {
|
||||||
sat::literal lit = ctx.internalize(prop.m_conseq, false, false, true);
|
sat::literal lit = ctx.internalize(prop.m_conseq, false, false);
|
||||||
if (s().value(lit) != l_true) {
|
if (s().value(lit) != l_true) {
|
||||||
s().assign(lit, mk_justification(m_qhead));
|
s().assign(lit, mk_justification(m_qhead));
|
||||||
++m_stats.m_num_propagations;
|
++m_stats.m_num_propagations;
|
||||||
|
@ -250,8 +250,8 @@ namespace user_solver {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
sat::literal solver::internalize(expr* e, bool sign, bool root, bool redundant) {
|
sat::literal solver::internalize(expr* e, bool sign, bool root) {
|
||||||
if (!visit_rec(m, e, sign, root, redundant)) {
|
if (!visit_rec(m, e, sign, root)) {
|
||||||
TRACE("array", tout << mk_pp(e, m) << "\n";);
|
TRACE("array", tout << mk_pp(e, m) << "\n";);
|
||||||
return sat::null_literal;
|
return sat::null_literal;
|
||||||
}
|
}
|
||||||
|
@ -263,15 +263,15 @@ namespace user_solver {
|
||||||
return lit;
|
return lit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::internalize(expr* e, bool redundant) {
|
void solver::internalize(expr* e) {
|
||||||
visit_rec(m, e, false, false, redundant);
|
visit_rec(m, e, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool solver::visit(expr* e) {
|
bool solver::visit(expr* e) {
|
||||||
if (visited(e))
|
if (visited(e))
|
||||||
return true;
|
return true;
|
||||||
if (!is_app(e) || to_app(e)->get_family_id() != get_id()) {
|
if (!is_app(e) || to_app(e)->get_family_id() != get_id()) {
|
||||||
ctx.internalize(e, m_is_redundant);
|
ctx.internalize(e);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
m_stack.push_back(sat::eframe(e));
|
m_stack.push_back(sat::eframe(e));
|
||||||
|
|
|
@ -154,8 +154,8 @@ namespace user_solver {
|
||||||
bool unit_propagate() override;
|
bool unit_propagate() override;
|
||||||
void get_antecedents(sat::literal l, sat::ext_justification_idx idx, sat::literal_vector & r, bool probing) override;
|
void get_antecedents(sat::literal l, sat::ext_justification_idx idx, sat::literal_vector & r, bool probing) override;
|
||||||
void collect_statistics(statistics& st) const override;
|
void collect_statistics(statistics& st) const override;
|
||||||
sat::literal internalize(expr* e, bool sign, bool root, bool learned) override;
|
sat::literal internalize(expr* e, bool sign, bool root) override;
|
||||||
void internalize(expr* e, bool redundant) override;
|
void internalize(expr* e) override;
|
||||||
std::ostream& display(std::ostream& out) const override;
|
std::ostream& display(std::ostream& out) const override;
|
||||||
std::ostream& display_justification(std::ostream& out, sat::ext_justification_idx idx) const override;
|
std::ostream& display_justification(std::ostream& out, sat::ext_justification_idx idx) const override;
|
||||||
std::ostream& display_constraint(std::ostream& out, sat::ext_constraint_idx idx) const override;
|
std::ostream& display_constraint(std::ostream& out, sat::ext_constraint_idx idx) const override;
|
||||||
|
|
|
@ -75,7 +75,6 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
||||||
func_decl_ref_vector m_unhandled_funs;
|
func_decl_ref_vector m_unhandled_funs;
|
||||||
bool m_default_external;
|
bool m_default_external;
|
||||||
bool m_euf = false;
|
bool m_euf = false;
|
||||||
bool m_is_redundant = false;
|
|
||||||
bool m_top_level = false;
|
bool m_top_level = false;
|
||||||
sat::literal_vector aig_lits;
|
sat::literal_vector aig_lits;
|
||||||
|
|
||||||
|
@ -133,7 +132,7 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
sat::status mk_status(euf::th_proof_hint* ph = nullptr) const {
|
sat::status mk_status(euf::th_proof_hint* ph = nullptr) const {
|
||||||
return sat::status::th(m_is_redundant, m.get_basic_family_id(), ph);
|
return sat::status::th(false, m.get_basic_family_id(), ph);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool relevancy_enabled() {
|
bool relevancy_enabled() {
|
||||||
|
@ -179,7 +178,7 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
||||||
TRACE("goal2sat", tout << "mk_root_clause: "; for (unsigned i = 0; i < n; i++) tout << lits[i] << " "; tout << "\n";);
|
TRACE("goal2sat", tout << "mk_root_clause: "; for (unsigned i = 0; i < n; i++) tout << lits[i] << " "; tout << "\n";);
|
||||||
if (relevancy_enabled())
|
if (relevancy_enabled())
|
||||||
ensure_euf()->add_root(n, lits);
|
ensure_euf()->add_root(n, lits);
|
||||||
m_solver.add_clause(n, lits, m_is_redundant ? mk_status(ph) : sat::status::input());
|
m_solver.add_clause(n, lits, ph ? mk_status(ph) : sat::status::input());
|
||||||
}
|
}
|
||||||
|
|
||||||
sat::bool_var add_var(bool is_ext, expr* n) {
|
sat::bool_var add_var(bool is_ext, expr* n) {
|
||||||
|
@ -688,7 +687,7 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
||||||
sat::literal lit;
|
sat::literal lit;
|
||||||
{
|
{
|
||||||
flet<bool> _top(m_top_level, false);
|
flet<bool> _top(m_top_level, false);
|
||||||
lit = euf->internalize(e, sign, root, m_is_redundant);
|
lit = euf->internalize(e, sign, root);
|
||||||
}
|
}
|
||||||
if (lit == sat::null_literal)
|
if (lit == sat::null_literal)
|
||||||
return;
|
return;
|
||||||
|
@ -711,7 +710,7 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
||||||
th = dynamic_cast<euf::th_solver*>(ext);
|
th = dynamic_cast<euf::th_solver*>(ext);
|
||||||
SASSERT(th);
|
SASSERT(th);
|
||||||
}
|
}
|
||||||
auto lit = th->internalize(t, sign, root, m_is_redundant);
|
auto lit = th->internalize(t, sign, root);
|
||||||
m_result_stack.shrink(m_result_stack.size() - t->get_num_args());
|
m_result_stack.shrink(m_result_stack.size() - t->get_num_args());
|
||||||
if (lit == sat::null_literal)
|
if (lit == sat::null_literal)
|
||||||
return;
|
return;
|
||||||
|
@ -780,12 +779,11 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void process(expr* n, bool is_root, bool redundant) {
|
void process(expr* n, bool is_root) {
|
||||||
TRACE("goal2sat", tout << "process-begin " << mk_bounded_pp(n, m, 2)
|
TRACE("goal2sat", tout << "process-begin " << mk_bounded_pp(n, m, 2)
|
||||||
<< " root: " << is_root
|
<< " root: " << is_root
|
||||||
<< " result-stack: " << m_result_stack.size()
|
<< " result-stack: " << m_result_stack.size()
|
||||||
<< " frame-stack: " << m_frame_stack.size() << "\n";);
|
<< " frame-stack: " << m_frame_stack.size() << "\n";);
|
||||||
flet<bool> _is_redundant(m_is_redundant, redundant);
|
|
||||||
scoped_stack _sc(*this, is_root);
|
scoped_stack _sc(*this, is_root);
|
||||||
unsigned sz = m_frame_stack.size();
|
unsigned sz = m_frame_stack.size();
|
||||||
if (visit(n, is_root, false))
|
if (visit(n, is_root, false))
|
||||||
|
@ -836,14 +834,14 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
||||||
<< " result-stack: " << m_result_stack.size() << "\n";);
|
<< " result-stack: " << m_result_stack.size() << "\n";);
|
||||||
}
|
}
|
||||||
|
|
||||||
sat::literal internalize(expr* n, bool redundant) override {
|
sat::literal internalize(expr* n) override {
|
||||||
bool is_not = m.is_not(n, n);
|
bool is_not = m.is_not(n, n);
|
||||||
flet<bool> _top(m_top_level, false);
|
flet<bool> _top(m_top_level, false);
|
||||||
unsigned sz = m_result_stack.size();
|
unsigned sz = m_result_stack.size();
|
||||||
(void)sz;
|
(void)sz;
|
||||||
SASSERT(n->get_ref_count() > 0);
|
SASSERT(n->get_ref_count() > 0);
|
||||||
TRACE("goal2sat", tout << "internalize " << mk_bounded_pp(n, m, 2) << "\n";);
|
TRACE("goal2sat", tout << "internalize " << mk_bounded_pp(n, m, 2) << "\n";);
|
||||||
process(n, false, redundant);
|
process(n, false);
|
||||||
SASSERT(m_result_stack.size() == sz + 1);
|
SASSERT(m_result_stack.size() == sz + 1);
|
||||||
sat::literal result = m_result_stack.back();
|
sat::literal result = m_result_stack.back();
|
||||||
TRACE("goal2sat", tout << "done internalize " << result << " " << mk_bounded_pp(n, m, 2) << "\n";);
|
TRACE("goal2sat", tout << "done internalize " << result << " " << mk_bounded_pp(n, m, 2) << "\n";);
|
||||||
|
@ -889,7 +887,7 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
||||||
flet<bool> _top(m_top_level, true);
|
flet<bool> _top(m_top_level, true);
|
||||||
VERIFY(m_result_stack.empty());
|
VERIFY(m_result_stack.empty());
|
||||||
TRACE("goal2sat", tout << "assert: " << mk_bounded_pp(n, m, 3) << "\n";);
|
TRACE("goal2sat", tout << "assert: " << mk_bounded_pp(n, m, 3) << "\n";);
|
||||||
process(n, true, m_is_redundant);
|
process(n, true);
|
||||||
CTRACE("goal2sat", !m_result_stack.empty(), tout << m_result_stack << "\n";);
|
CTRACE("goal2sat", !m_result_stack.empty(), tout << m_result_stack << "\n";);
|
||||||
SASSERT(m_result_stack.empty());
|
SASSERT(m_result_stack.empty());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue