@@ -178,8 +178,10 @@ namespace user_solver {
178
178
void solver::propagate_consequence (prop_info const & prop) {
179
179
sat::literal lit = ctx.internalize (prop.m_conseq , false , false );
180
180
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);
182
183
++m_stats.m_num_propagations ;
184
+ persist_clause (lit, j);
183
185
}
184
186
}
185
187
@@ -188,9 +190,17 @@ namespace user_solver {
188
190
}
189
191
190
192
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 () )
192
194
return false ;
193
195
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
+ }
194
204
ctx.push (value_trail<unsigned >(m_qhead));
195
205
unsigned np = m_stats.m_num_propagations ;
196
206
for (; m_qhead < m_prop.size () && !s ().inconsistent (); ++m_qhead) {
@@ -200,7 +210,37 @@ namespace user_solver {
200
210
else
201
211
propagate_new_fixed (prop);
202
212
}
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;
204
244
}
205
245
206
246
void solver::collect_statistics (::statistics& st) const {
0 commit comments