GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/sygus/sygus_repair_const.h Lines: 1 1 100.0 %
Date: 2021-08-06 Branches: 0 0 0.0 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Mathias Preiner, 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
 * sygus_repair_const
14
 */
15
16
#include "cvc5_private.h"
17
18
#ifndef CVC5__THEORY__QUANTIFIERS__SYGUS_REPAIR_CONST_H
19
#define CVC5__THEORY__QUANTIFIERS__SYGUS_REPAIR_CONST_H
20
21
#include <unordered_set>
22
#include "expr/node.h"
23
24
namespace cvc5 {
25
26
class LogicInfo;
27
28
namespace theory {
29
namespace quantifiers {
30
31
class TermDbSygus;
32
33
/** SygusRepairConst
34
 *
35
 * This module is used to repair portions of candidate solutions. In particular,
36
 * given a synthesis conjecture:
37
 *   exists f. forall x. P( f, x )
38
 * and a candidate solution f = \x. t[x,r] where r are repairable terms, this
39
 * function checks whether there exists a term of the form \x. t[x,c'] for some
40
 * constants c' such that:
41
 *   forall x. P( (\x. t[x,c']), x )  [***]
42
 * is satisfiable, where notice that the above formula after beta-reduction may
43
 * be one in pure first-order logic in a decidable theory (say linear
44
 * arithmetic). To check this, we invoke a separate instance of the SmtEngine
45
 * within repairSolution(...) below, which if satisfiable gives us the
46
 * valuation for c'.
47
 */
48
class SygusRepairConst
49
{
50
 public:
51
  SygusRepairConst(TermDbSygus* tds);
52
1151
  ~SygusRepairConst() {}
53
  /** initialize
54
   *
55
   * Initialize this class with the base instantiation (body) of the sygus
56
   * conjecture (see SynthConjecture::d_base_inst) and its candidate variables
57
   * (see SynthConjecture::d_candidates).
58
   */
59
  void initialize(Node base_inst, const std::vector<Node>& candidates);
60
  /** repair solution
61
   *
62
   * This function is called when candidates -> candidate_values is a (failed)
63
   * candidate solution for the synthesis conjecture.
64
   *
65
   * If this function returns true, then this class adds to repair_cv the
66
   * repaired version of the solution candidate_values for each candidate,
67
   * where for each index i, repair_cv[i] is obtained by replacing constant
68
   * subterms in candidate_values[i] with others, and
69
   *    candidates -> repair_cv
70
   * is a solution for the synthesis conjecture associated with this class.
71
   * Moreover, it is the case that
72
   *    repair_cv[j] != candidate_values[j], for at least one j.
73
   * We always consider applications of the "any constant" constructors in
74
   * candidate_values to be repairable. In addition, if the flag
75
   * useConstantsAsHoles is true, we consider all constants whose (sygus) type
76
   * admit alls constants to be repairable.
77
   * The repaired solution has the property that it satisfies the synthesis
78
   * conjecture whose body is given by sygusBody.
79
   */
80
  bool repairSolution(Node sygusBody,
81
                      const std::vector<Node>& candidates,
82
                      const std::vector<Node>& candidate_values,
83
                      std::vector<Node>& repair_cv,
84
                      bool useConstantsAsHoles = false);
85
  /**
86
   * Same as above, but where sygusBody is the body (base_inst) provided to the
87
   * call to initialize of this class.
88
   */
89
  bool repairSolution(const std::vector<Node>& candidates,
90
                      const std::vector<Node>& candidate_values,
91
                      std::vector<Node>& repair_cv,
92
                      bool useConstantsAsHoles = false);
93
  /**
94
   * Return whether this module has the possibility to repair solutions. This is
95
   * true if this module has been initialized, and at least one candidate has
96
   * an "any constant" constructor.
97
   */
98
  bool isActive() const;
99
  /** must repair?
100
   *
101
   * This returns true if n must be repaired for it to be a valid solution.
102
   * This corresponds to whether n contains a subterm that is a symbolic
103
   * constructor like the "any constant" constructor.
104
   */
105
  static bool mustRepair(Node n);
106
107
 private:
108
  /** pointer to the sygus term database of d_qe */
109
  TermDbSygus* d_tds;
110
  /**
111
   * The "base instantiation" of the deep embedding form of the synthesis
112
   * conjecture associated with this class, see CegConjecture::d_base_inst.
113
   */
114
  Node d_base_inst;
115
  /**
116
   * whether any sygus type for the candidate variables of d_base_inst (the
117
   * syntactic restrictions) allows all constants. If this flag is false, then
118
   * this class is a no-op.
119
   */
120
  bool d_allow_constant_grammar;
121
  /** map from skeleton variables to first-order variables */
122
  std::map<Node, Node> d_sk_to_fo;
123
  /** reverse map of d_sk_to_fo */
124
  std::map<Node, Node> d_fo_to_sk;
125
  /** a cache of satisfiability queries of the form [***] above we have tried */
126
  std::unordered_set<Node> d_queries;
127
  /**
128
   * Register information for sygus type tn, tprocessed stores the set of
129
   * already registered types.
130
   */
131
  void registerSygusType(TypeNode tn, std::map<TypeNode, bool>& tprocessed);
132
  /** is repairable?
133
   *
134
   * This returns true if n can be repaired by this class. In particular, we
135
   * return true if n is an "any constant" constructor, or it is a constructor
136
   * for a constant in a type that allows all constants and useConstantsAsHoles
137
   * is true.
138
   */
139
  static bool isRepairable(Node n, bool useConstantsAsHoles);
140
  /** get skeleton
141
   *
142
   * Returns a skeleton for sygus datatype value n, where the subterms of n that
143
   * are repairable are replaced by free variables. Since we are interested in
144
   * returning canonical skeletons, the free variables we use in this
145
   * replacement are taken from TermDbSygus, where we track indices
146
   * in free_var_count. Variables we introduce in this way are added to sk_vars.
147
   * The mapping sk_vars_to_subs contains entries v -> c, where v is a
148
   * variable in sk_vars, and c is the term in n that it replaced. The flag
149
   * useConstantsAsHoles affects which terms we consider to be repairable.
150
   */
151
  Node getSkeleton(Node n,
152
                   std::map<TypeNode, int>& free_var_count,
153
                   std::vector<Node>& sk_vars,
154
                   std::map<Node, Node>& sk_vars_to_subs,
155
                   bool useConstantsAsHoles);
156
  /** get first-order query
157
   *
158
   * This function returns a formula that is equivalent to the negation of the
159
   * synthesis conjecture whose body is given in the first argument, where
160
   * candidates are replaced by candidate_skeletons,
161
   * whose free variables are in the set sk_vars. The returned formula
162
   * is a first-order (quantified) formula in the background logic, without UF,
163
   * of the form [***] above.
164
   */
165
  Node getFoQuery(Node body,
166
                  const std::vector<Node>& candidates,
167
                  const std::vector<Node>& candidate_skeletons,
168
                  const std::vector<Node>& sk_vars);
169
  /** fit to logic
170
   *
171
   * This function ensures that a query of the form [***] above fits the given
172
   * logic. In our approach for constant repair, replacing constants by
173
   * variables may introduce e.g. non-linearity. If non-linear arithmetic is
174
   * not enabled, we must undo some of the variables we introduced when
175
   * inferring candidate skeletons.
176
   *
177
   * body is the (sygus) form of the original synthesis conjecture we are
178
   * considering in this call.
179
   *
180
   * This function may remove variables from sk_vars and the map
181
   * sk_vars_to_subs. The skeletons candidate_skeletons are obtained by
182
   * getSkeleton(...) on the resulting vectors. If this function returns a
183
   * non-null node n', then n' is getFoQuery(...) on the resulting vectors, and
184
   * n' is in the given logic. The function may return null if it is not
185
   * possible to find a n' of this form.
186
   *
187
   * It uses the function below to choose which variables to remove from
188
   * sk_vars.
189
   */
190
  Node fitToLogic(Node body,
191
                  LogicInfo& logic,
192
                  Node n,
193
                  const std::vector<Node>& candidates,
194
                  std::vector<Node>& candidate_skeletons,
195
                  std::vector<Node>& sk_vars,
196
                  std::map<Node, Node>& sk_vars_to_subs);
197
  /** get fit to logic exclusion variable
198
   *
199
   * If n is not in the given logic, then this method either returns false,
200
   * or returns true and sets exvar to some variable in the domain of
201
   * d_fo_to_sk, that must be replaced by a constant for n to be in the given
202
   * logic. For example, for logic linear arithemic, for input:
203
   *    x * y = 5
204
   * where x is in the domain of d_fo_to_sk, this function returns true and sets
205
   * exvar to x.
206
   * If n is in the given logic, this method returns true.
207
   */
208
  bool getFitToLogicExcludeVar(LogicInfo& logic, Node n, Node& exvar);
209
};
210
211
}  // namespace quantifiers
212
}  // namespace theory
213
}  // namespace cvc5
214
215
#endif /* CVC5__THEORY__QUANTIFIERS__SYGUS_REPAIR_CONST_H */