1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds, Andres Noetzli, 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 |
|
* Customized inference manager for the theory of strings. |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "cvc5_private.h" |
17 |
|
|
18 |
|
#ifndef CVC5__THEORY__STRINGS__INFERENCE_MANAGER_H |
19 |
|
#define CVC5__THEORY__STRINGS__INFERENCE_MANAGER_H |
20 |
|
|
21 |
|
#include <map> |
22 |
|
#include <vector> |
23 |
|
|
24 |
|
#include "context/cdhashset.h" |
25 |
|
#include "context/context.h" |
26 |
|
#include "expr/node.h" |
27 |
|
#include "proof/proof_node_manager.h" |
28 |
|
#include "theory/ext_theory.h" |
29 |
|
#include "theory/inference_manager_buffered.h" |
30 |
|
#include "theory/output_channel.h" |
31 |
|
#include "theory/strings/infer_info.h" |
32 |
|
#include "theory/strings/infer_proof_cons.h" |
33 |
|
#include "theory/strings/sequences_stats.h" |
34 |
|
#include "theory/strings/solver_state.h" |
35 |
|
#include "theory/strings/term_registry.h" |
36 |
|
#include "theory/theory_inference_manager.h" |
37 |
|
#include "theory/uf/equality_engine.h" |
38 |
|
|
39 |
|
namespace cvc5 { |
40 |
|
namespace theory { |
41 |
|
namespace strings { |
42 |
|
|
43 |
|
/** Inference Manager |
44 |
|
* |
45 |
|
* The purpose of this class is to process inference steps for strategies |
46 |
|
* in the theory of strings. |
47 |
|
* |
48 |
|
* In particular, inferences are given to this class via calls to functions: |
49 |
|
* |
50 |
|
* sendInternalInference, sendInference, sendSplit |
51 |
|
* |
52 |
|
* This class decides how the conclusion of these calls will be processed. |
53 |
|
* It primarily has to decide whether the conclusions will be processed: |
54 |
|
* |
55 |
|
* (1) Internally in the strings solver, via calls to equality engine's |
56 |
|
* assertLiteral and assertPredicate commands. We refer to these literals as |
57 |
|
* "facts", |
58 |
|
* (2) Externally on the output channel of theory of strings as "lemmas", |
59 |
|
* (3) External on the output channel as "conflicts" (when a conclusion of an |
60 |
|
* inference is false). |
61 |
|
* |
62 |
|
* It buffers facts and lemmas in vectors d_pending and d_pending_lem |
63 |
|
* respectively. |
64 |
|
* |
65 |
|
* When applicable, facts can be flushed to the equality engine via a call to |
66 |
|
* doPendingFacts, and lemmas can be flushed to the output channel via a call |
67 |
|
* to doPendingLemmas. |
68 |
|
* |
69 |
|
* It also manages other kinds of interaction with the output channel of the |
70 |
|
* theory of strings, e.g. sendPhaseRequirement, setIncomplete, and |
71 |
|
* with the extended theory object e.g. markCongruent. |
72 |
|
*/ |
73 |
|
class InferenceManager : public InferenceManagerBuffered |
74 |
|
{ |
75 |
|
typedef context::CDHashSet<Node> NodeSet; |
76 |
|
typedef context::CDHashMap<Node, Node> NodeNodeMap; |
77 |
|
friend class InferInfo; |
78 |
|
|
79 |
|
public: |
80 |
|
InferenceManager(Theory& t, |
81 |
|
SolverState& s, |
82 |
|
TermRegistry& tr, |
83 |
|
ExtTheory& e, |
84 |
|
SequencesStatistics& statistics, |
85 |
|
ProofNodeManager* pnm); |
86 |
9924 |
~InferenceManager() {} |
87 |
|
|
88 |
|
/** |
89 |
|
* Do pending method. This processes all pending facts, lemmas and pending |
90 |
|
* phase requests based on the policy of this manager. This means that |
91 |
|
* we process the pending facts first and abort if in conflict. Otherwise, we |
92 |
|
* process the pending lemmas and then the pending phase requirements. |
93 |
|
* Notice that we process the pending lemmas even if there were facts. |
94 |
|
*/ |
95 |
|
void doPending(); |
96 |
|
|
97 |
|
/** send internal inferences |
98 |
|
* |
99 |
|
* This is called when we have inferred exp => conc, where exp is a set |
100 |
|
* of equalities and disequalities that hold in the current equality engine. |
101 |
|
* This method adds equalities and disequalities ~( s = t ) via |
102 |
|
* sendInference such that both s and t are either constants or terms |
103 |
|
* that already occur in the equality engine, and ~( s = t ) is a consequence |
104 |
|
* of conc. This function can be seen as a "conservative" version of |
105 |
|
* sendInference below in that it does not introduce any new non-constant |
106 |
|
* terms to the state. |
107 |
|
* |
108 |
|
* The argument infer identifies the reason for the inference. |
109 |
|
* This is used for debugging and statistics purposes. |
110 |
|
* |
111 |
|
* Return true if the inference is complete, in the sense that we infer |
112 |
|
* inferences that are equivalent to conc. This returns false e.g. if conc |
113 |
|
* (or one of its conjuncts if it is a conjunction) was not inferred due |
114 |
|
* to the criteria mentioned above. |
115 |
|
*/ |
116 |
|
bool sendInternalInference(std::vector<Node>& exp, |
117 |
|
Node conc, |
118 |
|
InferenceId infer); |
119 |
|
|
120 |
|
/** send inference |
121 |
|
* |
122 |
|
* This function should be called when exp => eq. The set exp |
123 |
|
* contains literals that are explainable, i.e. those that hold in the |
124 |
|
* equality engine of the theory of strings. On the other hand, the set |
125 |
|
* noExplain contains nodes that are not explainable by the theory of strings. |
126 |
|
* This method may call sendLemma or otherwise add a InferInfo to d_pending, |
127 |
|
* indicating a fact should be asserted to the equality engine. Overall, the |
128 |
|
* result of this method is one of the following: |
129 |
|
* |
130 |
|
* [1] (No-op) Do nothing if eq is equivalent to true, |
131 |
|
* |
132 |
|
* [2] (Infer) Indicate that eq should be added to the equality engine of this |
133 |
|
* class with explanation exp, where exp is a set of literals that currently |
134 |
|
* hold in the equality engine. We add this to the pending vector d_pending. |
135 |
|
* |
136 |
|
* [3] (Lemma) Indicate that the lemma |
137 |
|
* ( EXPLAIN(exp \ noExplain) ^ noExplain ) => eq |
138 |
|
* should be sent on the output channel of the theory of strings, where |
139 |
|
* EXPLAIN returns the explanation of the node in exp in terms of the literals |
140 |
|
* asserted to the theory of strings, as computed by the equality engine. |
141 |
|
* This is also added to a pending vector, d_pendingLem. |
142 |
|
* |
143 |
|
* [4] (Conflict) Immediately report a conflict EXPLAIN(exp) on the output |
144 |
|
* channel of the theory of strings. |
145 |
|
* |
146 |
|
* Determining which case to apply depends on the form of eq and whether |
147 |
|
* noExplain is empty. In particular, lemmas must be used whenever noExplain |
148 |
|
* is non-empty, conflicts are used when noExplain is empty and eq is false. |
149 |
|
* |
150 |
|
* @param exp The explanation of eq. |
151 |
|
* @param noExplain The subset of exp that cannot be explained by the |
152 |
|
* equality engine. This may impact whether we are processing this call as a |
153 |
|
* fact or as a lemma. |
154 |
|
* @param eq The conclusion. |
155 |
|
* @param infer Identifies the reason for inference, used for |
156 |
|
* debugging. This updates the statistics about the number of inferences made |
157 |
|
* of each type. |
158 |
|
* @param isRev Whether this is the "reverse variant" of the inference, which |
159 |
|
* is used as a hint for proof reconstruction. |
160 |
|
* @param asLemma If true, then this method will send a lemma instead |
161 |
|
* of a fact whenever applicable. |
162 |
|
* @return true if the inference was not trivial (e.g. its conclusion did |
163 |
|
* not rewrite to true). |
164 |
|
*/ |
165 |
|
bool sendInference(const std::vector<Node>& exp, |
166 |
|
const std::vector<Node>& noExplain, |
167 |
|
Node eq, |
168 |
|
InferenceId infer, |
169 |
|
bool isRev = false, |
170 |
|
bool asLemma = false); |
171 |
|
/** same as above, but where noExplain is empty */ |
172 |
|
bool sendInference(const std::vector<Node>& exp, |
173 |
|
Node eq, |
174 |
|
InferenceId infer, |
175 |
|
bool isRev = false, |
176 |
|
bool asLemma = false); |
177 |
|
|
178 |
|
/** Send inference |
179 |
|
* |
180 |
|
* This implements the above methods for the InferInfo object. It is called |
181 |
|
* by the methods above. |
182 |
|
* |
183 |
|
* The inference info ii should have a rewritten conclusion and should not be |
184 |
|
* trivial (InferInfo::isTrivial). It is the responsibility of the caller to |
185 |
|
* ensure this. |
186 |
|
* |
187 |
|
* If the flag asLemma is true, then this method will send a lemma instead |
188 |
|
* of a fact whenever applicable. |
189 |
|
*/ |
190 |
|
void sendInference(InferInfo& ii, bool asLemma = false); |
191 |
|
/** Send split |
192 |
|
* |
193 |
|
* This requests that ( a = b V a != b ) is sent on the output channel as a |
194 |
|
* lemma. We additionally request a phase requirement for the equality a=b |
195 |
|
* with polarity preq. |
196 |
|
* |
197 |
|
* The argument infer identifies the reason for inference, used for |
198 |
|
* debugging. This updates the statistics about the number of |
199 |
|
* inferences made of each type. |
200 |
|
* |
201 |
|
* This method returns true if the split was non-trivial, and false |
202 |
|
* otherwise. A split is trivial if a=b rewrites to a constant. |
203 |
|
*/ |
204 |
|
bool sendSplit(Node a, Node b, InferenceId infer, bool preq = true); |
205 |
|
|
206 |
|
//----------------------------constructing antecedants |
207 |
|
/** |
208 |
|
* Adds equality a = b to the vector exp if a and b are distinct terms. It |
209 |
|
* must be the case that areEqual( a, b ) holds in this context. |
210 |
|
*/ |
211 |
|
void addToExplanation(Node a, Node b, std::vector<Node>& exp) const; |
212 |
|
/** Adds lit to the vector exp if it is non-null */ |
213 |
|
void addToExplanation(Node lit, std::vector<Node>& exp) const; |
214 |
|
//----------------------------end constructing antecedants |
215 |
|
/** |
216 |
|
* Have we processed an inference during this call to check? In particular, |
217 |
|
* this returns true if we have a pending fact or lemma, or have encountered |
218 |
|
* a conflict. |
219 |
|
*/ |
220 |
|
bool hasProcessed() const; |
221 |
|
|
222 |
|
// ------------------------------------------------- extended theory |
223 |
|
/** |
224 |
|
* Mark that extended function is reduced. If contextDepend is true, |
225 |
|
* then this mark is SAT-context dependent, otherwise it is user-context |
226 |
|
* dependent (see ExtTheory::markReduced). |
227 |
|
*/ |
228 |
|
void markReduced(Node n, ExtReducedId id, bool contextDepend = true); |
229 |
|
// ------------------------------------------------- end extended theory |
230 |
|
|
231 |
|
/** |
232 |
|
* Called when ii is ready to be processed as a conflict. This makes a |
233 |
|
* trusted node whose generator is the underlying proof equality engine |
234 |
|
* (if it exists), and sends it on the output channel. |
235 |
|
*/ |
236 |
|
void processConflict(const InferInfo& ii); |
237 |
|
|
238 |
|
private: |
239 |
|
/** Called when ii is ready to be processed as a fact */ |
240 |
|
void processFact(InferInfo& ii, ProofGenerator*& pg); |
241 |
|
/** Called when ii is ready to be processed as a lemma */ |
242 |
|
TrustNode processLemma(InferInfo& ii, LemmaProperty& p); |
243 |
|
/** Reference to the solver state of the theory of strings. */ |
244 |
|
SolverState& d_state; |
245 |
|
/** Reference to the term registry of theory of strings */ |
246 |
|
TermRegistry& d_termReg; |
247 |
|
/** the extended theory object for the theory of strings */ |
248 |
|
ExtTheory& d_extt; |
249 |
|
/** Reference to the statistics for the theory of strings/sequences. */ |
250 |
|
SequencesStatistics& d_statistics; |
251 |
|
/** Conversion from inferences to proofs */ |
252 |
|
std::unique_ptr<InferProofCons> d_ipc; |
253 |
|
/** Common constants */ |
254 |
|
Node d_true; |
255 |
|
Node d_false; |
256 |
|
Node d_zero; |
257 |
|
Node d_one; |
258 |
|
}; |
259 |
|
|
260 |
|
} // namespace strings |
261 |
|
} // namespace theory |
262 |
|
} // namespace cvc5 |
263 |
|
|
264 |
|
#endif |