GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/strings/inference_manager.h Lines: 1 1 100.0 %
Date: 2021-05-24 Branches: 0 0 0.0 %

Line Exec Source
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 "expr/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
9459
  ~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