Skip to content

Commit 7970e4f

Browse files
add clause persistence to sat/smt solver
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
1 parent 3cec3fc commit 7970e4f

File tree

2 files changed

+48
-3
lines changed

2 files changed

+48
-3
lines changed

src/sat/smt/user_solver.cpp

+43-3
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,10 @@ namespace user_solver {
178178
void solver::propagate_consequence(prop_info const& prop) {
179179
sat::literal lit = ctx.internalize(prop.m_conseq, false, false);
180180
if (s().value(lit) != l_true) {
181-
s().assign(lit, mk_justification(m_qhead));
181+
auto j = mk_justification(m_qhead);
182+
s().assign(lit, j);
182183
++m_stats.m_num_propagations;
184+
persist_clause(lit, j);
183185
}
184186
}
185187

@@ -188,9 +190,17 @@ namespace user_solver {
188190
}
189191

190192
bool solver::unit_propagate() {
191-
if (m_qhead == m_prop.size())
193+
if (m_qhead == m_prop.size() && m_replay_qhead == m_clauses_to_replay.size())
192194
return false;
193195
force_push();
196+
197+
bool replayed = false;
198+
if (m_replay_qhead < m_clauses_to_replay.size()) {
199+
replayed = true;
200+
ctx.push(value_trail<unsigned>(m_replay_qhead));
201+
for (; m_replay_qhead < m_clauses_to_replay.size(); ++m_replay_qhead)
202+
replay_clause(m_clauses_to_replay.get(m_replay_qhead));
203+
}
194204
ctx.push(value_trail<unsigned>(m_qhead));
195205
unsigned np = m_stats.m_num_propagations;
196206
for (; m_qhead < m_prop.size() && !s().inconsistent(); ++m_qhead) {
@@ -200,7 +210,37 @@ namespace user_solver {
200210
else
201211
propagate_new_fixed(prop);
202212
}
203-
return np < m_stats.m_num_propagations;
213+
return np < m_stats.m_num_propagations || replayed;
214+
}
215+
216+
void solver::replay_clause(expr_ref_vector const& clause) {
217+
sat::literal_vector lits;
218+
for (expr* e : clause)
219+
lits.push_back(ctx.mk_literal(e));
220+
add_clause(lits);
221+
}
222+
223+
void solver::persist_clause(sat::literal lit, sat::justification const& sj) {
224+
if (!ctx.get_config().m_up_persist_clauses)
225+
return;
226+
227+
expr_ref_vector clause(m);
228+
auto idx = sj.get_ext_justification_idx();
229+
auto& j = justification::from_index(idx);
230+
auto const& prop = m_prop[j.m_propagation_index];
231+
sat::literal_vector r;
232+
for (unsigned id : prop.m_ids)
233+
r.append(m_id2justification[id]);
234+
for (auto lit : r)
235+
clause.push_back(ctx.literal2expr(~lit));
236+
for (auto const& [a,b] : prop.m_eqs)
237+
clause.push_back(m.mk_not(m.mk_eq(a, b)));
238+
clause.push_back(ctx.literal2expr(lit));
239+
240+
m_clauses_to_replay.push_back(clause);
241+
if (m_replay_qhead + 1 < m_clauses_to_replay.size())
242+
std::swap(m_clauses_to_replay[m_replay_qhead], m_clauses_to_replay[m_clauses_to_replay.size()-1]);
243+
++m_replay_qhead;
204244
}
205245

206246
void solver::collect_statistics(::statistics& st) const {

src/sat/smt/user_solver.h

+5
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ namespace user_solver {
7777
stats m_stats;
7878
sat::bool_var m_next_split_var = sat::null_bool_var;
7979
lbool m_next_split_phase = l_undef;
80+
vector<expr_ref_vector> m_clauses_to_replay;
81+
unsigned m_replay_qhead = 0;
8082

8183
struct justification {
8284
unsigned m_propagation_index { 0 };
@@ -105,6 +107,9 @@ namespace user_solver {
105107

106108
sat::bool_var enode_to_bool(euf::enode* n, unsigned idx);
107109

110+
void replay_clause(expr_ref_vector const& clause);
111+
void persist_clause(sat::literal lit, sat::justification const& j);
112+
108113
public:
109114
solver(euf::solver& ctx);
110115

0 commit comments

Comments
 (0)