GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/strings/infer_proof_cons.h Lines: 1 1 100.0 %
Date: 2021-09-15 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
2486
  ~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
  /**
74
   * This returns the proof for fact. This is required for using this class as
75
   * a lazy proof generator.
76
   *
77
   * It should be the case that a call was made to notifyFact(ii) where
78
   * ii.d_conc is fact in this SAT context.
79
   *
80
   * This returns the appropriate application of STRING_INFERENCE so that it
81
   * can be reconstructed if necessary during proof post-processing.
82
   */
83
  std::shared_ptr<ProofNode> getProofFor(Node fact) override;
84
  /** Identify this generator (for debugging, etc..) */
85
  virtual std::string identify() const override;
86
  /**
87
   * Add proof of running convert on the given arguments to CDProof pf. This is
88
   * called lazily during proof post-processing.
89
   */
90
  static bool addProofTo(CDProof* pf,
91
                         Node conc,
92
                         InferenceId infer,
93
                         bool isRev,
94
                         const std::vector<Node>& exp);
95
  /**
96
   * Pack arguments of a STRING_INFERENCE rule application in args. This proof
97
   * rule stores the arguments to the convert method of this class below.
98
   */
99
  static void packArgs(Node conc,
100
                       InferenceId infer,
101
                       bool isRev,
102
                       const std::vector<Node>& exp,
103
                       std::vector<Node>& args);
104
  /**
105
   * Inverse of the above method, which recovers the arguments that were packed
106
   * into the vector args.
107
   */
108
  static bool unpackArgs(const std::vector<Node>& args,
109
                         Node& conc,
110
                         InferenceId& infer,
111
                         bool& isRev,
112
                         std::vector<Node>& exp);
113
114
 private:
115
  /** convert
116
   *
117
   * This method is called when the theory of strings makes an inference
118
   * described by an InferInfo, whose fields are given by the first four
119
   * arguments of this method.
120
   *
121
   * This method converts this call to instructions on what the proof rule
122
   * step(s) are for concluding the conclusion of the inference. This
123
   * information is either:
124
   *
125
   * (A) stored in the argument ps, which consists of:
126
   * - A proof rule identifier (ProofStep::d_rule).
127
   * - The premises of the proof step (ProofStep::d_children).
128
   * - Arguments to the proof step (ProofStep::d_args).
129
   *
130
   * (B) If the proof for the inference cannot be captured by a single
131
   * step, then the d_rule field of ps is not set, and useBuffer is set to
132
   * true. In this case, the argument psb is updated to contain (possibly
133
   * multiple) proof steps for how to construct a proof for the given inference.
134
   * In particular, psb will contain a set of steps that form a proof
135
   * whose conclusion is ii.d_conc and whose free assumptions are ii.d_ant.
136
   */
137
  static void convert(InferenceId infer,
138
                      bool isRev,
139
                      Node conc,
140
                      const std::vector<Node>& exp,
141
                      ProofStep& ps,
142
                      TheoryProofStepBuffer& psb,
143
                      bool& useBuffer);
144
  /**
145
   * Convert length proof. If this method returns true, it adds proof step(s)
146
   * to the buffer psb that conclude lenReq from premises lenExp.
147
   */
148
  static bool convertLengthPf(Node lenReq,
149
                              const std::vector<Node>& lenExp,
150
                              TheoryProofStepBuffer& psb);
151
  /**
152
   * Helper method, adds the proof of (TRANS eqa eqb) into the proof step
153
   * buffer psb, where eqa and eqb are flipped as needed. Returns the
154
   * conclusion, or null if we were not able to construct a TRANS step.
155
   */
156
  static Node convertTrans(Node eqa, Node eqb, TheoryProofStepBuffer& psb);
157
  /**
158
   * Purify core substitution.
159
   *
160
   * When reconstructing proofs for the core strings calculus, we rely on
161
   * sequential substitutions for constructing proofs involving recursive
162
   * computation of normal forms. However, this can be incorrect in cases where
163
   * a term like (str.replace x a b) is being treated as an atomic term,
164
   * and a substitution applied over (str.replace x a b) -> c, x -> d.
165
   * This can lead to the term (str.replace d a b) being generated instead of
166
   * c.
167
   *
168
   * As an example of this method, given input:
169
   *   tgt = (= x (str.++ (f x) c))
170
   *   children = { (= (f x) a), (= x (str.++ b (f x))) }
171
   *   concludeTgtNew = true
172
   * This method updates:
173
   *   tgt = (= x (str.++ k c))
174
   *   children = { (= k a), (= x (str.++ b k)) }
175
   * where k is the purification skolem for (f x). Additionally, it ensures
176
   * that psb has a proof of:
177
   *   (= x (str.++ k c)) from (= x (str.++ (f x) c))
178
   *      ...note the direction, since concludeTgtNew = true
179
   *   (= k a) from (= (f x) a)
180
   *   (= x (str.++ b k)) from (= x (str.++ b (f x)))
181
   * Notice that the resulting substitution can now be safely used as a
182
   * sequential substution, since (f x) has been purified with k. The proofs
183
   * in psb ensure that a proof step involving the purified substitution will
184
   * have the same net effect as a proof step using the original substitution.
185
   *
186
   * @param tgt The term we were originally going to apply the substitution to.
187
   * @param children The premises corresponding to the substitution.
188
   * @param psb The proof step buffer
189
   * @param concludeTgtNew Whether we require proving the purified form of
190
   * tgt from tgt or vice versa.
191
   * @return true if we successfully purified the substitution and the target
192
   * term. Additionally, if successful, we ensure psb contains proofs of
193
   * children'[i] from children[i] for all i, and tgt' from tgt (or vice versa
194
   * based on concludeTgtNew).
195
   */
196
  static bool purifyCoreSubstitution(Node& tgt,
197
                                     std::vector<Node>& children,
198
                                     TheoryProofStepBuffer& psb,
199
                                     bool concludeTgtNew = false);
200
  /**
201
   * Return the purified form of the predicate lit with respect to a set of
202
   * terms to purify, call the returned literal lit'.
203
   * If concludeNew is true, then we add a proof of lit' from lit in psb;
204
   * otherwise we add a proof of lit from lit'.
205
   * Note that string predicates that require purification are string
206
   * (dis)equalities only.
207
   */
208
  static Node purifyCorePredicate(Node lit,
209
                                  bool concludeNew,
210
                                  TheoryProofStepBuffer& psb,
211
                                  std::unordered_set<Node>& termsToPurify);
212
  /**
213
   * Purify term with respect to a set of terms to purify. This replaces
214
   * all terms to purify with their purification variables that occur in
215
   * positions that are relevant for the core calculus of strings (direct
216
   * children of concat or equal).
217
   */
218
  static Node purifyCoreTerm(Node n, std::unordered_set<Node>& termsToPurify);
219
  /** the proof node manager */
220
  ProofNodeManager* d_pnm;
221
  /** The lazy fact map */
222
  NodeInferInfoMap d_lazyFactMap;
223
  /** Reference to the statistics for the theory of strings/sequences. */
224
  SequencesStatistics& d_statistics;
225
};
226
227
}  // namespace strings
228
}  // namespace theory
229
}  // namespace cvc5
230
231
#endif /* CVC5__THEORY__STRINGS__INFER_PROOF_CONS_H */