1 /********************* */
2 /*! \file sat_proof_manager.cpp
4 ** Top contributors (to current version):
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2020 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.\endverbatim
12 ** \brief Implementation of the proof manager for Minisat
15 #include "prop/sat_proof_manager.h"
17 #include "expr/proof_node_algorithm.h"
18 #include "options/smt_options.h"
19 #include "prop/cnf_stream.h"
20 #include "prop/minisat/minisat.h"
21 #include "theory/theory_proof_step_buffer.h"
26 SatProofManager::SatProofManager(Minisat::Solver
* solver
,
28 context::UserContext
* userContext
,
29 ProofNodeManager
* pnm
)
31 d_cnfStream(cnfStream
),
33 d_resChains(pnm
, true, userContext
),
34 d_resChainPg(userContext
, pnm
),
35 d_assumptions(userContext
),
36 d_conflictLit(undefSatVariable
)
38 d_false
= NodeManager::currentNM()->mkConst(false);
41 void SatProofManager::printClause(const Minisat::Clause
& clause
)
43 for (unsigned i
= 0, size
= clause
.size(); i
< size
; ++i
)
45 SatLiteral satLit
= MinisatSatSolver::toSatLiteral(clause
[i
]);
46 Trace("sat-proof") << satLit
<< " ";
50 Node
SatProofManager::getClauseNode(SatLiteral satLit
)
52 Assert(d_cnfStream
->getNodeCache().find(satLit
)
53 != d_cnfStream
->getNodeCache().end())
54 << "SatProofManager::getClauseNode: literal " << satLit
56 return d_cnfStream
->getNodeCache()[satLit
];
59 Node
SatProofManager::getClauseNode(const Minisat::Clause
& clause
)
61 std::vector
<Node
> clauseNodes
;
62 for (unsigned i
= 0, size
= clause
.size(); i
< size
; ++i
)
64 SatLiteral satLit
= MinisatSatSolver::toSatLiteral(clause
[i
]);
65 Assert(d_cnfStream
->getNodeCache().find(satLit
)
66 != d_cnfStream
->getNodeCache().end())
67 << "SatProofManager::getClauseNode: literal " << satLit
69 clauseNodes
.push_back(d_cnfStream
->getNodeCache()[satLit
]);
71 // order children by node id
72 std::sort(clauseNodes
.begin(), clauseNodes
.end());
73 return NodeManager::currentNM()->mkNode(kind::OR
, clauseNodes
);
76 void SatProofManager::startResChain(const Minisat::Clause
& start
)
78 if (Trace
.isOn("sat-proof"))
80 Trace("sat-proof") << "SatProofManager::startResChain: ";
82 Trace("sat-proof") << "\n";
85 std::pair
<Node
, Node
>(getClauseNode(start
), Node::null()));
88 void SatProofManager::addResolutionStep(Minisat::Lit lit
, bool redundant
)
90 SatLiteral satLit
= MinisatSatSolver::toSatLiteral(lit
);
93 Trace("sat-proof") << "SatProofManager::addResolutionStep: [" << satLit
94 << "] " << ~satLit
<< "\n";
96 std::pair
<Node
, Node
>(d_cnfStream
->getNodeCache()[~satLit
],
97 d_cnfStream
->getNodeCache()[satLit
]));
101 Trace("sat-proof") << "SatProofManager::addResolutionStep: redundant lit "
102 << satLit
<< " stored\n";
103 d_redundantLits
.push_back(satLit
);
107 void SatProofManager::addResolutionStep(const Minisat::Clause
& clause
,
110 // the given clause is supposed to be the second in a resolution, with the
111 // given literal as the pivot occurring positive in the first and negatively
112 // in the second clause. Thus, we store its negation
113 SatLiteral satLit
= MinisatSatSolver::toSatLiteral(~lit
);
114 Node clauseNode
= getClauseNode(clause
);
115 d_resLinks
.push_back(
116 std::pair
<Node
, Node
>(clauseNode
, d_cnfStream
->getNodeCache()[satLit
]));
117 if (Trace
.isOn("sat-proof"))
119 Trace("sat-proof") << "SatProofManager::addResolutionStep: [" << satLit
122 Trace("sat-proof") << "\nSatProofManager::addResolutionStep:\t"
123 << clauseNode
<< "\n";
127 void SatProofManager::endResChain(Minisat::Lit lit
)
129 SatLiteral satLit
= MinisatSatSolver::toSatLiteral(lit
);
130 Trace("sat-proof") << "SatProofManager::endResChain: chain_res for "
132 endResChain(getClauseNode(satLit
), {satLit
});
135 void SatProofManager::endResChain(const Minisat::Clause
& clause
)
137 if (Trace
.isOn("sat-proof"))
139 Trace("sat-proof") << "SatProofManager::endResChain: chain_res for ";
142 std::set
<SatLiteral
> clauseLits
;
143 for (unsigned i
= 0, size
= clause
.size(); i
< size
; ++i
)
145 clauseLits
.insert(MinisatSatSolver::toSatLiteral(clause
[i
]));
147 endResChain(getClauseNode(clause
), clauseLits
);
150 void SatProofManager::endResChain(Node conclusion
,
151 const std::set
<SatLiteral
>& conclusionLits
)
153 Trace("sat-proof") << ", " << conclusion
<< "\n";
154 // first process redundant literals
155 std::set
<SatLiteral
> visited
;
156 unsigned pos
= d_resLinks
.size();
157 for (SatLiteral satLit
: d_redundantLits
)
159 processRedundantLit(satLit
, conclusionLits
, visited
, pos
);
161 d_redundantLits
.clear();
162 // build resolution chain
163 std::vector
<Node
> children
, args
;
164 for (unsigned i
= 0, size
= d_resLinks
.size(); i
< size
; ++i
)
166 children
.push_back(d_resLinks
[i
].first
);
167 Trace("sat-proof") << "SatProofManager::endResChain: ";
171 << "[" << d_cnfStream
->getTranslationCache()[d_resLinks
[i
].second
]
174 // special case for clause (or l1 ... ln) being a single literal
175 // corresponding itself to a clause, which is indicated by the pivot being
176 // of the form (not (or l1 ... ln))
177 if (d_resLinks
[i
].first
.getKind() == kind::OR
178 && !(d_resLinks
[i
].second
.getKind() == kind::NOT
179 && d_resLinks
[i
].second
[0].getKind() == kind::OR
180 && d_resLinks
[i
].second
[0] == d_resLinks
[i
].first
))
182 for (unsigned j
= 0, sizeJ
= d_resLinks
[i
].first
.getNumChildren();
187 << d_cnfStream
->getTranslationCache()[d_resLinks
[i
].first
[j
]];
190 Trace("sat-proof") << ", ";
196 Assert(d_cnfStream
->getTranslationCache().find(d_resLinks
[i
].first
)
197 != d_cnfStream
->getTranslationCache().end())
198 << "clause node " << d_resLinks
[i
].first
199 << " treated as unit has no literal. Pivot is "
200 << d_resLinks
[i
].second
<< "\n";
202 << d_cnfStream
->getTranslationCache()[d_resLinks
[i
].first
];
204 Trace("sat-proof") << " : ";
207 args
.push_back(d_resLinks
[i
].second
);
208 Trace("sat-proof") << "[" << d_resLinks
[i
].second
<< "] ";
210 Trace("sat-proof") << d_resLinks
[i
].first
<< "\n";
215 if (children
.size() == 1)
217 Trace("sat-proof") << "SatProofManager::endResChain: no-op. The conclusion "
218 << conclusion
<< " is set-equal to premise "
219 << children
[0] << "\n";
222 if (Trace
.isOn("sat-proof") && d_resChains
.hasGenerator(conclusion
))
224 Trace("sat-proof") << "SatProofManager::endResChain: replacing proof of "
225 << conclusion
<< "\n";
227 // since the conclusion can be both reordered and without duplicates and the
228 // SAT solver does not record this information, we must recompute it here so
229 // the proper CHAIN_RESOLUTION step can be created
230 // compute chain resolution conclusion
231 Node chainConclusion
= d_pnm
->getChecker()->checkDebug(
232 PfRule::CHAIN_RESOLUTION
, children
, args
, Node::null(), "");
234 << "SatProofManager::endResChain: creating step for computed conclusion "
235 << chainConclusion
<< "\n";
237 theory::TheoryProofStepBuffer psb
;
238 psb
.addStep(PfRule::CHAIN_RESOLUTION
, children
, args
, chainConclusion
);
239 if (chainConclusion
!= conclusion
)
241 // if this happens that chainConclusion needs to be factored and/or
242 // reordered, which in either case can be done only if it's not a unit
244 CVC4_UNUSED Node reducedChainConclusion
=
245 psb
.factorReorderElimDoubleNeg(chainConclusion
);
246 Assert(reducedChainConclusion
== conclusion
)
247 << "original conclusion " << conclusion
248 << "\nis different from computed conclusion " << chainConclusion
249 << "\nafter factorReorderElimDoubleNeg " << reducedChainConclusion
;
251 // buffer the steps in the resolution chain proof generator
252 const std::vector
<std::pair
<Node
, ProofStep
>>& steps
= psb
.getSteps();
253 for (const std::pair
<Node
, ProofStep
>& step
: steps
)
255 Trace("sat-proof") << "SatProofManager::endResChain: adding for "
256 << step
.first
<< " step " << step
.second
<< "\n";
257 d_resChainPg
.addStep(step
.first
, step
.second
);
258 // the premises of this resolution may not have been justified yet, so we do
259 // not pass assumptions to check closedness
260 d_resChains
.addLazyStep(step
.first
, &d_resChainPg
);
264 void SatProofManager::processRedundantLit(
266 const std::set
<SatLiteral
>& conclusionLits
,
267 std::set
<SatLiteral
>& visited
,
270 Trace("sat-proof") << push
271 << "SatProofManager::processRedundantLit: Lit: " << lit
273 if (visited
.count(lit
))
275 Trace("sat-proof") << "already visited\n" << pop
;
278 Minisat::Solver::TCRef reasonRef
=
279 d_solver
->reason(Minisat::var(MinisatSatSolver::toMinisatLit(lit
)));
280 if (reasonRef
== Minisat::Solver::TCRef_Undef
)
282 Trace("sat-proof") << "unit, add link to lit " << lit
<< " at pos: " << pos
286 d_resLinks
.insert(d_resLinks
.begin() + pos
,
287 std::pair
<Node
, Node
>(d_cnfStream
->getNodeCache()[~lit
],
288 d_cnfStream
->getNodeCache()[lit
]));
291 Assert(reasonRef
>= 0 && reasonRef
< d_solver
->ca
.size())
292 << "reasonRef " << reasonRef
<< " and d_satSolver->ca.size() "
293 << d_solver
->ca
.size() << "\n";
294 const Minisat::Clause
& reason
= d_solver
->ca
[reasonRef
];
295 if (Trace
.isOn("sat-proof"))
297 Trace("sat-proof") << "reason: ";
299 Trace("sat-proof") << "\n";
301 // check if redundant literals in the reason. The first literal is the one we
302 // will be eliminating, so we check the others
303 for (unsigned i
= 1, size
= reason
.size(); i
< size
; ++i
)
305 SatLiteral satLit
= MinisatSatSolver::toSatLiteral(reason
[i
]);
306 // if literal does not occur in the conclusion we process it as well
307 if (!conclusionLits
.count(satLit
))
309 processRedundantLit(satLit
, conclusionLits
, visited
, pos
);
312 Assert(!visited
.count(lit
));
314 Trace("sat-proof") << "clause, add link to lit " << lit
<< " at pos: " << pos
317 // add the step before steps for children. Note that the step is with the
318 // reason, not only with ~lit, since the learned clause is built under the
319 // assumption that the redundant literal is removed via the resolution with
320 // the explanation of its negation
321 Node clauseNode
= getClauseNode(reason
);
323 d_resLinks
.begin() + pos
,
324 std::pair
<Node
, Node
>(clauseNode
, d_cnfStream
->getNodeCache()[lit
]));
327 void SatProofManager::explainLit(
328 SatLiteral lit
, std::unordered_set
<TNode
, TNodeHashFunction
>& premises
)
330 Node litNode
= getClauseNode(lit
);
331 Trace("sat-proof") << push
<< "SatProofManager::explainLit: Lit: " << lit
332 << " [" << litNode
<< "]\n";
333 Minisat::Solver::TCRef reasonRef
=
334 d_solver
->reason(Minisat::var(MinisatSatSolver::toMinisatLit(lit
)));
335 if (reasonRef
== Minisat::Solver::TCRef_Undef
)
337 Trace("sat-proof") << "SatProofManager::explainLit: no SAT reason\n" << pop
;
340 Assert(reasonRef
>= 0 && reasonRef
< d_solver
->ca
.size())
341 << "reasonRef " << reasonRef
<< " and d_satSolver->ca.size() "
342 << d_solver
->ca
.size() << "\n";
343 const Minisat::Clause
& reason
= d_solver
->ca
[reasonRef
];
344 unsigned size
= reason
.size();
345 if (Trace
.isOn("sat-proof"))
347 Trace("sat-proof") << "SatProofManager::explainLit: with clause: ";
349 Trace("sat-proof") << "\n";
351 // pedantically check that the negation of the literal to explain *does not*
352 // occur in the reason, otherwise we will loop forever
353 for (unsigned i
= 0; i
< size
; ++i
)
355 AlwaysAssert(~MinisatSatSolver::toSatLiteral(reason
[i
]) != lit
)
356 << "cyclic justification\n";
358 // add the reason clause first
359 std::vector
<Node
> children
{getClauseNode(reason
)}, args
;
360 // save in the premises
361 premises
.insert(children
.back());
362 Trace("sat-proof") << push
;
363 for (unsigned i
= 0; i
< size
; ++i
)
365 SatLiteral curr_lit
= MinisatSatSolver::toSatLiteral(reason
[i
]);
366 // ignore the lit we are trying to explain...
371 std::unordered_set
<TNode
, TNodeHashFunction
> childPremises
;
372 explainLit(~curr_lit
, childPremises
);
373 // save to resolution chain premises / arguments
374 Assert(d_cnfStream
->getNodeCache().find(curr_lit
)
375 != d_cnfStream
->getNodeCache().end());
376 children
.push_back(d_cnfStream
->getNodeCache()[~curr_lit
]);
377 args
.push_back(d_cnfStream
->getNodeCache()[curr_lit
]);
378 // add child premises and the child itself
379 premises
.insert(childPremises
.begin(), childPremises
.end());
380 premises
.insert(d_cnfStream
->getNodeCache()[~curr_lit
]);
382 if (Trace
.isOn("sat-proof"))
384 Trace("sat-proof") << pop
<< "SatProofManager::explainLit: chain_res for "
385 << lit
<< ", " << litNode
<< " with clauses:\n";
386 for (unsigned i
= 0, csize
= children
.size(); i
< csize
; ++i
)
388 Trace("sat-proof") << "SatProofManager::explainLit: " << children
[i
];
391 Trace("sat-proof") << " [" << args
[i
- 1] << "]";
393 Trace("sat-proof") << "\n";
396 // if justification of children contains the expected conclusion, avoid the
397 // cyclic proof by aborting.
398 if (premises
.count(litNode
))
400 Trace("sat-proof") << "SatProofManager::explainLit: CYCLIC PROOF of " << lit
401 << " [" << litNode
<< "], ABORT\n"
405 Trace("sat-proof") << pop
;
407 ProofStep
ps(PfRule::CHAIN_RESOLUTION
, children
, args
);
408 d_resChainPg
.addStep(litNode
, ps
);
409 // the premises in the limit of the justification may correspond to other
410 // links in the chain which have, themselves, literals yet to be justified. So
411 // we are not ready yet to check closedness w.r.t. CNF transformation of the
412 // preprocessed assertions
413 d_resChains
.addLazyStep(litNode
, &d_resChainPg
);
416 void SatProofManager::finalizeProof(Node inConflictNode
,
417 const std::vector
<SatLiteral
>& inConflict
)
420 << "SatProofManager::finalizeProof: conflicting clause node: "
421 << inConflictNode
<< "\n";
423 if (inConflictNode
== d_false
)
427 if (Trace
.isOn("sat-proof-debug2"))
429 Trace("sat-proof-debug2")
430 << push
<< "SatProofManager::finalizeProof: saved proofs in chain:\n";
431 std::map
<Node
, std::shared_ptr
<ProofNode
>> links
= d_resChains
.getLinks();
432 std::unordered_set
<Node
, NodeHashFunction
> skip
;
433 for (const std::pair
<const Node
, std::shared_ptr
<ProofNode
>>& link
: links
)
435 if (skip
.count(link
.first
))
439 auto it
= d_cnfStream
->getTranslationCache().find(link
.first
);
440 if (it
!= d_cnfStream
->getTranslationCache().end())
442 Trace("sat-proof-debug2")
443 << "SatProofManager::finalizeProof: " << it
->second
;
445 // a refl step added due to double elim negation, ignore
446 else if (link
.second
->getRule() == PfRule::REFL
)
453 Trace("sat-proof-debug2") << "SatProofManager::finalizeProof:";
454 Assert(link
.first
.getKind() == kind::OR
) << link
.first
;
455 for (const Node
& n
: link
.first
)
457 it
= d_cnfStream
->getTranslationCache().find(n
);
458 Assert(it
!= d_cnfStream
->getTranslationCache().end());
459 Trace("sat-proof-debug2") << it
->second
<< " ";
462 Trace("sat-proof-debug2") << "\n";
463 Trace("sat-proof-debug2")
464 << "SatProofManager::finalizeProof: " << link
.first
<< "\n";
466 Node cur
= link
.first
;
467 std::shared_ptr
<ProofNode
> pfn
= link
.second
;
468 while (pfn
->getRule() != PfRule::CHAIN_RESOLUTION
)
470 Assert(pfn
->getChildren().size() == 1
471 && pfn
->getChildren()[0]->getRule() == PfRule::ASSUME
)
472 << *link
.second
.get() << "\n"
474 cur
= pfn
->getChildren()[0]->getResult();
475 // retrieve justification of assumption in the links
476 Assert(links
.find(cur
) != links
.end());
478 // ignore it in the rest of the outside loop
481 std::vector
<Node
> fassumps
;
482 expr::getFreeAssumptions(pfn
.get(), fassumps
);
483 Trace("sat-proof-debug2") << push
;
484 for (const Node
& fa
: fassumps
)
486 Trace("sat-proof-debug2") << "SatProofManager::finalizeProof: - ";
487 it
= d_cnfStream
->getTranslationCache().find(fa
);
488 if (it
!= d_cnfStream
->getTranslationCache().end())
490 Trace("sat-proof-debug2") << it
->second
<< "\n";
493 // then it's a clause
494 Assert(fa
.getKind() == kind::OR
);
495 for (const Node
& n
: fa
)
497 it
= d_cnfStream
->getTranslationCache().find(n
);
498 Assert(it
!= d_cnfStream
->getTranslationCache().end());
499 Trace("sat-proof-debug2") << it
->second
<< " ";
501 Trace("sat-proof-debug2") << "\n";
503 Trace("sat-proof-debug2") << pop
;
504 Trace("sat-proof-debug2")
505 << "SatProofManager::finalizeProof: " << *pfn
.get() << "\n=======\n";
508 Trace("sat-proof-debug2") << pop
;
510 // We will resolve away of the literals l_1...l_n in inConflict. At this point
511 // each ~l_i must be either explainable, the result of a previously saved
512 // resolution chain, or an input. In account of it possibly being the first,
513 // we call explainLit on each ~l_i while accumulating the children and
514 // arguments for the resolution step to conclude false.
515 std::vector
<Node
> children
{inConflictNode
}, args
;
516 std::unordered_set
<TNode
, TNodeHashFunction
> premises
;
517 for (unsigned i
= 0, size
= inConflict
.size(); i
< size
; ++i
)
519 Assert(d_cnfStream
->getNodeCache().find(inConflict
[i
])
520 != d_cnfStream
->getNodeCache().end());
521 std::unordered_set
<TNode
, TNodeHashFunction
> childPremises
;
522 explainLit(~inConflict
[i
], childPremises
);
523 Node negatedLitNode
= d_cnfStream
->getNodeCache()[~inConflict
[i
]];
524 // save to resolution chain premises / arguments
525 children
.push_back(negatedLitNode
);
526 args
.push_back(d_cnfStream
->getNodeCache()[inConflict
[i
]]);
527 // add child premises and the child itself
528 premises
.insert(childPremises
.begin(), childPremises
.end());
529 premises
.insert(negatedLitNode
);
530 Trace("sat-proof") << "===========\n";
532 if (Trace
.isOn("sat-proof"))
534 Trace("sat-proof") << "SatProofManager::finalizeProof: chain_res for false "
536 for (unsigned i
= 0, size
= children
.size(); i
< size
; ++i
)
538 Trace("sat-proof") << "SatProofManager::finalizeProof: " << children
[i
];
541 Trace("sat-proof") << " [" << args
[i
- 1] << "]";
543 Trace("sat-proof") << "\n";
547 ProofStep
ps(PfRule::CHAIN_RESOLUTION
, children
, args
);
548 d_resChainPg
.addStep(d_false
, ps
);
549 // not yet ready to check closedness because maybe only now we will justify
550 // literals used in resolutions
551 d_resChains
.addLazyStep(d_false
, &d_resChainPg
);
552 // Fix point justification of literals in leaves of the proof of false
557 Trace("sat-proof") << "expand assumptions to prove false\n";
558 std::shared_ptr
<ProofNode
> pfn
= d_resChains
.getProofFor(d_false
);
560 Trace("sat-proof-debug") << "sat proof of flase: " << *pfn
.get() << "\n";
561 std::vector
<Node
> fassumps
;
562 expr::getFreeAssumptions(pfn
.get(), fassumps
);
563 if (Trace
.isOn("sat-proof"))
565 for (const Node
& fa
: fassumps
)
567 Trace("sat-proof") << "- ";
568 auto it
= d_cnfStream
->getTranslationCache().find(fa
);
569 if (it
!= d_cnfStream
->getTranslationCache().end())
571 Trace("sat-proof") << it
->second
<< "\n";
572 Trace("sat-proof") << "- " << fa
<< "\n";
575 // then it's a clause
576 Assert(fa
.getKind() == kind::OR
);
577 for (const Node
& n
: fa
)
579 it
= d_cnfStream
->getTranslationCache().find(n
);
580 Assert(it
!= d_cnfStream
->getTranslationCache().end());
581 Trace("sat-proof") << it
->second
<< " ";
583 Trace("sat-proof") << "\n";
584 Trace("sat-proof") << "- " << fa
<< "\n";
588 // for each assumption, see if it has a reason
589 for (const Node
& fa
: fassumps
)
591 // ignore already processed assumptions
592 if (premises
.count(fa
))
594 Trace("sat-proof") << "already processed assumption " << fa
<< "\n";
597 // ignore input assumptions. This is necessary to avoid rare collisions
598 // between input clauses and literals that are equivalent at the node
599 // level. In trying to justify the literal below if, it was previously
600 // propagated (say, in a previous check-sat call that survived the
601 // user-context changes) but no longer holds, then we may introduce a
602 // bogus proof for it, rather than keeping it as an input.
603 if (d_assumptions
.contains(fa
))
605 Trace("sat-proof") << "input assumption " << fa
<< "\n";
608 // ignore non-literals
609 auto it
= d_cnfStream
->getTranslationCache().find(fa
);
610 if (it
== d_cnfStream
->getTranslationCache().end())
612 Trace("sat-proof") << "no lit assumption " << fa
<< "\n";
616 Trace("sat-proof") << "lit assumption (" << it
->second
<< "), " << fa
618 // mark another iteration for the loop, as some resolution link may be
619 // connected because of the new justifications
621 std::unordered_set
<TNode
, TNodeHashFunction
> childPremises
;
622 explainLit(it
->second
, childPremises
);
623 // add the premises used in the justification. We know they will have
624 // been as expanded as possible
625 premises
.insert(childPremises
.begin(), childPremises
.end());
626 // add free assumption itself
630 // now we should be able to close it
631 if (options::proofNewEagerChecking())
633 std::vector
<Node
> assumptionsVec
;
634 for (const Node
& a
: d_assumptions
)
636 assumptionsVec
.push_back(a
);
638 d_resChains
.addLazyStep(d_false
, &d_resChainPg
, assumptionsVec
);
642 void SatProofManager::storeUnitConflict(Minisat::Lit inConflict
)
644 Assert(d_conflictLit
== undefSatVariable
);
645 d_conflictLit
= MinisatSatSolver::toSatLiteral(inConflict
);
648 void SatProofManager::finalizeProof()
650 Assert(d_conflictLit
!= undefSatVariable
);
652 << "SatProofManager::finalizeProof: conflicting (lazy) satLit: "
653 << d_conflictLit
<< "\n";
654 finalizeProof(getClauseNode(d_conflictLit
), {d_conflictLit
});
657 void SatProofManager::finalizeProof(Minisat::Lit inConflict
, bool adding
)
659 SatLiteral satLit
= MinisatSatSolver::toSatLiteral(inConflict
);
660 Trace("sat-proof") << "SatProofManager::finalizeProof: conflicting satLit: "
662 Node clauseNode
= getClauseNode(satLit
);
665 registerSatAssumptions({clauseNode
});
667 finalizeProof(clauseNode
, {satLit
});
670 void SatProofManager::finalizeProof(const Minisat::Clause
& inConflict
,
673 if (Trace
.isOn("sat-proof"))
676 << "SatProofManager::finalizeProof: conflicting clause: ";
677 printClause(inConflict
);
678 Trace("sat-proof") << "\n";
680 std::vector
<SatLiteral
> clause
;
681 for (unsigned i
= 0, size
= inConflict
.size(); i
< size
; ++i
)
683 clause
.push_back(MinisatSatSolver::toSatLiteral(inConflict
[i
]));
685 Node clauseNode
= getClauseNode(inConflict
);
688 registerSatAssumptions({clauseNode
});
690 finalizeProof(clauseNode
, clause
);
693 std::shared_ptr
<ProofNode
> SatProofManager::getProof()
695 std::shared_ptr
<ProofNode
> pfn
= d_resChains
.getProofFor(d_false
);
698 pfn
= d_pnm
->mkAssume(d_false
);
703 void SatProofManager::registerSatLitAssumption(Minisat::Lit lit
)
705 Trace("sat-proof") << "SatProofManager::registerSatLitAssumption: - "
706 << getClauseNode(MinisatSatSolver::toSatLiteral(lit
))
708 d_assumptions
.insert(getClauseNode(MinisatSatSolver::toSatLiteral(lit
)));
711 void SatProofManager::registerSatAssumptions(const std::vector
<Node
>& assumps
)
713 for (const Node
& a
: assumps
)
715 Trace("sat-proof") << "SatProofManager::registerSatAssumptions: - " << a
717 d_assumptions
.insert(a
);