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

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Yoni Zohar, Haniel Barbosa
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
 * Class for constructing inductive datatypes that correspond to
14
 * grammars that encode syntactic restrictions for SyGuS.
15
 */
16
17
#include "cvc5_private.h"
18
19
#ifndef CVC5__THEORY__QUANTIFIERS__SYGUS_GRAMMAR_CONS_H
20
#define CVC5__THEORY__QUANTIFIERS__SYGUS_GRAMMAR_CONS_H
21
22
#include <map>
23
#include <vector>
24
25
#include "expr/attribute.h"
26
#include "expr/node.h"
27
#include "expr/sygus_datatype.h"
28
#include "smt/env_obj.h"
29
30
namespace cvc5 {
31
namespace theory {
32
33
/**
34
 * Attribute for associating a function-to-synthesize with a first order
35
 * variable whose type is a sygus datatype type that encodes its grammar.
36
 */
37
struct SygusSynthGrammarAttributeId
38
{
39
};
40
typedef expr::Attribute<SygusSynthGrammarAttributeId, Node>
41
    SygusSynthGrammarAttribute;
42
43
/**
44
 * Attribute for associating a function-to-synthesize with its formal argument
45
 * list.
46
 */
47
struct SygusSynthFunVarListAttributeId
48
{
49
};
50
typedef expr::Attribute<SygusSynthFunVarListAttributeId, Node>
51
    SygusSynthFunVarListAttribute;
52
53
namespace quantifiers {
54
55
class SynthConjecture;
56
class TermDbSygus;
57
58
/**
59
 * Utility for constructing datatypes that correspond to syntactic restrictions,
60
 * and applying the deep embedding from Section 4 of Reynolds et al CAV 2015.
61
 */
62
class CegGrammarConstructor : protected EnvObj
63
{
64
public:
65
 CegGrammarConstructor(Env& env, TermDbSygus* tds, SynthConjecture* p);
66
3792
 ~CegGrammarConstructor() {}
67
 /** process
68
  *
69
  * This converts node q based on its deep embedding
70
  * (Section 4 of Reynolds et al CAV 2015).
71
  * The syntactic restrictions are associated with
72
  * the functions-to-synthesize using the attribute
73
  * SygusSynthGrammarAttribute.
74
  * The arguments templates and template_args
75
  * indicate templates for the function to synthesize,
76
  * in particular the solution for the i^th function
77
  * to synthesis must be of the form
78
  *   templates[i]{ templates_arg[i] -> t }
79
  * for some t if !templates[i].isNull().
80
  */
81
 Node process(Node q,
82
              const std::map<Node, Node>& templates,
83
              const std::map<Node, Node>& templates_arg);
84
 /**
85
  * Same as above, but we have already determined that the set of first-order
86
  * datatype variables that will quantify the deep embedding conjecture are
87
  * the vector ebvl.
88
  */
89
 Node process(Node q,
90
              const std::map<Node, Node>& templates,
91
              const std::map<Node, Node>& templates_arg,
92
              const std::vector<Node>& ebvl);
93
94
 /** Is the syntax restricted? */
95
542
 bool isSyntaxRestricted() { return d_is_syntax_restricted; }
96
97
 /**
98
  * Make the default sygus datatype type corresponding to builtin type range
99
  * arguments:
100
  *   - bvl: the set of free variables to include in the grammar
101
  *   - fun: used for naming
102
  *   - extra_cons: a set of extra constant symbols to include in the grammar,
103
  *     regardless of their inclusion in the default grammar.
104
  *   - exclude_cons: used to exclude operators from the grammar,
105
  *   - term_irrelevant: a set of terms that should not be included in the
106
  *      grammar.
107
  *   - include_cons: a set of operators such that if this set is not empty,
108
  *     its elements that are in the default grammar (and only them)
109
  *     will be included.
110
  */
111
 static TypeNode mkSygusDefaultType(
112
     TypeNode range,
113
     Node bvl,
114
     const std::string& fun,
115
     std::map<TypeNode, std::unordered_set<Node>>& extra_cons,
116
     std::map<TypeNode, std::unordered_set<Node>>& exclude_cons,
117
     std::map<TypeNode, std::unordered_set<Node>>& include_cons,
118
     std::unordered_set<Node>& term_irrelevant);
119
120
 /**
121
  * Make the default sygus datatype type corresponding to builtin type range.
122
  */
123
 static TypeNode mkSygusDefaultType(TypeNode range,
124
                                    Node bvl,
125
                                    const std::string& fun)
126
 {
127
   std::map<TypeNode, std::unordered_set<Node>> extra_cons;
128
   std::map<TypeNode, std::unordered_set<Node>> exclude_cons;
129
   std::map<TypeNode, std::unordered_set<Node>> include_cons;
130
   std::unordered_set<Node> term_irrelevant;
131
   return mkSygusDefaultType(range,
132
                             bvl,
133
                             fun,
134
                             extra_cons,
135
                             exclude_cons,
136
                             include_cons,
137
                             term_irrelevant);
138
  }
139
140
  /** make the sygus datatype type that encodes the solution space (lambda
141
  * templ_arg. templ[templ_arg]) where templ_arg
142
  * has syntactic restrictions encoded by sygus type templ_arg_sygus_type
143
  *   bvl is the set of free variables to include in the grammar
144
  *   fun is for naming
145
  */
146
  static TypeNode mkSygusTemplateType( Node templ, Node templ_arg, TypeNode templ_arg_sygus_type, Node bvl, const std::string& fun );
147
  /**
148
   * Returns true iff there are syntax restrictions on the
149
   * functions-to-synthesize of sygus conjecture q.
150
   */
151
  static bool hasSyntaxRestrictions(Node q);
152
  /**
153
   * Make the builtin constants for type "type" that should be included in a
154
   * sygus grammar, add them to vector ops.
155
   */
156
  static void mkSygusConstantsForType(TypeNode type, std::vector<Node>& ops);
157
  /** Is it possible to construct a default grammar for type t? */
158
  static bool isHandledType(TypeNode t);
159
  /**
160
   * Convert node n based on deep embedding, see Section 4 of Reynolds et al
161
   * CAV 2015.
162
   *
163
   * This returns the result of converting n to its deep embedding based on
164
   * the mapping from functions to datatype variables, stored in
165
   * d_synth_fun_vars. This method should be called only after calling process
166
   * above.
167
   */
168
  Node convertToEmbedding(Node n);
169
170
 private:
171
  /** The sygus term database we are using */
172
  TermDbSygus* d_tds;
173
  /** parent conjecture
174
  * This contains global information about the synthesis conjecture.
175
  */
176
  SynthConjecture* d_parent;
177
  /**
178
   * Maps each synthesis function to its corresponding (first-order) sygus
179
   * datatype variable. This map is initialized by the process methods.
180
   */
181
  std::map<Node, Node> d_synth_fun_vars;
182
  /** is the syntax restricted? */
183
  bool d_is_syntax_restricted;
184
  /** collect terms */
185
  void collectTerms(Node n,
186
                    std::map<TypeNode, std::unordered_set<Node>>& consts);
187
  //---------------- grammar construction
188
  /** A class for generating sygus datatypes */
189
2869
  class SygusDatatypeGenerator
190
  {
191
   public:
192
    SygusDatatypeGenerator(const std::string& name);
193
4164
    ~SygusDatatypeGenerator() {}
194
    /**
195
     * Possibly add a constructor to d_sdt, based on the criteria mentioned
196
     * in this class below. For details see expr/sygus_datatype.h.
197
     */
198
    void addConstructor(Node op,
199
                        const std::string& name,
200
                        const std::vector<TypeNode>& consTypes,
201
                        int weight = -1);
202
    /**
203
     * Possibly add a constructor to d_sdt, based on the criteria mentioned
204
     * in this class below.
205
     */
206
    void addConstructor(Kind k,
207
                        const std::vector<TypeNode>& consTypes,
208
                        int weight = -1);
209
    /** Should we include constructor with operator op? */
210
    bool shouldInclude(Node op) const;
211
    /** The constructors that should be excluded. */
212
    std::unordered_set<Node> d_exclude_cons;
213
    /**
214
     * If this set is non-empty, then only include variables and constructors
215
     * from it.
216
     */
217
    std::unordered_set<Node> d_include_cons;
218
    /** The sygus datatype we are generating. */
219
    SygusDatatype d_sdt;
220
  };
221
222
  // helper for mkSygusDefaultGrammar (makes unresolved type for mutually recursive datatype construction)
223
  static TypeNode mkUnresolvedType(const std::string& name,
224
                                   std::set<TypeNode>& unres);
225
  // collect the list of types that depend on type range
226
  static void collectSygusGrammarTypesFor(TypeNode range,
227
                                          std::vector<TypeNode>& types);
228
  /** helper function for function mkSygusDefaultType
229
  * Collects a set of mutually recursive datatypes "datatypes" corresponding to
230
  * encoding type "range" to SyGuS.
231
  *   unres is used for the resulting call to mkMutualDatatypeTypes
232
  */
233
  static void mkSygusDefaultGrammar(
234
      TypeNode range,
235
      Node bvl,
236
      const std::string& fun,
237
      std::map<TypeNode, std::unordered_set<Node>>& extra_cons,
238
      std::map<TypeNode, std::unordered_set<Node>>& exclude_cons,
239
      const std::map<TypeNode, std::unordered_set<Node>>& include_cons,
240
      std::unordered_set<Node>& term_irrelevant,
241
      std::vector<SygusDatatypeGenerator>& sdts,
242
      std::set<TypeNode>& unres);
243
244
  // helper function for mkSygusTemplateType
245
  static TypeNode mkSygusTemplateTypeRec(Node templ,
246
                                         Node templ_arg,
247
                                         TypeNode templ_arg_sygus_type,
248
                                         Node bvl,
249
                                         const std::string& fun,
250
                                         unsigned& tcount);
251
252
  /**
253
   * Given a kind k, create a lambda operator with the given builtin input type
254
   * and an extra zero argument of that same type.  For example, for k = LEQ and
255
   * bArgType = Int, the operator will be lambda x : Int. x + 0.  Currently the
256
   * supported input types are Real (thus also Int) and BitVector.
257
   */
258
  static Node createLambdaWithZeroArg(Kind k,
259
                                      TypeNode bArgType);
260
  //---------------- end grammar construction
261
};
262
263
}  // namespace quantifiers
264
}  // namespace theory
265
}  // namespace cvc5
266
267
#endif