GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/prop/sat_proof_manager.h Lines: 1 1 100.0 %
Date: 2021-08-17 Branches: 0 0 0.0 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Haniel Barbosa, Gereon Kremer
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8
 * in the top-level source directory and their institutional affiliations.
9
 * All rights reserved.  See the file COPYING in the top-level source
10
 * directory for licensing information.
11
 * ****************************************************************************
12
 *
13
 * The proof manager for Minisat.
14
 */
15
16
#include "cvc5_private.h"
17
18
#ifndef CVC5__SAT_PROOF_MANAGER_H
19
#define CVC5__SAT_PROOF_MANAGER_H
20
21
#include "context/cdhashset.h"
22
#include "expr/node.h"
23
#include "proof/buffered_proof_generator.h"
24
#include "proof/lazy_proof_chain.h"
25
#include "prop/minisat/core/SolverTypes.h"
26
#include "prop/sat_solver_types.h"
27
28
namespace Minisat {
29
class Solver;
30
}
31
32
namespace cvc5 {
33
34
class ProofNodeManager;
35
36
namespace prop {
37
38
class CnfStream;
39
40
/**
41
 * This class is responsible for managing the proof production of the SAT
42
 * solver. It tracks resolutions produced during solving and stores them,
43
 * independently, with the connection of the resolutions only made when the
44
 * empty clause is produced and the refutation is complete. The expected
45
 * assumptions of the refutation are the clausified preprocessed assertions and
46
 * lemmas.
47
 *
48
 * These resolutions are stored in a LazyCDProofChain, a user-context-dependent
49
 * proof that takes lazy steps and can connect them when generating a proof for
50
 * a given fact. Its use in this proof manager is so that, assuming the
51
 * following lazy steps are saved in the LazyCDProofChain:
52
 *
53
 * --- S0: (l4,          PG0)
54
 * --- S1: ((or l3 l4),  PG1)
55
 * --- S2: ((or l1 ~l3), PG2)
56
 * --- S3: (false,       PG3)
57
 * --- S4: (~l2,         PG4)
58
 * --- S5: (~l3,         PG5)
59
 * --- S6: (~l5,         PG6)
60
 *
61
 * when requesting the proof of false, assuming that the proof generators have
62
 * the following expansions:
63
 *
64
 * --- PG0 -> (CHAIN_RES ((or l4 l1) ~l1))
65
 * --- PG1 -> (CHAIN_RES ((or l3 l5 l6 l7) ~l5 (or ~l6 l7) (or l4 ~l7)))
66
 * --- PG2 -> (CHAIN_RES ((or l1 ~l3 l5) ~l5))
67
 * --- PG3 -> (CHAIN_RES ((or l1 l2) ~l1 ~l2))
68
 * --- PG4 -> (CHAIN_RES ((or l3 ~l2) ~l3))
69
 * --- PG5 -> (CHAIN_RES ((or l1 ~l3) ~l1))
70
 * --- PG6 -> (CHAIN_RES ((or l1 ~l5) ~l1))
71
 *
72
 * will connect the independent resolutions and yield the following refutation
73
 *
74
 *                                             (or l1 ~l5)  ~l1
75
 *                                             ---------------- CHAIN_RES
76
 *                            (or l1 ~l3 l5)   ~l5
77
 *                            ---------------------- CHAIN_RES
78
 *                                      (or l1 ~l3)              ~l1
79
 *                                      ----------------------------- CHAIN_RES
80
 *                       (or l3 ~l2)     ~l3
81
 *                       -------------------- CHAIN_RES
82
 *   (or l1 l2)   ~l1    ~l2
83
 *  --------------------------- CHAIN_RES
84
 *              false
85
 *
86
 * where note that the steps S0 and S1, for l4 and (or l3 l4), respectively,
87
 * were ignored, since they were not part of the chain starting with
88
 * false. Moreover there is no requirement that the steps are registered
89
 * chronologically in the LazyCDProofChain. The chain started on step S3 and
90
 * proceeded to steps S4, S5, S2, and finally S6.
91
 *
92
 * To track the reasoning of the SAT solver and produce the steps above this
93
 * class does three main things:
94
 *  (1) Register the resolutions for learned clauses as they are learned.
95
 *  (2) Register the resolutions for propagated literals when necessary.
96
 *  (3) Register the *full* resolution proof for the empty clause.
97
 *
98
 * Case (1) covers the learned clauses during backjumping. The only information
99
 * saved is that, from clauses C1 to Cn, a given learned clause C is derived via
100
 * chain resolution (and possibly factoring, reordering and double negation
101
 * elimination in its literals), i.e., we do not recursively prove C1 to Cn at
102
 * this moment.
103
 *
104
 * Not explaining C1 to Cn eagerly is beneficial because:
105
 * - we might be wasting resources in fully explanaining it now, since C may not
106
 *   be necessary for the derivation of the empty clause, and
107
 * - in explaining clauses lazily we might have shorter explanations, which has
108
 *   been observed empirically to be often the case.
109
 *
110
 * The latter case is a result of the SAT solver possibly changing the
111
 * explanation of each of C, C1 to Cn, or the components of their
112
 * explanations. This is because the set of propagated literals that may be used
113
 * in these explanations can change in different SAT contexts, with the same
114
 * clause being derived several times, each from a different set of clauses.
115
 *
116
 * Therefore we only fully explain a clause when absolutely necessary, i.e.,
117
 * when we are done (see case (3)) or when we'd not be able to do it afterwards
118
 * (see case (2)). In the example above, step S2 is generated from case (1),
119
 * with the shallow proof
120
 *
121
 *        (or l1 ~l3 l5)       ~l5
122
 *        ------------------------- CHAIN_RES
123
 *                 (or l1 ~l3)
124
 *
125
 * explaining the learned clause (or l1 ~l3). Its full proof would only be
126
 * produced if it were part of the final refutation, as it indeed is. Note that
127
 * in the example above the refutation proof contains the resolution proof of
128
 * ~l5.
129
 *
130
 * Case (2) covers:
131
 *  (2.1) propagated literals explained by clauses being deleted
132
 *  (2.2) propagated literals whose negation occurs in a learned clause, which
133
 *  are then deleted for being redundant.
134
 *
135
 * Case (2.1) only happens for the so-called "locked clauses", which are clauses
136
 * C = l1 v ... v ln that propagate their first literal, l1. When a locked
137
 * clause C is deleted we save a chain resolution proof of l1 because we'd not
138
 * be able to retrieve C afterwards, since it is deleted. The proof is a chain
139
 * resolution step between C and ~l2, ..., ~ln, concluding l1. In the example
140
 * above, step S0 is generated from case (2.1), with the locked clause (or l4
141
 * l1) being deleted and requiring the registration in the LazyCDPRoofChain of a
142
 * lazy step for
143
 *
144
 *         (or l4 l1)       ~l1
145
 *      ------------------------- CHAIN_RES
146
 *               l4
147
 *
148
 * Case (2.2) requires that, when a redundant literal (i.e., a literal whose
149
 * negation is propagated) is deleted from a learned clause, we add the
150
 * explanation of its negation to the chain resolution proof of the learned
151
 * clause. This justifies the deletion of the redundant literal. However, the
152
 * explanation for the propagated literal (the SAT solver maintains a map from
153
 * propagated literals to the clauses that propagate them in the current
154
 * context, i.e., their explanations, clauses in which all literals but the
155
 * propagated one have their negation propagated) may also contain literals that
156
 * were in the learned clause and were deleted for being redundant. Therefore
157
 * eliminating a redundant literal requires recursively explaining the
158
 * propagated literals in its explanation as long as they are, themselves,
159
 * redundant literals in the learned clause.
160
 *
161
 * In the above example step S1, concluding (or l3 l4), is generated from the
162
 * resolutions
163
 *
164
 *   (or l3 l5 l6 l7)    ~l5
165
 *  -------------------------- CHAIN_RES
166
 *     (or l3 l6 l7)                        (or ~l6 l7)   (or l4 ~l7)
167
 *    ---------------------------------------------------------------- CHAIN_RES
168
 *                           (or l3 l4)
169
 *
170
 * as l6 and l7 are redundant, which leads to (or l3 l6 l7) being resolved with
171
 * l6's explanation, (or ~l6 l7). The literals in the explanation of l7 are
172
 * recursively explained if they are also redundant, which is the case for l7,
173
 * so its explanation is also added as premise for the resolution. Since l4 is
174
 * not redundant, it is not recursively explained.
175
 *
176
 * Note that the actual proof generated does not have the intermediary step
177
 * before removing redundant literals. It's all done in one fell swoop:
178
 *
179
 *   (or l3 l5 l6 l7)   ~l5   (or ~l6 l7)   (or l4 ~l7)
180
 *   --------------------------------------------------- CHAIN_RES
181
 *                           (or l3 l4)
182
 *
183
 * Finally, case (3) happens when the SAT solver derives the empty clause and
184
 * it's not possible to backjump. The empty clause is learned from a conflict
185
 * clause: a clause whose every literal has its negation propagated in the
186
 * current context. Thus the proof of the empty clause is generated, at first,
187
 * in the same way as case (1): a resolution chain betweeen the conflict clause
188
 * and its negated literals. However, since we are now done, we recursively
189
 * explain the propagated literals, starting from the negated literals from the
190
 * conflict clause and progressing to all propagated literals ocurring in a
191
 * given explanation.
192
 *
193
 * In the above example this happens as: step S3
194
 *
195
 *    (or l1 l2)   ~l1    ~l2
196
 *  --------------------------- CHAIN_RES
197
 *             false
198
 *
199
 * is added for a conflict clause (or l1 l2). Then we attempt to explain ~l1 and
200
 * ~l2. The former has no explanation (i.e., it's an input), while the latter
201
 * has explanation (or l3 ~l2). This leads to step S4
202
 *
203
 *  (or l3 ~l2)     ~l3
204
 *  -------------------- CHAIN_RES
205
 *        ~l2
206
 *
207
 * being added to the LazyCDProofChain. In explaining ~l3 the step S5
208
 *
209
 *  (or l1 ~l3)      ~l1
210
 *  --------------------- CHAIN_RES
211
 *         ~l3
212
 *
213
 * is added. Since ~l1 has no explanation, the process halts. Note that at this
214
 * point the step S6 has not been added to the LazyCDProofChain. This is because
215
 * to explain ~l5 we need to look at the literal premises in the proofs of
216
 * learned clauses.
217
 *
218
 * The last thing done then in case (3), after the resolution on the conflict
219
 * clause and an initial recursive explanation of propagated literals, is to
220
 * connect the refutation proof and then recursively its propagated literal
221
 * leaves, repeating until a fix point.
222
 *
223
 * In the above example the first connection yields
224
 *
225
 *                           (or l1 ~l3 l5)   ~l5
226
 *                           ---------------------- CHAIN_RES
227
 *                                     (or l1 ~l3)              ~l1
228
 *                                     ----------------------------- CHAIN_RES
229
 *                      (or l3 ~l2)     ~l3
230
 *                      -------------------- CHAIN_RES
231
 *  (or l1 l2)   ~l1    ~l2
232
 * --------------------------- CHAIN_RES
233
 *                     false
234
 *
235
 * whose literal leaves are ~l1 and ~l5. The former has no explanation, but the
236
 * latter is explained by (or l1 ~l5), thus leading to step S6
237
 *
238
 *  (or l1 ~l5)      ~l1
239
 *  --------------------- CHAIN_RES
240
 *         ~l5
241
 *
242
 * then the final connection
243
 *
244
 *                                             (or l1 ~l5)  ~l1
245
 *                                             ---------------- CHAIN_RES
246
 *                            (or l1 ~l3 l5)   ~l5
247
 *                            ---------------------- CHAIN_RES
248
 *                                      (or l1 ~l3)              ~l1
249
 *                                      ----------------------------- CHAIN_RES
250
 *                       (or l3 ~l2)     ~l3
251
 *                       -------------------- CHAIN_RES
252
 *   (or l1 l2)   ~l1    ~l2
253
 *  --------------------------- CHAIN_RES
254
 *                      false
255
 *
256
 * which has no more explainable literals as leaves.
257
 *
258
 * The interfaces below provide ways for the SAT solver to register its
259
 * assumptions (clausified assertions and lemmas) for the SAT proof
260
 * (registerSatAssumption), register resolution steps (startResChain /
261
 * addResolutionStep / endResChain), build the final refutation proof
262
 * (finalizeProof) and retrieve the refutation proof (getProof). So in a given
263
 * run of the SAT solver these interfaces are expected to be used in the
264
 * following order:
265
 *
266
 * (registerSatAssumptions | (startResChain (addResolutionStep)+ endResChain)*)*
267
 * finalizeProof
268
 * getProof
269
 *
270
 */
271
1254
class SatProofManager
272
{
273
 public:
274
  SatProofManager(Minisat::Solver* solver,
275
                  CnfStream* cnfStream,
276
                  context::UserContext* userContext,
277
                  ProofNodeManager* pnm);
278
279
  /** Marks the start of a resolution chain.
280
   *
281
   * This call is followed by *at least one* call to addResolution step and one
282
   * call to endResChain.
283
   *
284
   * The given clause, at the node level, is registered in d_resLinks with a
285
   * null pivot, since this is the first link in the chain.
286
   *
287
   * @param start a SAT solver clause (list of literals) that will be the first
288
   * clause in a resolution chain.
289
   */
290
  void startResChain(const Minisat::Clause& start);
291
  /** Adds a resolution step with a clause
292
   *
293
   * There must have been a call to startResChain before any call to
294
   * addResolution step. After following calls to addResolution step there is
295
   * one call to endResChain.
296
   *
297
   * The resolution step is added to d_resLinks with the clause, at the node
298
   * level, and the literal, at the node level, as the pivot.
299
   *
300
   * @param clause the clause being resolved against
301
   * @param lit the literal occurring in clause to be the pivot of the
302
   * resolution step
303
   */
304
  void addResolutionStep(const Minisat::Clause& clause, Minisat::Lit lit);
305
  /** Adds a resolution step with a unit clause
306
   *
307
   * The resolution step is added to d_resLinks such that lit, at the node
308
   * level, is the pivot and and the unit clause is ~lit, at the node level.
309
   *
310
   * If the literal is marked as redundant, then a step is *not* is added to
311
   * d_resLinks. It is rather saved to d_redundandLits, whose components we will
312
   * be handled in a special manner when the resolution chain is finished. This
313
   * is because the steps corresponding to the removal of redundant literals
314
   * have to be done in a specific order. See proccessRedundantLits below.
315
   *
316
   * @param lit the literal being resolved against
317
   * @param redundant whether lit is redundant
318
   */
319
  void addResolutionStep(Minisat::Lit lit, bool redundant = false);
320
  /** Ends resolution chain concluding a unit clause
321
   *
322
   * This call must have been preceded by one call to startResChain and at least
323
   * one call to addResolutionStep.
324
   *
325
   * This and the version below both call the node version of this method,
326
   * described further below, which actually does the necessary processing.
327
   */
328
  void endResChain(Minisat::Lit lit);
329
  /** Ends resolution chain concluding a clause */
330
  void endResChain(const Minisat::Clause& clause);
331
  /** Build refutation proof starting from conflict clause
332
   *
333
   * This method (or its variations) is only called when the SAT solver has
334
   * reached an unsatisfiable state.
335
   *
336
   * This and the versions below call the node version of this method, described
337
   * further below, which actually does the necessary processing.
338
   *
339
   * @param adding whether the conflict is coming from a freshly added clause
340
   */
341
  void finalizeProof(const Minisat::Clause& inConflict, bool adding = false);
342
  /** Build refutation proof starting from conflict unit clause
343
   *
344
   * @param adding whether the conflict is coming from a freshly added clause
345
   */
346
  void finalizeProof(Minisat::Lit inConflict, bool adding = false);
347
  /** As above, but uses the unit conflict clause saved in d_conflictLit. */
348
  void finalizeProof();
349
  /** Set the unit conflict clause d_conflictLit. */
350
  void storeUnitConflict(Minisat::Lit inConflict);
351
352
  /** Retrive the refutation proof
353
   *
354
   * If there is no chain for false in d_resChains, meaning that this call was
355
   * made before finalizeProof, an assumption proof node is produced.
356
   */
357
  std::shared_ptr<ProofNode> getProof();
358
359
  /** Register a unit clause input, converted to its node representation.  */
360
  void registerSatLitAssumption(Minisat::Lit lit);
361
  /** Register a set clause inputs. */
362
  void registerSatAssumptions(const std::vector<Node>& assumps);
363
364
 private:
365
  /** Ends resolution chain concluding clause
366
   *
367
   * This method builds the proof of conclusion from the resolution chain
368
   * currently saved in d_resLinks.
369
   *
370
   * First each saved redundant literals in d_redundantLits is processed via
371
   * processRedundantLit. The literals in the resolution chain's conclusion are
372
   * used to verifynig which literals in the computed explanations are
373
   * redundant, i.e., don't occur in conclusionLits. The nessary resolution
374
   * steps will be added to d_resLinks.
375
   *
376
   * The proof to be built will be a CHAIN_RESOLUTION step, whose children and
377
   * arguments will be retrieved from traversing d_resLinks. Consider the
378
   * following d_resLinks (where each [~]li is its node equivalent):
379
   *
380
   * - <(or l3 l5 l6 l7), null>
381
   * - <~l5, l5>
382
   * - <(or ~l6 l7), l6>
383
   * - <(or l4 ~l7), l7>
384
   *
385
   * The resulting children and arguments for the CHAIN_RESOLUTION proof step would be:
386
   * - [(or l3 l5 l6 l7), ~l5, (or ~l6 l7), (or l4 ~l7)]
387
   * - [l5, l6, l7]
388
   * and the proof step
389
   *
390
   *   (or l3 l5 l6 l7)   ~l5   (or ~l6 l7)   (or l4 ~l7)
391
   *   --------------------------------------------------- CHAIN_RES_{l5,l6,l7}
392
   *                           (or l3 l4)
393
   *
394
   * The conclusion of the CHAIN_RES proof step is *not* the given conclusion of
395
   * this method. This is because conclusion is the node equivalent of the
396
   * clause in the SAT solver, which is kept modulo duplicates, reordering, and
397
   * double negation elimination. Therefore we generate the above step in the
398
   * correct way for the semantics of CHAIN_RES, based on its children and
399
   * arguments, via the d_pnm's proof checker. The resulting node n is fed into
400
   * the clause normalization in TheoryProofStepBuffer, which reduces n to
401
   * conclusion.
402
   *
403
   * All the proof steps generated to conclude conclusion from the premises in
404
   * d_resLinks are saved into d_resChainPg, which is saved as the proof
405
   * generator for lazy step added to d_resChains for the conclusion.
406
   *
407
   * @param conclusion the node-level conclusion of the resolution chain
408
   * @param conclusionLits the set of literals in the conclusion
409
   */
410
  void endResChain(Node conclusion, const std::set<SatLiteral>& conclusionLits);
411
412
  /** Explain redundant literal and generate corresponding resolution steps
413
   *
414
   * If the redundant literal has a reason, we add a resolution step with that
415
   * clause, otherwise with the negation of the redundant literal as the unit
416
   * clause. The redundant literal is the resolvent in both cases.  The steps
417
   * are always added as the *first* link after last resolution step added
418
   * *before* processing redundant literals began, i.e., at d_resLinks.begin() +
419
   * pos. This is to guarantee that the links are in the correct order for the
420
   * chain resolution, see below.
421
   *
422
   * If the reason contains literals that do not occur in conclusionLits, they
423
   * are redundant and recursively processed by this method. This recursive
424
   * processing happens *before* the resolution step for lit is added. Since
425
   * steps are always added in position pos, pushing steps after that 1
426
   * position, this guarantees that a step with a clause will occur before the
427
   * steps that eliminate its redundant literals.
428
   *
429
   * Consider d_resLinks with 3 links before the first processRedundantLit call,
430
   * i.e., pos = 3, and d_redundantLits = {l1}, with reason(l1) = (or l1 ~l2),
431
   * with ~l2 redundant. Assume ~l2 has no explanation. By processing ~l2 first,
432
   * the link <~l2, l2> will be added at position 3. Then by coming back to the
433
   * processing of l1 the link <(or l1 ~l2), l1> will also be added position 3,
434
   * with <~l2, l2> pushed to position 4. If this these links had the reverse
435
   * order the literal ~l2 would, erroneously, occur in the chain resolution
436
   * conclusion, as it is introduced by (or l1 ~l2).
437
   *
438
   * After a resolution step for a redundant literal is added, it is marked as
439
   * visited, thus avoiding adding redundunt resolution steps to the chain if
440
   * that literal occurs again in another redundant literal's reason.
441
   *
442
   * @param lit the redundant literal
443
   * @param conclusionLits the literals in the clause from which redundant
444
   * literals have been removed
445
   * @param visited cache of literals already processed
446
   * @param pos position, in d_resLinks, of last resolution step added *before*
447
   * processing redundant literals
448
   */
449
  void processRedundantLit(SatLiteral lit,
450
                           const std::set<SatLiteral>& conclusionLits,
451
                           std::set<SatLiteral>& visited,
452
                           unsigned pos);
453
  /** Explain literal if it is propagated in the SAT solver
454
   *
455
   * If a literal is propagated, i.e., it has a reason in the SAT solver, that
456
   * clause is retrieved. This method is then called recursively on the negation
457
   * of each of reason's literals (that is not lit). Afterwards a
458
   * CHAIN_RESOLUTION proof step is created to conclude lit from the reason and
459
   * its literals, other than lit, negations.
460
   *
461
   * This method also tracks all the literals and clauses, at the node level,
462
   * that have been used as premises of resolutions steps in the recursive
463
   * explanations. A resolution step is only created if the conclusion does not
464
   * occur in these premises, as this would configure a cyclic proof.
465
   *
466
   * These cyclic proofs, at the node level, are naturally generated by the SAT
467
   * solver because they are so that a literal is derived from a clause (so they
468
   * are different) but both correspond to the *same node*. For example,
469
   * consider the following derivation at the SAT solver level
470
   *
471
   *                       [l1, l2, l3]    ~l2   ~l3
472
   *                       -------------------------- CHAIN_RES
473
   *           [l0, ~l1]       l1
474
   *           ---------------------- CHAIN_RES
475
   *                    l0
476
   *
477
   * which has no issues. However, its node equivalent is
478
   *
479
   *                  (or a b c)    (not b)   (not c)
480
   *                  ------------------------------- CHAIN_RES
481
   *      (or (or a b c) (not a))       a
482
   *      --------------------------------- CHAIN_RES
483
   *               (or a b c)
484
   *
485
   * which is cyclic. The issue is that l0 = (or a b c). Only at the SAT level
486
   * are l0 and [l1, l2, l3] different.
487
   *
488
   * If a cyclic proof is identified, the respective node is kept as an
489
   * assumption.
490
   *
491
   * @param lit the literal to explained
492
   * @param premises set of literals and clauses, at the node level, that
493
   * have been used as premises of resolution steps while explaining
494
   * propagations
495
   */
496
  void explainLit(prop::SatLiteral lit, std::unordered_set<TNode>& premises);
497
498
  /** Build refutation proof starting from conflict clause
499
   *
500
   * Given a conflict clause, this method handles case (3) described in the
501
   * preamble. Each of the literals in the conflict clause is either
502
   * explainable, the result of a previously saved resolution chain, or an
503
   * input.
504
   *
505
   * First, explainLit is called recursively on the negated literals from
506
   * the conflict clause.
507
   *
508
   * Second, a CHAIN_RESOLUTION proof step is added between
509
   * the conflict clause and its negated literals, concluding false.
510
   *
511
   * Third, until a fix point, the refutation proof is connected, by calling
512
   * d_resChain.getProofFor(d_false), its free assumptions are determined and,
513
   * in case any as a literal that might be explained, we call explainLit.
514
   *
515
   * The latter is called to a fix point because adding an explanation to a
516
   * propagated literal may connect it with a previously saved resolution chain,
517
   * which may have free assumptions that are literals that can be explained and
518
   * so on.
519
   *
520
   * @param inConflictNode node corresponding to conflict clause
521
   * @param inConflict literals in the conflict clause
522
   */
523
  void finalizeProof(Node inConflictNode,
524
                     const std::vector<SatLiteral>& inConflict);
525
526
  /** The SAT solver to which we are managing proofs */
527
  Minisat::Solver* d_solver;
528
  /** Pointer to the underlying cnf stream. */
529
  CnfStream* d_cnfStream;
530
  /** The proof node manager */
531
  ProofNodeManager* d_pnm;
532
  /** Resolution steps (links) accumulator for chain resolution.
533
   *
534
   * Each tuple has a clause and the pivot for the resolution step it is
535
   * involved on, as well as whether the pivot occurs positively/negatively or
536
   * negatively/positively in the clauses being resolved. If the third argument
537
   * is true (resp. false), the pivot occurs positively (negatively) in the
538
   * clause yielded by the resolution up to the previous link and negatively
539
   * (positively) in this link. The first link has a null pivot. Links are kept
540
   * at the node level.
541
   *
542
   * This accumulator is reset after each chain resolution. */
543
  std::vector<std::tuple<Node, Node, bool>> d_resLinks;
544
545
  /** Redundant literals removed from the resolution chain's conclusion.
546
   *
547
   * This accumulator is reset after each chain resolution. */
548
  std::vector<SatLiteral> d_redundantLits;
549
550
  /**
551
   * Associates clauses to their local proofs. These proofs are local and
552
   * possibly updated during solving. When the final conclusion is reached, a
553
   * final proof is built based on the proofs saved here.
554
   *
555
   * This chain is initialized so that its getProofFor method, which connects
556
   * the chain, accounts for cyclic proofs. This is so that we avoid the issue
557
   * described in explainLit.
558
   */
559
  LazyCDProofChain d_resChains;
560
561
  /** The proof generator for resolution chains */
562
  BufferedProofGenerator d_resChainPg;
563
564
  /** The true/false nodes */
565
  Node d_true;
566
  Node d_false;
567
568
  /** All clauses added to the SAT solver, kept in a context-dependent manner.
569
   */
570
  context::CDHashSet<Node> d_assumptions;
571
572
  /**
573
   * A placeholder that may be used to store the literal with the final
574
   * conflict.
575
   */
576
  SatLiteral d_conflictLit;
577
  /** Gets node equivalent to literal */
578
  Node getClauseNode(SatLiteral satLit);
579
  /** Gets node equivalent to clause.
580
   *
581
   * To avoid generating different nodes for the same clause, modulo ordering,
582
   * an invariant assumed throughout this class, the OR node generated by this
583
   * method always has its children ordered.
584
   */
585
  Node getClauseNode(const Minisat::Clause& clause);
586
  /** Prints clause, as a sequence of literals, in the "sat-proof" trace. */
587
  void printClause(const Minisat::Clause& clause);
588
}; /* class SatProofManager */
589
590
}  // namespace prop
591
}  // namespace cvc5
592
593
#endif /* CVC5__SAT_PROOF_MANAGER_H */