GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/strings/extf_solver.h Lines: 4 4 100.0 %
Date: 2021-09-18 Branches: 1 2 50.0 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Andres Noetzli, Tim King
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
 * Solver for extended functions of theory of strings.
14
 */
15
16
#include "cvc5_private.h"
17
18
#ifndef CVC5__THEORY__STRINGS__EXTF_SOLVER_H
19
#define CVC5__THEORY__STRINGS__EXTF_SOLVER_H
20
21
#include <map>
22
#include <vector>
23
24
#include "context/cdo.h"
25
#include "expr/node.h"
26
#include "smt/env_obj.h"
27
#include "theory/ext_theory.h"
28
#include "theory/strings/base_solver.h"
29
#include "theory/strings/core_solver.h"
30
#include "theory/strings/inference_manager.h"
31
#include "theory/strings/sequences_stats.h"
32
#include "theory/strings/skolem_cache.h"
33
#include "theory/strings/solver_state.h"
34
#include "theory/strings/strings_rewriter.h"
35
#include "theory/strings/theory_strings_preprocess.h"
36
37
namespace cvc5 {
38
namespace theory {
39
namespace strings {
40
41
/**
42
 * Non-static information about an extended function t. This information is
43
 * constructed and used during the check extended function evaluation
44
 * inference schema.
45
 *
46
 * In the following, we refer to the "context-dependent simplified form"
47
 * of a term t to be the result of rewriting t * sigma, where sigma is a
48
 * derivable substitution in the current context. For example, the
49
 * context-depdendent simplified form of contains( x++y, "a" ) given
50
 * sigma = { x -> "" } is contains(y,"a").
51
 */
52
547816
class ExtfInfoTmp
53
{
54
 public:
55
547816
  ExtfInfoTmp() : d_modelActive(true) {}
56
  /**
57
   * If s is in d_ctn[true] (resp. d_ctn[false]), then contains( t, s )
58
   * (resp. ~contains( t, s )) holds in the current context. The vector
59
   * d_ctnFrom is the explanation for why this holds. For example,
60
   * if d_ctn[false][i] is "A", then d_ctnFrom[false][i] might be
61
   * t = x ++ y AND x = "" AND y = "B".
62
   */
63
  std::map<bool, std::vector<Node> > d_ctn;
64
  std::map<bool, std::vector<Node> > d_ctnFrom;
65
  /**
66
   * The constant that t is entailed to be equal to, or null if none exist.
67
   */
68
  Node d_const;
69
  /**
70
   * The explanation for why t is equal to its context-dependent simplified
71
   * form.
72
   */
73
  std::vector<Node> d_exp;
74
  /** This flag is false if t is reduced in the model. */
75
  bool d_modelActive;
76
};
77
78
/**
79
 * Extended function solver for the theory of strings. This manages extended
80
 * functions for the theory of strings using a combination of context-dependent
81
 * simplification (Reynolds et al CAV 2017) and lazy reductions.
82
 */
83
class ExtfSolver : protected EnvObj
84
{
85
  typedef context::CDHashSet<Node> NodeSet;
86
87
 public:
88
  ExtfSolver(Env& env,
89
             SolverState& s,
90
             InferenceManager& im,
91
             TermRegistry& tr,
92
             StringsRewriter& rewriter,
93
             BaseSolver& bs,
94
             CoreSolver& cs,
95
             ExtTheory& et,
96
             SequencesStatistics& statistics);
97
  ~ExtfSolver();
98
  /** check extended functions evaluation
99
   *
100
   * This applies "context-dependent simplification" for all active extended
101
   * function terms in this SAT context. This infers facts of the form:
102
   *   x = c => f( t1 ... tn ) = c'
103
   * where the rewritten form of f( t1...tn ) { x |-> c } is c', and x = c
104
   * is a (tuple of) equalities that are asserted in this SAT context, and
105
   * f( t1 ... tn ) is a term from this SAT context.
106
   *
107
   * For more details, this is steps 4 when effort=0 and step 6 when
108
   * effort=1 from Strategy 1 in Reynolds et al, "Scaling up DPLL(T) String
109
   * Solvers using Context-Dependent Simplification", CAV 2017. When called with
110
   * effort=3, we apply context-dependent simplification based on model values.
111
   */
112
  void checkExtfEval(int effort);
113
  /** check extended function reductions
114
   *
115
   * This adds "reduction" lemmas for each active extended function in this SAT
116
   * context. These are generally lemmas of the form:
117
   *   F[t1...tn,k] ^ f( t1 ... tn ) = k
118
   * where f( t1 ... tn ) is an active extended function, k is a fresh constant
119
   * and F is a formula that constrains k based on the definition of f.
120
   *
121
   * For more details, this is step 7 from Strategy 1 in Reynolds et al,
122
   * CAV 2017. We stratify this in practice, where calling this with effort=1
123
   * reduces some of the "easier" extended functions, and effort=2 reduces
124
   * the rest.
125
   */
126
  void checkExtfReductions(int effort);
127
  /** get preprocess module */
128
  StringsPreprocess* getPreprocess() { return &d_preproc; }
129
130
  /**
131
   * Get the current substitution for term n.
132
   *
133
   * This method returns a term that n is currently equal to in the current
134
   * context. It updates exp to contain an explanation of why it is currently
135
   * equal to that term.
136
   *
137
   * The argument effort determines what kind of term to return, either
138
   * a constant in the equivalence class of n (effort=0), the normal form of
139
   * n (effort=1,2) or the model value of n (effort>=3). The latter is only
140
   * valid at LAST_CALL effort. If a term of the above form cannot be returned,
141
   * then n itself is returned.
142
   */
143
  Node getCurrentSubstitutionFor(int effort, Node n, std::vector<Node>& exp);
144
  /** get mapping from extended functions to their information
145
   *
146
   * This information is valid during a full effort check after a call to
147
   * checkExtfEval.
148
   */
149
  const std::map<Node, ExtfInfoTmp>& getInfo() const;
150
  //---------------------------------- information about ExtTheory
151
  /** Are there any active extended functions? */
152
  bool hasExtendedFunctions() const;
153
  /**
154
   * Get the function applications of kind k that are active in the current
155
   * context (see ExtTheory::getActive).
156
   */
157
  std::vector<Node> getActive(Kind k) const;
158
  //---------------------------------- end information about ExtTheory
159
  /**
160
   * Print the relevant information regarding why we have a model, return as a
161
   * string.
162
   */
163
  std::string debugPrintModel();
164
165
 private:
166
  /** do reduction
167
   *
168
   * This is called when an extended function application n is not able to be
169
   * simplified by context-depdendent simplification, and we are resorting to
170
   * expanding n to its full semantics via a reduction. This method returns
171
   * true if it successfully reduced n by some reduction. If so, it either
172
   * caches that the reduction lemma was sent, or marks n as reduced in this
173
   * SAT-context. The argument effort has the same meaning as in
174
   * checkExtfReductions.
175
   */
176
  bool doReduction(int effort, Node n);
177
  /** check extended function inferences
178
   *
179
   * This function makes additional inferences for n that do not contribute
180
   * to its reduction, but may help show a refutation.
181
   *
182
   * This function is called when the context-depdendent simplified form of
183
   * n is nr. The argument "in" is the information object for n. The argument
184
   * "effort" has the same meaning as the effort argument of checkExtfEval.
185
   */
186
  void checkExtfInference(Node n, Node nr, ExtfInfoTmp& in, int effort);
187
  /** The solver state object */
188
  SolverState& d_state;
189
  /** The (custom) output channel of the theory of strings */
190
  InferenceManager& d_im;
191
  /** Reference to the term registry of theory of strings */
192
  TermRegistry& d_termReg;
193
  /** The theory rewriter for this theory. */
194
  StringsRewriter& d_rewriter;
195
  /** reference to the base solver, used for certain queries */
196
  BaseSolver& d_bsolver;
197
  /** reference to the core solver, used for certain queries */
198
  CoreSolver& d_csolver;
199
  /** the extended theory object for the theory of strings */
200
  ExtTheory& d_extt;
201
  /** Reference to the statistics for the theory of strings/sequences. */
202
  SequencesStatistics& d_statistics;
203
  /** preprocessing utility, for performing strings reductions */
204
  StringsPreprocess d_preproc;
205
  /** Common constants */
206
  Node d_true;
207
  Node d_false;
208
  /** Empty vector */
209
  std::vector<Node> d_emptyVec;
210
  /** map extended functions to the above information */
211
  std::map<Node, ExtfInfoTmp> d_extfInfoTmp;
212
  /** any non-reduced extended functions exist? */
213
  context::CDO<bool> d_hasExtf;
214
  /** extended functions inferences cache */
215
  NodeSet d_extfInferCache;
216
  /** The set of extended functions we have sent reduction lemmas for */
217
  NodeSet d_reduced;
218
};
219
220
/** An extended theory callback */
221
9937
class StringsExtfCallback : public ExtTheoryCallback
222
{
223
 public:
224
9940
  StringsExtfCallback() : d_esolver(nullptr) {}
225
  /**
226
   * Get current substitution based on the underlying extended function
227
   * solver.
228
   */
229
  bool getCurrentSubstitution(int effort,
230
                              const std::vector<Node>& vars,
231
                              std::vector<Node>& subs,
232
                              std::map<Node, std::vector<Node> >& exp) override;
233
  /** The extended function solver */
234
  ExtfSolver* d_esolver;
235
};
236
237
}  // namespace strings
238
}  // namespace theory
239
}  // namespace cvc5
240
241
#endif /* CVC5__THEORY__STRINGS__EXTF_SOLVER_H */