From a17d4e68eb483145ed27a29e6a74cfb7cf47a7d4 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 4 Dec 2024 15:32:08 -0800 Subject: [PATCH] bugfix to elim_uncnstr to ensure nodes are created. Prepare smt_internalizer to replay unit literals Signed-off-by: Nikolaj Bjorner --- src/ast/expr_substitution.cpp | 5 +++-- src/ast/simplifiers/elim_unconstrained.cpp | 10 +++++++--- src/smt/smt_context.cpp | 4 ++-- src/smt/smt_internalizer.cpp | 14 +++++++++----- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/ast/expr_substitution.cpp b/src/ast/expr_substitution.cpp index 957b884fb..57cecc0b2 100644 --- a/src/ast/expr_substitution.cpp +++ b/src/ast/expr_substitution.cpp @@ -19,6 +19,7 @@ Notes: #include "util/ref_util.h" #include "ast/expr_substitution.h" #include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" typedef obj_map expr2proof; typedef obj_map expr2expr_dependency; @@ -58,8 +59,8 @@ expr_substitution::~expr_substitution() { } std::ostream& expr_substitution::display(std::ostream& out) { - for (auto & kv : m_subst) { - out << mk_pp(kv.m_key, m()) << " |-> " << mk_pp(kv.m_value, m()) << "\n"; + for (auto & [k, v] : m_subst) { + out << mk_bounded_pp(k, m()) << " |-> " << mk_bounded_pp(v, m()) << "\n"; } return out; } diff --git a/src/ast/simplifiers/elim_unconstrained.cpp b/src/ast/simplifiers/elim_unconstrained.cpp index 9ddee634a..4ed9f2f28 100644 --- a/src/ast/simplifiers/elim_unconstrained.cpp +++ b/src/ast/simplifiers/elim_unconstrained.cpp @@ -131,7 +131,9 @@ elim_unconstrained::~elim_unconstrained() { } bool elim_unconstrained::is_var_lt(int v1, int v2) const { - return get_node(v1).num_parents() < get_node(v2).num_parents(); + auto p1 = get_node(v1).num_parents(); + auto p2 = get_node(v2).num_parents(); + return p1 < p2; } void elim_unconstrained::eliminate() { @@ -287,8 +289,11 @@ void elim_unconstrained::init_nodes() { for (expr* e : subterms_postorder::all(terms)) { SASSERT(get_node(e).is_root()); - if (is_uninterp_const(e)) + + if (is_uninterp_const(e)) { + get_node(e); // ensure the node exists m_heap.insert(e->get_id()); + } } // mark top level terms @@ -390,7 +395,6 @@ void elim_unconstrained::update_model_trail(generic_model_converter& mc, vector< trail.hide(entry.m_f); break; case generic_model_converter::instruction::ADD: - // trail.push(entry.m_f, entry.m_def, nullptr, old_fmls); break; } } diff --git a/src/smt/smt_context.cpp b/src/smt/smt_context.cpp index b165e54a6..4c1ba3da7 100644 --- a/src/smt/smt_context.cpp +++ b/src/smt/smt_context.cpp @@ -2381,7 +2381,7 @@ namespace smt { unsigned i = units_to_reassert_lim; unsigned sz = m_units_to_reassert.size(); for (; i < sz; i++) { - auto& [unit, sign, is_relevant] = m_units_to_reassert[i]; + auto [unit, sign, is_relevant] = m_units_to_reassert[i]; bool gate_ctx = true; internalize(unit, gate_ctx); bool_var v = get_bool_var(unit); @@ -2389,7 +2389,7 @@ namespace smt { assign(l, b_justification::mk_axiom()); if (is_relevant) mark_as_relevant(l); - TRACE("reassert_units", tout << "reasserting #" << unit->get_id() << " " << sign << " @ " << m_scope_lvl << "\n";); + TRACE("reassert_units", tout << "reasserting #" << unit->get_id() << " " << sign << " @ " << m_scope_lvl << "\n";); } if (at_base_level()) m_units_to_reassert.reset(); diff --git a/src/smt/smt_internalizer.cpp b/src/smt/smt_internalizer.cpp index 9181c9025..f19144b62 100644 --- a/src/smt/smt_internalizer.cpp +++ b/src/smt/smt_internalizer.cpp @@ -1396,8 +1396,7 @@ namespace smt { DEBUG_CODE(for (literal lit : simp_lits) SASSERT(get_assignment(lit) == l_true);); if (!simp_lits.empty()) { j = mk_justification(unit_resolution_justification(*this, j, simp_lits.size(), simp_lits.data())); - } - + } break; } case CLS_TH_LEMMA: @@ -1423,6 +1422,7 @@ namespace smt { unsigned activity = 1; bool lemma = is_lemma(k); m_stats.m_num_mk_lits += num_lits; + switch (num_lits) { case 0: if (j && !j->in_region()) @@ -1431,12 +1431,16 @@ namespace smt { set_conflict(j == nullptr ? b_justification::mk_axiom() : b_justification(j)); SASSERT(inconsistent()); return nullptr; - case 1: + case 1: { + literal unit = lits[0]; + expr* atom = m_bool_var2expr[unit.var()]; if (j && !j->in_region()) m_justifications.push_back(j); - assign(lits[0], j); - inc_ref(lits[0]); + assign(unit, j); + inc_ref(unit); + // m_units_to_reassert.push_back({ expr_ref(atom, m), unit.sign(), is_relevant(unit) }); return nullptr; + } case 2: if (use_binary_clause_opt(lits[0], lits[1], lemma)) { literal l1 = lits[0];