diff --git a/src/ast/rewriter/seq_axioms.cpp b/src/ast/rewriter/seq_axioms.cpp index bc3b6c66e..ab19a5586 100644 --- a/src/ast/rewriter/seq_axioms.cpp +++ b/src/ast/rewriter/seq_axioms.cpp @@ -1061,16 +1061,12 @@ namespace seq { // using iterative deepening can be re-used. // // create recursive relation 'ra' with properties: - // ra(s, p, t, r) <- s = "" && r = "" - // ra(s, p, t, r) <- s != "" && p = "" && r = t + s - // ra(s, p, t, r) <- s != "" && p + s' = s && t + r' = r && ra(s', p, t, r') - // ra(s, p, t, r) <- s = [s0] + s' && ~prefix(p, s) && r = [s0] + r' && ra(s', p, t, r') + // ra(i, j, s, p, t, r) <- len(s) = i && len(r) = j + // ra(i, j, s, p, t, r) <- len(s) > i = 0 && p = "" && r = t + s + // ra(i, j, s, p, t, r) <- len(s) > i && p != "" && s = extract(s, 0, i) + p + extract(s, i + len(p), len(s)) && r = extract(r, 0, i) + t + extract(r, i + len(p), len(r)) && ra(i + len(p), j + len(t), s, p, t, r) + // ra(i, s, p, t, r) <- ~prefix(p, extract(s, i, len(s)) && at(s,i) = at(r,j) && ra(i + 1, j + 1, s, p, t, r) // which amounts to: // - // s = "" -> r = "" - // p = "" -> r = t + s - // prefix(p, s) -> p + s' = s && t + r' = r && ra(s', p, t, r') - // else -> s = [s0] + s' && r = [s0] + r' && ra(s', p, t, r') // // Then assert // ra(s, p, t, replace_all(s, p, t)) @@ -1085,16 +1081,23 @@ namespace seq { sort* domain[4] = { srt, srt, srt, srt }; auto d = plugin.ensure_def(symbol("ra"), 4, domain, m.mk_bool_sort(), true); func_decl* ra = d.get_def()->get_decl(); + sort* isrt = a.mk_int(); + var_ref vi(m.mk_var(5, isrt), m); + var_ref vj(m.mk_var(4, isrt), m); var_ref vs(m.mk_var(3, srt), m); var_ref vp(m.mk_var(2, srt), m); var_ref vt(m.mk_var(1, srt), m); var_ref vr(m.mk_var(0, srt), m); - var* vars[4] = { vs, vp, vt, vr }; - expr_ref test1(seq.str.mk_is_empty(vs), m); - expr_ref branch1(seq.str.mk_is_empty(vr), m); - expr_ref test2(seq.str.mk_is_empty(vp), m); + var* vars[6] = { vi, vj, vs, vp, vt, vr }; + expr_ref len_s(seq.str.mk_length(vs), m); + expr_ref len_r(seq.str.mk_length(vr), m); + expr_ref test1(m.mk_eq(len_s, vi), m); + expr_ref branch1(m.mk_eq(len_r, vj), m); + expr_ref test2(m.mk_and(a.mk_gt(len_s, vi), m.mk_eq(vi, a.mk_int(0)), seq.str.mk_is_empty(vp)), m); expr_ref branch2(m.mk_eq(vr, seq.str.mk_concat(vt, vs)), m); - expr_ref test3(seq.str.mk_prefix(vp, vs), m); + NOT_IMPLEMENTED_YET(); +#if 0 + expr_ref test3(, m); expr_ref s1(m_sk.mk_prefix_inv(vp, vs), m); expr_ref r1(m_sk.mk_prefix_inv(vp, vr), m); expr* args1[4] = { s1, vp, vt, r1 }; @@ -1116,6 +1119,7 @@ namespace seq { expr* args3[4] = { s, p, t, r }; expr_ref lit(m.mk_app(ra, 4, args3), m); add_clause(lit); +#endif } void axioms::replace_re_all_axiom(expr* e) { diff --git a/src/sat/sat_solver.cpp b/src/sat/sat_solver.cpp index 286038dea..0e72de37f 100644 --- a/src/sat/sat_solver.cpp +++ b/src/sat/sat_solver.cpp @@ -3009,7 +3009,7 @@ namespace sat { svector logits(vars.size(), 0.0); double itau = m_config.m_reorder_itau; double lse = 0; - double mid = m_rand.max_value()/2; + double mid = (double)(m_rand.max_value()/2); double max = 0; for (double& f : logits) { f = itau * (m_rand() - mid)/mid; diff --git a/src/sat/smt/CMakeLists.txt b/src/sat/smt/CMakeLists.txt index dc7f73c93..3721963c8 100644 --- a/src/sat/smt/CMakeLists.txt +++ b/src/sat/smt/CMakeLists.txt @@ -21,7 +21,6 @@ z3_add_component(sat_smt euf_invariant.cpp euf_model.cpp euf_proof.cpp - euf_relevancy.cpp euf_solver.cpp fpa_solver.cpp pb_card.cpp @@ -38,7 +37,6 @@ z3_add_component(sat_smt q_queue.cpp q_solver.cpp recfun_solver.cpp - sat_dual_solver.cpp sat_th.cpp smt_relevant.cpp user_solver.cpp diff --git a/src/sat/smt/euf_internalize.cpp b/src/sat/smt/euf_internalize.cpp index 68f2295a2..d42a5a353 100644 --- a/src/sat/smt/euf_internalize.cpp +++ b/src/sat/smt/euf_internalize.cpp @@ -183,8 +183,6 @@ namespace euf { m_egraph.set_bool_var(n, v); if (m.is_eq(e) || m.is_or(e) || m.is_and(e) || m.is_not(e)) m_egraph.set_merge_enabled(n, false); - if (!si.is_bool_op(e)) - track_relevancy(lit.var()); if (s().value(lit) != l_undef) m_egraph.set_value(n, s().value(lit)); return lit; @@ -396,7 +394,7 @@ namespace euf { // Remark: The inconsistency is not going to be detected if they are // not marked as shared. - for (auto p : euf::enode_th_vars(n)) + for (auto const& p : euf::enode_th_vars(n)) if (fid2solver(p.get_id())->is_shared(p.get_var())) return true; diff --git a/src/sat/smt/euf_relevancy.cpp b/src/sat/smt/euf_relevancy.cpp deleted file mode 100644 index 07960c584..000000000 --- a/src/sat/smt/euf_relevancy.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/*++ -Copyright (c) 2020 Microsoft Corporation - -Module Name: - - euf_relevancy.cpp - -Abstract: - - Features for relevancy tracking. - A reduced (minimal) implicant is extracted by running a dual solver. - Then the literals in the implicant are used as a basis for marking - subterms relevant. - -Author: - - Nikolaj Bjorner (nbjorner) 2020-09-22 - ---*/ - -#include "sat/smt/euf_solver.h" - -namespace euf { - - void solver::mark_relevant(sat::literal lit) { - if (m_relevancy.enabled()) { - m_relevancy.mark_relevant(lit); - return; - } - if (!relevancy_enabled()) - return; - for (; m_auto_relevant_scopes > 0; --m_auto_relevant_scopes) - m_auto_relevant_lim.push_back(m_auto_relevant.size()); - expr* e = bool_var2expr(lit.var()); - m_auto_relevant.push_back(e); - } - - void solver::pop_relevant(unsigned n) { - if (m_relevancy.enabled()) { - m_relevancy.pop(n); - return; - } - if (m_auto_relevant_scopes >= n) { - m_auto_relevant_scopes -= n; - return; - } - n -= m_auto_relevant_scopes; - m_auto_relevant_scopes = 0; - unsigned top = m_auto_relevant_lim.size() - n; - unsigned lim = m_auto_relevant_lim[top]; - m_auto_relevant_lim.shrink(top); - m_auto_relevant.shrink(lim); - } - - void solver::push_relevant() { - if (m_relevancy.enabled()) { - m_relevancy.push(); - return; - } - ++m_auto_relevant_scopes; - } - - bool solver::is_relevant(enode* n) const { - if (m_relevancy.enabled()) - return m_relevancy.is_relevant(n); - return m_relevant_expr_ids.get(n->get_expr_id(), true); - } - - bool solver::is_relevant(bool_var v) const { - if (m_relevancy.enabled()) - return m_relevancy.is_relevant(v); - auto* e = bool_var2enode(v); - return !e || is_relevant(e); - } - - void solver::ensure_dual_solver() { - if (m_relevancy.enabled()) - return; - if (m_dual_solver) - return; - m_dual_solver = alloc(sat::dual_solver, s(), s().rlimit()); - for (unsigned i = s().num_user_scopes(); i-- > 0; ) - m_dual_solver->push(); - } - - /** - * Add a root clause. Root clauses must all be satisfied by the - * final assignment. If a clause is added above search level it - * is subject to removal on backtracking. These clauses are therefore - * not tracked. - */ - void solver::add_root(unsigned n, sat::literal const* lits) { - if (m_relevancy.enabled()) { - m_relevancy.add_root(n, lits); - return; - } - if (!relevancy_enabled()) - return; - ensure_dual_solver(); - m_dual_solver->add_root(n, lits); - } - - void solver::add_aux(unsigned n, sat::literal const* lits) { - if (m_relevancy.enabled()) { - m_relevancy.add_def(n, lits); - return; - } - if (!relevancy_enabled()) - return; - ensure_dual_solver(); - m_dual_solver->add_aux(n, lits); - } - - void solver::track_relevancy(sat::bool_var v) { - if (m_relevancy.enabled()) - return; - ensure_dual_solver(); - m_dual_solver->track_relevancy(v); - } - - bool solver::init_relevancy() { - if (m_relevancy.enabled()) - return true; - m_relevant_expr_ids.reset(); - if (!relevancy_enabled()) - return true; - if (!m_dual_solver) - return true; - if (!(*m_dual_solver)()) - return false; - init_relevant_expr_ids(); - - for (auto lit : m_dual_solver->core()) - push_relevant(lit.var()); - - relevant_subterms(); - - return true; - } - - void solver::push_relevant(sat::bool_var v) { - SASSERT(!m_relevancy.enabled()); - expr* e = m_bool_var2expr.get(v, nullptr); - if (e) - m_relevant_todo.push_back(e); - } - - bool solver::is_propagated(sat::literal lit) { - SASSERT(!m_relevancy.enabled()); - return s().value(lit) == l_true && !s().get_justification(lit.var()).is_none(); - } - - void solver::init_relevant_expr_ids() { - SASSERT(!m_relevancy.enabled()); - unsigned max_id = 0; - for (enode* n : m_egraph.nodes()) - max_id = std::max(max_id, n->get_expr_id()); - m_relevant_expr_ids.resize(max_id + 1, false); - m_relevant_todo.reset(); - m_relevant_todo.append(m_auto_relevant); - } - - void solver::relevant_subterms() { - SASSERT(!m_relevancy.enabled()); - ptr_vector& todo = m_relevant_todo; - bool_vector& visited = m_relevant_visited; - for (unsigned i = 0; i < todo.size(); ++i) { - expr* e = todo[i]; - if (visited.get(e->get_id(), false)) - continue; - visited.setx(e->get_id(), true, false); - if (si.is_bool_op(e)) - continue; - else - m_relevant_expr_ids.setx(e->get_id(), true, false); - if (!is_app(e)) - continue; - expr* c = nullptr, *th = nullptr, *el = nullptr; - if (m.is_ite(e, c, th, el) && get_enode(c)) { - sat::literal lit = expr2literal(c); - todo.push_back(c); - switch (s().value(lit)) { - case l_true: - todo.push_back(th); - break; - case l_false: - todo.push_back(el); - break; - default: - todo.push_back(th); - todo.push_back(el); - break; - } - continue; - } - for (expr* arg : *to_app(e)) - todo.push_back(arg); - } - - for (auto * e : todo) - visited[e->get_id()] = false; - - TRACE("euf", - for (enode* n : m_egraph.nodes()) - if (is_relevant(n)) - tout << "relevant " << n->get_expr_id() << " [r" << n->get_root_id() << "]: " << mk_bounded_pp(n->get_expr(), m) << "\n";); - } -} diff --git a/src/sat/smt/euf_solver.cpp b/src/sat/smt/euf_solver.cpp index f6d6e73dd..79b86e9a9 100644 --- a/src/sat/smt/euf_solver.cpp +++ b/src/sat/smt/euf_solver.cpp @@ -479,9 +479,6 @@ namespace euf { if (unit_propagate()) return sat::check_result::CR_CONTINUE; - - if (!init_relevancy()) - give_up = true; unsigned num_nodes = m_egraph.num_nodes(); auto apply_solver = [&](th_solver* e) { @@ -546,9 +543,7 @@ namespace euf { for (auto* e : m_solvers) e->push(); m_egraph.push(); - if (m_dual_solver) - m_dual_solver->push(); - push_relevant(); + m_relevancy.push(); } void solver::pop(unsigned n) { @@ -558,7 +553,7 @@ namespace euf { e->pop(n); si.pop(n); m_egraph.pop(n); - pop_relevant(n); + m_relevancy.pop(n); scope const & sc = m_scopes[m_scopes.size() - n]; for (unsigned i = m_var_trail.size(); i-- > sc.m_var_lim; ) { bool_var v = m_var_trail[i]; @@ -567,8 +562,6 @@ namespace euf { } m_var_trail.shrink(sc.m_var_lim); m_scopes.shrink(m_scopes.size() - n); - if (m_dual_solver) - m_dual_solver->pop(n); SASSERT(m_egraph.num_scopes() == m_scopes.size()); TRACE("euf_verbose", display(tout << "pop to: " << m_scopes.size() << "\n");); } @@ -741,6 +734,13 @@ namespace euf { } } + bool solver::is_relevant(bool_var v) const { + if (m_relevancy.enabled()) + return m_relevancy.is_relevant(v); + auto* e = bool_var2enode(v); + return !e || is_relevant(e); + } + void solver::relevant_eh(euf::enode* n) { if (m_qsolver) m_qsolver->relevant_eh(n); diff --git a/src/sat/smt/euf_solver.h b/src/sat/smt/euf_solver.h index 12afc492f..77fce4a20 100644 --- a/src/sat/smt/euf_solver.h +++ b/src/sat/smt/euf_solver.h @@ -25,7 +25,6 @@ Author: #include "sat/sat_extension.h" #include "sat/smt/atom2bool_var.h" #include "sat/smt/sat_th.h" -#include "sat/smt/sat_dual_solver.h" #include "sat/smt/euf_ackerman.h" #include "sat/smt/user_solver.h" #include "sat/smt/smt_relevant.h" @@ -184,14 +183,11 @@ namespace euf { void init_drat(); // relevancy - bool_vector m_relevant_expr_ids; - bool_vector m_relevant_visited; - ptr_vector m_relevant_todo; - void ensure_dual_solver(); - bool init_relevancy(); - void relevant_subterms(); - void init_relevant_expr_ids(); - void push_relevant(sat::bool_var v); + //bool_vector m_relevant_expr_ids; + //bool_vector m_relevant_visited; + //ptr_vector m_relevant_todo; + //void init_relevant_expr_ids(); + //void push_relevant(sat::bool_var v); bool is_propagated(sat::literal lit); // invariant void check_eqc_bool_assignment() const; @@ -376,29 +372,26 @@ namespace euf { // relevancy bool m_relevancy_enabled = true; - scoped_ptr m_dual_solver; ptr_vector m_auto_relevant; unsigned_vector m_auto_relevant_lim; unsigned m_auto_relevant_scopes = 0; bool relevancy_enabled() const { return m_relevancy_enabled && get_config().m_relevancy_lvl > 0; } void disable_relevancy(expr* e) { IF_VERBOSE(0, verbose_stream() << "disabling relevancy " << mk_pp(e, m) << "\n"); m_relevancy_enabled = false; } - void add_root(unsigned n, sat::literal const* lits); + void add_root(unsigned n, sat::literal const* lits) { m_relevancy.add_root(n, lits); } void add_root(sat::literal_vector const& lits) { add_root(lits.size(), lits.data()); } void add_root(sat::literal lit) { add_root(1, &lit); } void add_aux(sat::literal_vector const& lits) { add_aux(lits.size(), lits.data()); } - void add_aux(unsigned n, sat::literal const* lits); + void add_aux(unsigned n, sat::literal const* lits) { m_relevancy.add_def(n, lits); } void add_aux(sat::literal a) { sat::literal lits[1] = { a }; add_aux(1, lits); } void add_aux(sat::literal a, sat::literal b) { sat::literal lits[2] = {a, b}; add_aux(2, lits); } void add_aux(sat::literal a, sat::literal b, sat::literal c) { sat::literal lits[3] = { a, b, c }; add_aux(3, lits); } - void track_relevancy(sat::bool_var v); - bool is_relevant(enode* n) const; + void mark_relevant(sat::literal lit) { m_relevancy.mark_relevant(lit); } + bool is_relevant(enode* n) const { return m_relevancy.is_relevant(n); } bool is_relevant(bool_var v) const; bool is_relevant(sat::literal lit) const { return is_relevant(lit.var()); } - void mark_relevant(sat::literal lit); - void pop_relevant(unsigned n); - void push_relevant(); void relevant_eh(euf::enode* n); + smt::relevancy& relevancy() { return m_relevancy; } // model construction diff --git a/src/sat/smt/sat_dual_solver.cpp b/src/sat/smt/sat_dual_solver.cpp deleted file mode 100644 index d4b93b90c..000000000 --- a/src/sat/smt/sat_dual_solver.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/*++ -Copyright (c) 2020 Microsoft Corporation - -Module Name: - - sat_dual_solver.cpp - -Abstract: - - Solver for obtaining implicant. - -Author: - - Nikolaj Bjorner (nbjorner) 2020-08-25 - ---*/ -#include "sat/smt/sat_dual_solver.h" - -namespace sat { - - dual_solver::dual_solver(solver& s, reslimit& l): - s(s), - m_solver(m_params, l) - { - SASSERT(!m_solver.get_config().m_drat); - m_solver.set_incremental(true); - } - - void dual_solver::flush() { - while (m_num_scopes > 0) { - m_solver.user_push(); - m_roots.push_scope(); - m_tracked_vars.push_scope(); - m_units.push_scope(); - m_vars.push_scope(); - --m_num_scopes; - } - } - - void dual_solver::push() { - ++m_num_scopes; - } - - void dual_solver::pop(unsigned num_scopes) { - if (m_num_scopes >= num_scopes) { - m_num_scopes -= num_scopes; - return; - } - num_scopes -= m_num_scopes; - m_num_scopes = 0; - m_solver.user_pop(num_scopes); - unsigned old_sz = m_tracked_vars.old_size(num_scopes); - for (unsigned i = m_tracked_vars.size(); i-- > old_sz; ) - m_is_tracked[m_tracked_vars[i]] = false; - old_sz = m_vars.old_size(num_scopes); - for (unsigned i = m_vars.size(); i-- > old_sz; ) { - unsigned v = m_vars[i]; - unsigned w = m_ext2var[v]; - m_ext2var[v] = null_bool_var; - m_var2ext[w] = null_bool_var; - } - m_vars.pop_scope(num_scopes); - m_units.pop_scope(num_scopes); - m_roots.pop_scope(num_scopes); - m_tracked_vars.pop_scope(num_scopes); - } - - bool_var dual_solver::ext2var(bool_var v) { - bool_var w = m_ext2var.get(v, null_bool_var); - if (null_bool_var == w) { - w = m_solver.mk_var(); - m_solver.set_external(w); - s.set_external(v); - m_ext2var.setx(v, w, null_bool_var); - m_var2ext.setx(w, v, null_bool_var); - m_vars.push_back(v); - } - return w; - } - - void dual_solver::track_relevancy(bool_var w) { - flush(); - bool_var v = ext2var(w); - if (!m_is_tracked.get(v, false)) { - m_is_tracked.setx(v, true, false); - m_tracked_vars.push_back(v); - } - } - - literal dual_solver::ext2lit(literal lit) { - return literal(ext2var(lit.var()), lit.sign()); - } - - literal dual_solver::lit2ext(literal lit) { - return literal(m_var2ext[lit.var()], lit.sign()); - } - - void dual_solver::add_root(unsigned sz, literal const* clause) { - flush(); - if (false && sz == 1) { - TRACE("dual", tout << "unit: " << clause[0] << "\n";); - m_units.push_back(clause[0]); - return; - } - literal root; - if (sz == 1) - root = ext2lit(clause[0]); - else { - root = literal(m_solver.mk_var(), false); - for (unsigned i = 0; i < sz; ++i) - m_solver.mk_clause(root, ~ext2lit(clause[i]), status::input()); - } - m_solver.set_external(root.var()); - m_roots.push_back(~root); - TRACE("dual", tout << "root: " << ~root << " => " << literal_vector(sz, clause) << "\n";); - } - - void dual_solver::add_aux(unsigned sz, literal const* clause) { - flush(); - m_lits.reset(); - for (unsigned i = 0; i < sz; ++i) - m_lits.push_back(ext2lit(clause[i])); - TRACE("dual", tout << "aux: " << literal_vector(sz, clause) << " -> " << m_lits << "\n";); - m_solver.mk_clause(sz, m_lits.data(), status::input()); - } - - void dual_solver::add_assumptions() { - flush(); - m_lits.reset(); - for (bool_var v : m_tracked_vars) - m_lits.push_back(literal(v, l_false == s.value(m_var2ext[v]))); - for (auto lit : m_units) { - bool_var w = m_ext2var.get(lit.var(), null_bool_var); - if (w != null_bool_var) - m_lits.push_back(ext2lit(lit)); - } - } - - bool dual_solver::operator()() { - m_core.reset(); - m_core.append(m_units); - if (m_roots.empty()) - return true; - m_solver.user_push(); - m_solver.add_clause(m_roots.size(), m_roots.data(), status::input()); - add_assumptions(); - lbool is_sat = m_solver.check(m_lits.size(), m_lits.data()); - if (is_sat == l_false) - for (literal lit : m_solver.get_core()) - m_core.push_back(lit2ext(lit)); - if (is_sat == l_true) { - TRACE("dual", display(tout); s.display(tout);); - IF_VERBOSE(0, verbose_stream() << "unexpected SAT\n"); - IF_VERBOSE(0, verbose_stream() << "assumptions: " << m_lits << "\n"); - IF_VERBOSE(0, display(verbose_stream()); s.display(verbose_stream());); - UNREACHABLE(); - return false; - } - TRACE("dual", m_solver.display(tout << "is-sat: " << is_sat << " core: " << m_core << "\n");); - m_solver.user_pop(1); - return is_sat == l_false; - } - - std::ostream& dual_solver::display(std::ostream& out) const { - 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 || v2 == l_undef) - continue; - out << "ext: " << w << " " << v2 << "\n"; - out << "int: " << v << " " << v1 << "\n"; - } - literal_vector lits; - for (bool_var v : m_tracked_vars) - lits.push_back(literal(m_var2ext[v], l_false == s.value(m_var2ext[v]))); - out << "tracked: " << lits << "\n"; - lits.reset(); - for (literal r : m_roots) - if (m_solver.value(r) == l_true) - lits.push_back(r); - out << "roots: " << lits << "\n"; - m_solver.display(out); - - return out; - } -} diff --git a/src/sat/smt/sat_dual_solver.h b/src/sat/smt/sat_dual_solver.h deleted file mode 100644 index d9b43f7af..000000000 --- a/src/sat/smt/sat_dual_solver.h +++ /dev/null @@ -1,84 +0,0 @@ -/*++ -Copyright (c) 2020 Microsoft Corporation - -Module Name: - - sat_dual_solver.h - -Abstract: - - Solver for obtaining implicant. - Based on an idea by Armin Biere to use dual propagation - for representation of negated goal. - -Author: - - Nikolaj Bjorner (nbjorner) 2020-08-25 - ---*/ -#pragma once -#include "util/lim_vector.h" -#include "sat/sat_solver.h" - -namespace sat { - - class dual_solver { - class dual_params : public no_drat_params { - public: - dual_params() { - set_bool("core.minimize", false); - } - }; - solver& s; - dual_params m_params; - solver m_solver; - lim_svector m_units, m_roots; - lim_svector m_tracked_vars; - literal_vector m_lits, m_core; - bool_var_vector m_is_tracked; - unsigned_vector m_ext2var; - unsigned_vector m_var2ext; - lim_svector m_vars; - unsigned m_num_scopes = 0; - void add_literal(literal lit); - - bool_var ext2var(bool_var v); - bool_var var2ext(bool_var v); - literal ext2lit(literal lit); - literal lit2ext(literal lit); - - void add_assumptions(); - - std::ostream& display(std::ostream& out) const; - - void flush(); - - public: - dual_solver(solver& s, reslimit& l); - void push(); - void pop(unsigned num_scopes); - - /* - * track model relevancy for variable - */ - void track_relevancy(bool_var v); - - /* - * Add a root clause from the input problem. - * At least one literal has to be satisfied in every root. - */ - void add_root(unsigned sz, literal const* clause); - - /* - * Add auxiliary clauses that originate from compiling definitions. - */ - void add_aux(unsigned sz, literal const* clause); - - /* - * Extract a minimized subset of relevant literals from a model for s. - */ - bool operator()(); - - literal_vector const& core() const { return m_core; } - }; -} diff --git a/src/sat/smt/smt_relevant.cpp b/src/sat/smt/smt_relevant.cpp index a037090a2..87a85f61b 100644 --- a/src/sat/smt/smt_relevant.cpp +++ b/src/sat/smt/smt_relevant.cpp @@ -44,6 +44,8 @@ namespace smt { } void relevancy::pop(unsigned n) { + if (!m_enabled) + return; if (n <= m_num_scopes) { m_num_scopes -= n; return; @@ -55,7 +57,7 @@ namespace smt { SASSERT(n > 0); unsigned sz = m_lim[m_lim.size() - n]; for (unsigned i = m_trail.size(); i-- > sz; ) { - auto [u, idx] = m_trail[i]; + auto const& [u, idx] = m_trail[i]; switch (u) { case update::relevant_var: m_relevant_var_ids[idx] = false; @@ -168,7 +170,7 @@ namespace smt { return; m_trail.push_back(std::make_pair(update::set_qhead, m_qhead)); while (m_qhead < m_queue.size() && !ctx.s().inconsistent() && ctx.get_manager().inc()) { - auto [lit, n] = m_queue[m_qhead++]; + auto const& [lit, n] = m_queue[m_qhead++]; SASSERT(n || lit != sat::null_literal); SASSERT(!n || lit == sat::null_literal); if (n) diff --git a/src/sat/smt/smt_relevant.h b/src/sat/smt/smt_relevant.h index 723cf613a..e27694ae2 100644 --- a/src/sat/smt/smt_relevant.h +++ b/src/sat/smt/smt_relevant.h @@ -137,7 +137,7 @@ namespace smt { public: relevancy(euf::solver& ctx); - void push() { ++m_num_scopes; } + void push() { if (m_enabled) ++m_num_scopes; } void pop(unsigned n); void add_root(unsigned n, sat::literal const* lits); diff --git a/src/sat/tactic/goal2sat.cpp b/src/sat/tactic/goal2sat.cpp index e3386b4e2..a6d5625ee 100644 --- a/src/sat/tactic/goal2sat.cpp +++ b/src/sat/tactic/goal2sat.cpp @@ -186,8 +186,6 @@ struct goal2sat::imp : public sat::sat_internalizer { return v; v = m_solver.add_var(is_ext); log_def(v, n); - if (top_level_relevant() && !is_bool_op(n)) - ensure_euf()->track_relevancy(v); return v; } @@ -216,10 +214,6 @@ struct goal2sat::imp : public sat::sat_internalizer { if (!m_expr2var_replay || !m_expr2var_replay->find(t, v)) v = add_var(true, t); m_map.insert(t, v); - if (relevancy_enabled() && (m.is_true(t) || m.is_false(t))) { - add_dual_root(sat::literal(v, m.is_false(t))); - ensure_euf()->track_relevancy(v); - } return v; } @@ -678,8 +672,6 @@ struct goal2sat::imp : public sat::sat_internalizer { } if (lit == sat::null_literal) return; - if (top_level_relevant()) - euf->track_relevancy(lit.var()); if (root) mk_root_clause(lit); else diff --git a/src/sat/tactic/sat_tactic.cpp b/src/sat/tactic/sat_tactic.cpp index 892a88f89..ef9c1f4f2 100644 --- a/src/sat/tactic/sat_tactic.cpp +++ b/src/sat/tactic/sat_tactic.cpp @@ -135,6 +135,7 @@ class sat_tactic : public tactic { ref mc; m_sat2goal(*m_solver, map, m_params, *(g.get()), mc); g->add(mc.get()); + g->display(std::cout); if (produce_core || m_goal2sat.has_interpreted_funs()) { // sat2goal does not preseve assumptions or assignments to interpreted atoms g->updt_prec(goal::OVER);