1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds, Aina Niemetz |
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 theory engine proof generator. |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "theory/theory_engine_proof_generator.h" |
17 |
|
|
18 |
|
#include <sstream> |
19 |
|
|
20 |
|
#include "expr/proof_node.h" |
21 |
|
|
22 |
|
using namespace cvc5::kind; |
23 |
|
|
24 |
|
namespace cvc5 { |
25 |
|
|
26 |
9459 |
TheoryEngineProofGenerator::TheoryEngineProofGenerator(ProofNodeManager* pnm, |
27 |
9459 |
context::UserContext* u) |
28 |
9459 |
: d_pnm(pnm), d_proofs(u) |
29 |
|
{ |
30 |
9459 |
d_false = NodeManager::currentNM()->mkConst(false); |
31 |
9459 |
} |
32 |
|
|
33 |
20937 |
theory::TrustNode TheoryEngineProofGenerator::mkTrustExplain( |
34 |
|
TNode lit, Node exp, std::shared_ptr<LazyCDProof> lpf) |
35 |
|
{ |
36 |
41874 |
Node p; |
37 |
20937 |
theory::TrustNode trn; |
38 |
20937 |
if (lit == d_false) |
39 |
|
{ |
40 |
|
// propagation of false is a conflict |
41 |
111 |
trn = theory::TrustNode::mkTrustConflict(exp, this); |
42 |
111 |
p = trn.getProven(); |
43 |
111 |
Assert(p.getKind() == NOT); |
44 |
|
} |
45 |
|
else |
46 |
|
{ |
47 |
20826 |
trn = theory::TrustNode::mkTrustPropExp(lit, exp, this); |
48 |
20826 |
p = trn.getProven(); |
49 |
20826 |
Assert(p.getKind() == IMPLIES && p.getNumChildren() == 2); |
50 |
|
} |
51 |
|
// should not already be proven |
52 |
20937 |
NodeLazyCDProofMap::iterator it = d_proofs.find(p); |
53 |
20937 |
if (it == d_proofs.end()) |
54 |
|
{ |
55 |
|
// we will prove the fact p using the proof from lpf. |
56 |
17903 |
d_proofs.insert(p, lpf); |
57 |
|
} |
58 |
41874 |
return trn; |
59 |
|
} |
60 |
|
|
61 |
14571 |
std::shared_ptr<ProofNode> TheoryEngineProofGenerator::getProofFor(Node f) |
62 |
|
{ |
63 |
29142 |
Trace("tepg-debug") << "TheoryEngineProofGenerator::getProofFor: " << f |
64 |
14571 |
<< std::endl; |
65 |
14571 |
NodeLazyCDProofMap::iterator it = d_proofs.find(f); |
66 |
14571 |
if (it == d_proofs.end()) |
67 |
|
{ |
68 |
|
Trace("tepg-debug") << "...null" << std::endl; |
69 |
|
return nullptr; |
70 |
|
} |
71 |
29142 |
std::shared_ptr<LazyCDProof> lcp = (*it).second; |
72 |
|
// finalize it via scope |
73 |
29142 |
std::vector<Node> scopeAssumps; |
74 |
|
// should only ask this generator for proofs of implications, or conflicts |
75 |
29142 |
Node exp; |
76 |
29142 |
Node conclusion; |
77 |
14571 |
if (f.getKind() == IMPLIES && f.getNumChildren() == 2) |
78 |
|
{ |
79 |
14551 |
exp = f[0]; |
80 |
14551 |
conclusion = f[1]; |
81 |
|
} |
82 |
20 |
else if (f.getKind() == NOT) |
83 |
|
{ |
84 |
20 |
exp = f[0]; |
85 |
20 |
conclusion = d_false; |
86 |
|
} |
87 |
|
else |
88 |
|
{ |
89 |
|
Unhandled() << "TheoryEngineProofGenerator::getProofFor: unexpected fact " |
90 |
|
<< f << std::endl; |
91 |
|
return nullptr; |
92 |
|
} |
93 |
|
// get the assumptions to assume in a scope |
94 |
14571 |
if (exp.getKind() == AND) |
95 |
|
{ |
96 |
119586 |
for (const Node& fc : exp) |
97 |
|
{ |
98 |
106438 |
scopeAssumps.push_back(fc); |
99 |
|
} |
100 |
|
} |
101 |
|
else |
102 |
|
{ |
103 |
1423 |
scopeAssumps.push_back(exp); |
104 |
|
} |
105 |
14571 |
Trace("tepg-debug") << "...get proof body" << std::endl; |
106 |
|
// get the proof for conclusion |
107 |
29142 |
std::shared_ptr<ProofNode> pfb = lcp->getProofFor(conclusion); |
108 |
14571 |
Trace("tepg-debug") << "...mkScope" << std::endl; |
109 |
|
// call the scope method of proof node manager |
110 |
29142 |
std::shared_ptr<ProofNode> pf = d_pnm->mkScope(pfb, scopeAssumps); |
111 |
|
|
112 |
14571 |
if (pf->getResult() != f) |
113 |
|
{ |
114 |
|
std::stringstream serr; |
115 |
|
serr << "TheoryEngineProofGenerator::getProofFor: Proof: " << std::endl; |
116 |
|
serr << *pf << std::endl; |
117 |
|
serr << "TheoryEngineProofGenerator::getProofFor: unexpected return proof" |
118 |
|
<< std::endl; |
119 |
|
serr << " Expected: " << f << std::endl; |
120 |
|
serr << " Got: " << pf->getResult() << std::endl; |
121 |
|
Unhandled() << serr.str(); |
122 |
|
} |
123 |
14571 |
Trace("tepg-debug") << "...finished" << std::endl; |
124 |
14571 |
return pf; |
125 |
|
} |
126 |
|
|
127 |
64142 |
std::string TheoryEngineProofGenerator::identify() const |
128 |
|
{ |
129 |
64142 |
return "TheoryEngineProofGenerator"; |
130 |
|
} |
131 |
|
|
132 |
28191 |
} // namespace cvc5 |