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

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, 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
 * Inference to proof conversion.
14
 */
15
16
#include "cvc5_private.h"
17
18
#ifndef CVC5__THEORY__STRINGS__INFER_PROOF_CONS_H
19
#define CVC5__THEORY__STRINGS__INFER_PROOF_CONS_H
20
21
#include <vector>
22
23
#include "expr/node.h"
24
#include "proof/proof_checker.h"
25
#include "proof/proof_rule.h"
26
#include "proof/theory_proof_step_buffer.h"
27
#include "theory/builtin/proof_checker.h"
28
#include "theory/strings/infer_info.h"
29
#include "theory/strings/sequences_stats.h"
30
#include "theory/uf/proof_equality_engine.h"
31
32
namespace cvc5 {
33
namespace theory {
34
namespace strings {
35
36
/**
37
 * Converts between the strings-specific (untrustworthy) InferInfo class and
38
 * information about how to construct a trustworthy proof step
39
 * (PfRule, children, args). It acts as a (lazy) proof generator where the
40
 * former is registered via notifyFact and the latter is asked for in
41
 * getProofFor, typically by the proof equality engine.
42
 *
43
 * The main (private) method of this class is convert below, which is
44
 * called when we need to construct a proof node from an InferInfo.
45
 *
46
 * This class uses lazy proof reconstruction. Namely, the getProofFor method
47
 * returns applications of the rule STRING_INFERENCE, which store the arguments
48
 * to the proof conversion routine "convert" below.
49
 */
50
class InferProofCons : public ProofGenerator
51
{
52
  typedef context::CDHashMap<Node, std::shared_ptr<InferInfo>> NodeInferInfoMap;
53
54
 public:
55
  InferProofCons(context::Context* c,
56
                 ProofNodeManager* pnm,
57
                 SequencesStatistics& statistics);
58
21488
  ~InferProofCons() {}
59
  /**
60
   * This is called to notify that ii is an inference that may need a proof
61
   * in the future.
62
   *
63
   * In detail, this class should be prepared to respond to a call to:
64
   *   getProofFor(ii.d_conc)
65
   * in the remainder of the SAT context. This method copies ii and stores it
66
   * in the context-dependent map d_lazyFactMap below.
67
   *
68
   * This is used for lazy proof construction, where proofs are constructed
69
   * only for facts that are explained.
70
   */
71
  void notifyFact(const InferInfo& ii);
72
  /**
73
   * Same as above, but always overwrites. This is used for lemmas and
74
   * conflicts, which do not necessarily have unique conclusions.
75
   */
76
  void notifyLemma(const InferInfo& ii);
77
78
  /**
79
   * This returns the proof for fact. This is required for using this class as
80
   * a lazy proof generator.
81
   *
82
   * It should be the case that a call was made to notifyFact(ii) where
83
   * ii.d_conc is fact in this SAT context.
84
   *
85
   * This returns the appropriate application of STRING_INFERENCE so that it
86
   * can be reconstructed if necessary during proof post-processing.
87
   */
88
  std::shared_ptr<ProofNode> getProofFor(Node fact) override;
89
  /** Identify this generator (for debugging, etc..) */
90
  virtual std::string identify() const override;
91
  /**
92
   * Add proof of running convert on the given arguments to CDProof pf. This is
93
   * called lazily during proof post-processing.
94
   */
95
  static bool addProofTo(CDProof* pf,
96
                         Node conc,
97
                         InferenceId infer,
98
                         bool isRev,
99
                         const std::vector<Node>& exp);
100
  /**
101
   * Pack arguments of a STRING_INFERENCE rule application in args. This proof
102
   * rule stores the arguments to the convert method of this class below.
103
   */
104
  static void packArgs(Node conc,
105
                       InferenceId infer,
106
                       bool isRev,
107
                       const std::vector<Node>& exp,
108
                       std::vector<Node>& args);
109
  /**
110
   * Inverse of the above method, which recovers the arguments that were packed
111
   * into the vector args.
112
   */
113
  static bool unpackArgs(const std::vector<Node>& args,
114
                         Node& conc,
115
                         InferenceId& infer,
116
                         bool& isRev,
117
                         std::vector<Node>& exp);
118
119
 private:
120
  /** convert
121
   *
122
   * This method is called when the theory of strings makes an inference
123
   * described by an InferInfo, whose fields are given by the first four
124
   * arguments of this method.
125
   *
126
   * This method converts this call to instructions on what the proof rule
127
   * step(s) are for concluding the conclusion of the inference. This
128
   * information is either:
129
   *
130
   * (A) stored in the argument ps, which consists of:
131
   * - A proof rule identifier (ProofStep::d_rule).
132
   * - The premises of the proof step (ProofStep::d_children).
133
   * - Arguments to the proof step (ProofStep::d_args).
134
   *
135
   * (B) If the proof for the inference cannot be captured by a single
136
   * step, then the d_rule field of ps is not set, and useBuffer is set to
137
   * true. In this case, the argument psb is updated to contain (possibly
138
   * multiple) proof steps for how to construct a proof for the given inference.
139
   * In particular, psb will contain a set of steps that form a proof
140
   * whose conclusion is ii.d_conc and whose free assumptions are ii.d_ant.
141
   */
142
  static void convert(InferenceId infer,
143
                      bool isRev,
144
                      Node conc,
145
                      const std::vector<Node>& exp,
146
                      ProofStep& ps,
147
                      TheoryProofStepBuffer& psb,
148
                      bool& useBuffer);
149
  /**
150
   * Convert length proof. If this method returns true, it adds proof step(s)
151
   * to the buffer psb that conclude lenReq from premises lenExp.
152
   */
153
  static bool convertLengthPf(Node lenReq,
154
                              const std::vector<Node>& lenExp,
155
                              TheoryProofStepBuffer& psb);
156
  /**
157
   * Helper method, adds the proof of (TRANS eqa eqb) into the proof step
158
   * buffer psb, where eqa and eqb are flipped as needed. Returns the
159
   * conclusion, or null if we were not able to construct a TRANS step.
160
   */
161
  static Node convertTrans(Node eqa, Node eqb, TheoryProofStepBuffer& psb);
162
  /**
163
   * Purify core substitution.
164
   *
165
   * When reconstructing proofs for the core strings calculus, we rely on
166
   * sequential substitutions for constructing proofs involving recursive
167
   * computation of normal forms. However, this can be incorrect in cases where
168
   * a term like (str.replace x a b) is being treated as an atomic term,
169
   * and a substitution applied over (str.replace x a b) -> c, x -> d.
170
   * This can lead to the term (str.replace d a b) being generated instead of
171
   * c.
172
   *
173
   * As an example of this method, given input:
174
   *   tgt = (= x (str.++ (f x) c))
175
   *   children = { (= (f x) a), (= x (str.++ b (f x))) }
176
   *   concludeTgtNew = true
177
   * This method updates:
178
   *   tgt = (= x (str.++ k c))
179
   *   children = { (= k a), (= x (str.++ b k)) }
180
   * where k is the purification skolem for (f x). Additionally, it ensures
181
   * that psb has a proof of:
182
   *   (= x (str.++ k c)) from (= x (str.++ (f x) c))
183
   *      ...note the direction, since concludeTgtNew = true
184
   *   (= k a) from (= (f x) a)
185
   *   (= x (str.++ b k)) from (= x (str.++ b (f x)))
186
   * Notice that the resulting substitution can now be safely used as a
187
   * sequential substution, since (f x) has been purified with k. The proofs
188
   * in psb ensure that a proof step involving the purified substitution will
189
   * have the same net effect as a proof step using the original substitution.
190
   *
191
   * @param tgt The term we were originally going to apply the substitution to.
192
   * @param children The premises corresponding to the substitution.
193
   * @param psb The proof step buffer
194
   * @param concludeTgtNew Whether we require proving the purified form of
195
   * tgt from tgt or vice versa.
196
   * @return true if we successfully purified the substitution and the target
197
   * term. Additionally, if successful, we ensure psb contains proofs of
198
   * children'[i] from children[i] for all i, and tgt' from tgt (or vice versa
199
   * based on concludeTgtNew).
200
   */
201
  static bool purifyCoreSubstitution(Node& tgt,
202
                                     std::vector<Node>& children,
203
                                     TheoryProofStepBuffer& psb,
204
                                     bool concludeTgtNew = false);
205
  /**
206
   * Return the purified form of the predicate lit with respect to a set of
207
   * terms to purify, call the returned literal lit'.
208
   * If concludeNew is true, then we add a proof of lit' from lit in psb;
209
   * otherwise we add a proof of lit from lit'.
210
   * Note that string predicates that require purification are string
211
   * (dis)equalities only.
212
   */
213
  static Node purifyCorePredicate(Node lit,
214
                                  bool concludeNew,
215
                                  TheoryProofStepBuffer& psb,
216
                                  std::unordered_set<Node>& termsToPurify);
217
  /**
218
   * Purify term with respect to a set of terms to purify. This replaces
219
   * all terms to purify with their purification variables that occur in
220
   * positions that are relevant for the core calculus of strings (direct
221
   * children of concat or equal).
222
   */
223
  static Node purifyCoreTerm(Node n, std::unordered_set<Node>& termsToPurify);
224
  /** the proof node manager */
225
  ProofNodeManager* d_pnm;
226
  /** The lazy fact map */
227
  NodeInferInfoMap d_lazyFactMap;
228
  /** Reference to the statistics for the theory of strings/sequences. */
229
  SequencesStatistics& d_statistics;
230
};
231
232
}  // namespace strings
233
}  // namespace theory
234
}  // namespace cvc5
235
236
#endif /* CVC5__THEORY__STRINGS__INFER_PROOF_CONS_H */