GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/strings/base_solver.h Lines: 2 2 100.0 %
Date: 2021-11-07 Branches: 2 4 50.0 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Andres Noetzli, Mudathir Mohamed
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
 * Base solver for term indexing and constant inference for the
14
 * theory of strings.
15
 */
16
17
#include "cvc5_private.h"
18
19
#ifndef CVC5__THEORY__STRINGS__BASE_SOLVER_H
20
#define CVC5__THEORY__STRINGS__BASE_SOLVER_H
21
22
#include "context/cdhashset.h"
23
#include "context/cdlist.h"
24
#include "smt/env_obj.h"
25
#include "theory/strings/infer_info.h"
26
#include "theory/strings/inference_manager.h"
27
#include "theory/strings/normal_form.h"
28
#include "theory/strings/skolem_cache.h"
29
#include "theory/strings/solver_state.h"
30
#include "theory/strings/term_registry.h"
31
32
namespace cvc5 {
33
namespace theory {
34
namespace strings {
35
36
/** The base solver for the theory of strings
37
 *
38
 * This implements techniques for inferring when terms are congruent in the
39
 * current context, and techniques for inferring when equivalence classes
40
 * are equivalent to constants.
41
 */
42
class BaseSolver : protected EnvObj
43
{
44
  using NodeSet = context::CDHashSet<Node>;
45
46
 public:
47
  BaseSolver(Env& env, SolverState& s, InferenceManager& im);
48
  ~BaseSolver();
49
50
  //-----------------------inference steps
51
  /** check initial
52
   *
53
   * This function initializes term indices for each strings function symbol.
54
   * One key aspect of this construction is that concat terms are indexed by
55
   * their list of non-empty components. For example, if x = "" is an equality
56
   * asserted in this SAT context, then y ++ x ++ z may be indexed by (y,z).
57
   * This method may infer various facts while building these term indices, for
58
   * instance, based on congruence. An example would be inferring:
59
   *   y ++ x ++ z = y ++ z
60
   * if both terms are registered in this SAT context.
61
   *
62
   * This function should be called as a first step of any strategy.
63
   */
64
  void checkInit();
65
  /** check constant equivalence classes
66
   *
67
   * This function infers whether CONCAT terms can be simplified to constants.
68
   * For example, if x = "a" and y = "b" are equalities in the current SAT
69
   * context, then we may infer x ++ "c" ++ y is equivalent to "acb". In this
70
   * case, we infer the fact x ++ "c" ++ y = "acb".
71
   */
72
  void checkConstantEquivalenceClasses();
73
  /** check cardinality
74
   *
75
   * This function checks whether a cardinality inference needs to be applied
76
   * to a set of equivalence classes. For details, see Step 5 of the proof
77
   * procedure from Liang et al, CAV 2014.
78
   */
79
  void checkCardinality();
80
  //-----------------------end inference steps
81
82
  //-----------------------query functions
83
  /**
84
   * Is n congruent to another term in the current context that has not been
85
   * marked congruent? If so, we can ignore n.
86
   *
87
   * Note this and the functions in this block below are valid during a full
88
   * effort check after a call to checkInit.
89
   */
90
  bool isCongruent(Node n);
91
  /**
92
   * Get the constant that the equivalence class eqc is entailed to be equal
93
   * to, or null if none exist.
94
   */
95
  Node getConstantEqc(Node eqc);
96
  /**
97
   * Same as above, where the explanation for n = c is added to exp if c is
98
   * the (non-null) return value of this function, where n is a term in the
99
   * equivalence class of eqc.
100
   */
101
  Node explainConstantEqc(Node n, Node eqc, std::vector<Node>& exp);
102
  /**
103
   * Same as above, for "best content" terms.
104
   */
105
  Node explainBestContentEqc(Node n, Node eqc, std::vector<Node>& exp);
106
  /**
107
   * Get the set of equivalence classes of type string.
108
   */
109
  const std::vector<Node>& getStringEqc() const;
110
  //-----------------------end query functions
111
112
 private:
113
  /**
114
   * The information that we associated with each equivalence class.
115
   *
116
   * Example 1. Consider the equivalence class { r, x++"a"++y, x++z }, and
117
   * assume x = "" and y = "bb" in the current context. We have that
118
   *   d_bestContent = "abb",
119
   *   d_base = x++"a"++y
120
   *   d_exp = ( x = "" AND y = "bb" )
121
   *
122
   * Example 2. Consider the equivalence class { r, x++"a"++w++y, x++z }, and
123
   * assume x = "" and y = "bb" in the current context. We have that
124
   *   d_bestContent = "a" ++ w ++ "bb",
125
   *   d_bestScore = 3
126
   *   d_base = x++"a"++w++y
127
   *   d_exp = ( x = "" AND y = "bb" )
128
   *
129
   * This information is computed during checkInit and is used during various
130
   * inference schemas for deriving inferences.
131
   */
132
1198552
  struct BaseEqcInfo
133
  {
134
    /**
135
     * Either a constant or a concatentation of constants and variables that
136
     * this equivalence class is entailed to be equal to. If it is a
137
     * concatenation, this is the concatenation that is currently known to have
138
     * the highest score (see `d_bestScore`).
139
     */
140
    Node d_bestContent;
141
    /**
142
     * The sum of the number of characters in the string literals of
143
     * `d_bestContent`.
144
     */
145
    size_t d_bestScore;
146
    /**
147
     * The term in the equivalence class that is entailed to be equal to
148
     * `d_bestContent`.
149
     */
150
    Node d_base;
151
    /** This term explains why `d_bestContent` is equal to `d_base`. */
152
    Node d_exp;
153
  };
154
155
  /**
156
   * A term index that considers terms modulo flattening and constant merging
157
   * for concatenation terms.
158
   */
159
4221312
  class TermIndex
160
  {
161
   public:
162
    /** Add n to this trie
163
     *
164
     * A term is indexed by flattening arguments of concatenation terms,
165
     * and replacing them by (non-empty) constants when possible, for example
166
     * if n is (str.++ x y z) and x = "abc" and y = "" are asserted, then n is
167
     * indexed by ("abc", z).
168
     *
169
     * index: the child of n we are currently processing,
170
     * s : reference to solver state,
171
     * er : the representative of the empty equivalence class.
172
     *
173
     * We store the vector of terms that n was indexed by in the vector c.
174
     */
175
    Node add(TNode n,
176
             unsigned index,
177
             const SolverState& s,
178
             Node er,
179
             std::vector<Node>& c);
180
    /** Clear this trie */
181
    void clear() { d_children.clear(); }
182
    /** The data at this node of the trie */
183
    Node d_data;
184
    /** The children of this node of the trie */
185
    std::map<TNode, TermIndex> d_children;
186
  };
187
  /**
188
   * This method is called as we are traversing the term index ti, where vecc
189
   * accumulates the list of constants in the path to ti. If ti has a non-null
190
   * data n, then we have inferred that d_data is equivalent to the
191
   * constant specified by vecc.
192
   *
193
   * @param ti The term index for string concatenations
194
   * @param vecc The list of constants in the path to ti
195
   * @param ensureConst If true, require that each element in the path is
196
   *                    constant
197
   * @param isConst If true, the path so far only includes constants
198
   */
199
  void checkConstantEquivalenceClasses(TermIndex* ti,
200
                                       std::vector<Node>& vecc,
201
                                       bool ensureConst = true,
202
                                       bool isConst = true);
203
  /**
204
   * Check cardinality for type tn. This adds a lemma corresponding to
205
   * cardinality for terms of type tn, if applicable.
206
   *
207
   * @param tn The string-like type of terms we are considering,
208
   * @param cols The list of collections of equivalence classes. This is a
209
   * partition of all string equivalence classes, grouped by those with equal
210
   * lengths.
211
   * @param lts The length of each of the collections in cols.
212
   */
213
  void checkCardinalityType(TypeNode tn,
214
                            std::vector<std::vector<Node> >& cols,
215
                            std::vector<Node>& lts);
216
  /** The solver state object */
217
  SolverState& d_state;
218
  /** The (custom) output channel of the theory of strings */
219
  InferenceManager& d_im;
220
  /** Commonly used constants */
221
  Node d_emptyString;
222
  Node d_false;
223
  /**
224
   * A congruence class is a set of terms f( t1 ), ..., f( tn ) where
225
   * t1 = ... = tn. Congruence classes are important since all but
226
   * one of the above terms (the representative of the congruence class)
227
   * can be ignored by the solver.
228
   *
229
   * This set contains a set of nodes that are not representatives of their
230
   * congruence class. This set is used to skip reasoning about terms in
231
   * various inference schemas implemented by this class.
232
   */
233
  NodeSet d_congruent;
234
  /**
235
   * Maps equivalence classes to their info, see description of `BaseEqcInfo`
236
   * for more information.
237
   */
238
  std::map<Node, BaseEqcInfo> d_eqcInfo;
239
  /** The list of equivalence classes of type string */
240
  std::vector<Node> d_stringsEqc;
241
  /** A term index for each type, function kind pair */
242
  std::map<TypeNode, std::map<Kind, TermIndex> > d_termIndex;
243
  /** the cardinality of the alphabet */
244
  uint32_t d_cardSize;
245
}; /* class BaseSolver */
246
247
}  // namespace strings
248
}  // namespace theory
249
}  // namespace cvc5
250
251
#endif /* CVC5__THEORY__STRINGS__BASE_SOLVER_H */