1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds, 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 |
|
* A utility for updating proof nodes. |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "cvc5_private.h" |
17 |
|
|
18 |
|
#ifndef CVC5__PROOF__PROOF_NODE_UPDATER_H |
19 |
|
#define CVC5__PROOF__PROOF_NODE_UPDATER_H |
20 |
|
|
21 |
|
#include <map> |
22 |
|
#include <memory> |
23 |
|
|
24 |
|
#include "expr/node.h" |
25 |
|
#include "proof/proof_node.h" |
26 |
|
|
27 |
|
namespace cvc5 { |
28 |
|
|
29 |
|
class CDProof; |
30 |
|
class ProofNode; |
31 |
|
class ProofNodeManager; |
32 |
|
|
33 |
|
/** |
34 |
|
* A virtual callback class for updating ProofNode. An example use case of this |
35 |
|
* class is to eliminate a proof rule by expansion. |
36 |
|
*/ |
37 |
|
class ProofNodeUpdaterCallback |
38 |
|
{ |
39 |
|
public: |
40 |
|
ProofNodeUpdaterCallback(); |
41 |
|
virtual ~ProofNodeUpdaterCallback(); |
42 |
|
/** Should proof pn be updated? |
43 |
|
* |
44 |
|
* @param pn the proof node that maybe should be updated |
45 |
|
* @param fa the assumptions in scope |
46 |
|
* @param continueUpdate whether we should continue recursively updating pn |
47 |
|
* @return whether we should run the update method on pn |
48 |
|
*/ |
49 |
|
virtual bool shouldUpdate(std::shared_ptr<ProofNode> pn, |
50 |
|
const std::vector<Node>& fa, |
51 |
|
bool& continueUpdate) = 0; |
52 |
|
/** |
53 |
|
* Update the proof rule application, store steps in cdp. Return true if |
54 |
|
* the proof changed. It can be assumed that cdp contains proofs of each |
55 |
|
* fact in children. |
56 |
|
* |
57 |
|
* If continueUpdate is set to false in this method, then the resulting |
58 |
|
* proof (the proof of res in cdp) is *not* called back to update by the |
59 |
|
* proof node updater, nor are its children recursed. Otherwise, by default, |
60 |
|
* the proof node updater will continue updating the resulting proof and will |
61 |
|
* recursively update its children. This is analogous to marking REWRITE_DONE |
62 |
|
* in a rewrite response. |
63 |
|
*/ |
64 |
|
virtual bool update(Node res, |
65 |
|
PfRule id, |
66 |
|
const std::vector<Node>& children, |
67 |
|
const std::vector<Node>& args, |
68 |
|
CDProof* cdp, |
69 |
|
bool& continueUpdate); |
70 |
|
}; |
71 |
|
|
72 |
|
/** |
73 |
|
* A generic class for updating ProofNode. It is parameterized by a callback |
74 |
|
* class. Its process method runs this callback on all subproofs of a provided |
75 |
|
* ProofNode application that meet some criteria |
76 |
|
* (ProofNodeUpdaterCallback::shouldUpdate) |
77 |
|
* and overwrites them based on the update procedure of the callback |
78 |
|
* (ProofNodeUpdaterCallback::update), which uses local CDProof objects that |
79 |
|
* should be filled in the callback for each ProofNode to update. This update |
80 |
|
* process is applied in a *pre-order* traversal. |
81 |
|
*/ |
82 |
10395 |
class ProofNodeUpdater |
83 |
|
{ |
84 |
|
public: |
85 |
|
/** |
86 |
|
* @param pnm The proof node manager we are using |
87 |
|
* @param cb The callback to apply to each node |
88 |
|
* @param mergeSubproofs Whether to automatically merge subproofs within |
89 |
|
* the same SCOPE that prove the same fact. |
90 |
|
* @param autoSym Whether intermediate CDProof objects passed to updater |
91 |
|
* callbacks automatically introduce SYMM steps. |
92 |
|
*/ |
93 |
|
ProofNodeUpdater(ProofNodeManager* pnm, |
94 |
|
ProofNodeUpdaterCallback& cb, |
95 |
|
bool mergeSubproofs = false, |
96 |
|
bool autoSym = true); |
97 |
|
/** |
98 |
|
* Post-process, which performs the main post-processing technique described |
99 |
|
* above. |
100 |
|
*/ |
101 |
|
void process(std::shared_ptr<ProofNode> pf); |
102 |
|
|
103 |
|
/** |
104 |
|
* Set free assumptions to freeAssumps. This indicates that we expect |
105 |
|
* the proof we are processing to have free assumptions that are in |
106 |
|
* freeAssumps. This enables checking when this is violated, which is |
107 |
|
* expensive in general. It is not recommended that this method is called |
108 |
|
* by default. |
109 |
|
*/ |
110 |
|
void setDebugFreeAssumptions(const std::vector<Node>& freeAssumps); |
111 |
|
|
112 |
|
private: |
113 |
|
/** The proof node manager */ |
114 |
|
ProofNodeManager* d_pnm; |
115 |
|
/** The callback */ |
116 |
|
ProofNodeUpdaterCallback& d_cb; |
117 |
|
/** |
118 |
|
* Post-process, which performs the main post-processing technique described |
119 |
|
* above. |
120 |
|
* |
121 |
|
* @param pf The proof to process |
122 |
|
* @param fa The assumptions of the scope that fa is a subproof of with |
123 |
|
* respect to the original proof. For example, if (SCOPE P :args (A B)), we |
124 |
|
* may call this method on P with fa = { A, B }. |
125 |
|
*/ |
126 |
|
void processInternal(std::shared_ptr<ProofNode> pf, std::vector<Node>& fa); |
127 |
|
/** |
128 |
|
* Update proof node cur based on the callback. This modifies curr using |
129 |
|
* ProofNodeManager::updateNode based on the proof node constructed to |
130 |
|
* replace it by the callback. Return true if cur was updated. If |
131 |
|
* continueUpdate is updated to false, then cur is not updated further |
132 |
|
* and its children are not traversed. |
133 |
|
*/ |
134 |
|
bool runUpdate(std::shared_ptr<ProofNode> cur, |
135 |
|
const std::vector<Node>& fa, |
136 |
|
bool& continueUpdate); |
137 |
|
/** |
138 |
|
* Finalize the node cur. This is called at the moment that it is established |
139 |
|
* that cur will appear in the final proof. We do any final debug checking |
140 |
|
* and add it to resCache/resCacheNcWaiting if we are merging subproofs, where |
141 |
|
* these map result formulas to proof nodes with/without assumptions. |
142 |
|
*/ |
143 |
|
void runFinalize(std::shared_ptr<ProofNode> cur, |
144 |
|
const std::vector<Node>& fa, |
145 |
|
std::map<Node, std::shared_ptr<ProofNode>>& resCache, |
146 |
|
std::map<Node, std::vector<std::shared_ptr<ProofNode>>>& |
147 |
|
resCacheNcWaiting, |
148 |
|
std::unordered_map<const ProofNode*, bool>& cfaMap); |
149 |
|
/** Are we debugging free assumptions? */ |
150 |
|
bool d_debugFreeAssumps; |
151 |
|
/** The initial free assumptions */ |
152 |
|
std::vector<Node> d_freeAssumps; |
153 |
|
/** Whether we are merging subproofs */ |
154 |
|
bool d_mergeSubproofs; |
155 |
|
/** |
156 |
|
* Whether intermediate CDProof objects passed to updater callbacks |
157 |
|
* automatically introduce SYMM steps. |
158 |
|
*/ |
159 |
|
bool d_autoSym; |
160 |
|
}; |
161 |
|
|
162 |
|
} // namespace cvc5 |
163 |
|
|
164 |
|
#endif |