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