1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds, Haniel Barbosa, Mathias Preiner |
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 |
|
* cegis |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "cvc5_private.h" |
17 |
|
|
18 |
|
#ifndef CVC5__THEORY__QUANTIFIERS__CEGIS_H |
19 |
|
#define CVC5__THEORY__QUANTIFIERS__CEGIS_H |
20 |
|
|
21 |
|
#include <map> |
22 |
|
|
23 |
|
#include "smt/env_obj.h" |
24 |
|
#include "theory/quantifiers/sygus/sygus_module.h" |
25 |
|
#include "theory/quantifiers/sygus_sampler.h" |
26 |
|
|
27 |
|
namespace cvc5 { |
28 |
|
namespace theory { |
29 |
|
namespace quantifiers { |
30 |
|
|
31 |
|
class SygusEvalUnfold; |
32 |
|
|
33 |
|
/** Cegis |
34 |
|
* |
35 |
|
* The default sygus module for synthesis, counterexample-guided inductive |
36 |
|
* synthesis (CEGIS). |
37 |
|
* |
38 |
|
* It initializes a list of sygus enumerators that are one-to-one with |
39 |
|
* candidates, and returns a list of candidates that are the model values |
40 |
|
* of these enumerators on calls to constructCandidates. |
41 |
|
* |
42 |
|
* It implements an optimization (getRefinementEvalLemmas) that evaluates all |
43 |
|
* previous refinement lemmas for a term before returning it as a candidate |
44 |
|
* in calls to constructCandidates. |
45 |
|
*/ |
46 |
|
class Cegis : public SygusModule |
47 |
|
{ |
48 |
|
public: |
49 |
|
Cegis(Env& env, |
50 |
|
QuantifiersState& qs, |
51 |
|
QuantifiersInferenceManager& qim, |
52 |
|
TermDbSygus* tds, |
53 |
|
SynthConjecture* p); |
54 |
7588 |
~Cegis() override {} |
55 |
|
/** initialize */ |
56 |
|
virtual bool initialize(Node conj, |
57 |
|
Node n, |
58 |
|
const std::vector<Node>& candidates) override; |
59 |
|
/** get term list */ |
60 |
|
virtual void getTermList(const std::vector<Node>& candidates, |
61 |
|
std::vector<Node>& enums) override; |
62 |
|
/** construct candidate */ |
63 |
|
virtual bool constructCandidates( |
64 |
|
const std::vector<Node>& enums, |
65 |
|
const std::vector<Node>& enum_values, |
66 |
|
const std::vector<Node>& candidates, |
67 |
|
std::vector<Node>& candidate_values) override; |
68 |
|
/** register refinement lemma |
69 |
|
* |
70 |
|
* This function stores lem as a refinement lemma, and adds it to lems. |
71 |
|
*/ |
72 |
|
virtual void registerRefinementLemma(const std::vector<Node>& vars, |
73 |
|
Node lem) override; |
74 |
|
/** using repair const */ |
75 |
|
virtual bool usingRepairConst() override; |
76 |
|
|
77 |
|
protected: |
78 |
|
/** the evaluation unfold utility of d_tds */ |
79 |
|
SygusEvalUnfold* d_eval_unfold; |
80 |
|
/** If SynthConjecture::d_base_inst is exists y. P( d, y ), then this is y. */ |
81 |
|
std::vector<Node> d_base_vars; |
82 |
|
/** |
83 |
|
* If SynthConjecture::d_base_inst is exists y. P( d, y ), then this is the |
84 |
|
* formula P( SynthConjecture::d_candidates, y ). |
85 |
|
*/ |
86 |
|
Node d_base_body; |
87 |
|
//----------------------------------cegis-implementation-specific |
88 |
|
/** |
89 |
|
* Do cegis-implementation-specific initialization for this class. The return |
90 |
|
* value and behavior of this function is the same as initialize(...) above. |
91 |
|
*/ |
92 |
|
virtual bool processInitialize(Node conj, |
93 |
|
Node n, |
94 |
|
const std::vector<Node>& candidates); |
95 |
|
/** do cegis-implementation-specific post-processing for construct candidate |
96 |
|
* |
97 |
|
* satisfiedRl is whether all refinement lemmas are satisfied under the |
98 |
|
* substitution { enums -> enum_values }. |
99 |
|
* |
100 |
|
* The return value and behavior of this function is the same as |
101 |
|
* constructCandidates(...) above. |
102 |
|
*/ |
103 |
|
virtual bool processConstructCandidates(const std::vector<Node>& enums, |
104 |
|
const std::vector<Node>& enum_values, |
105 |
|
const std::vector<Node>& candidates, |
106 |
|
std::vector<Node>& candidate_values, |
107 |
|
bool satisfiedRl); |
108 |
|
//----------------------------------end cegis-implementation-specific |
109 |
|
|
110 |
|
//-----------------------------------refinement lemmas |
111 |
|
/** refinement lemmas */ |
112 |
|
std::vector<Node> d_refinement_lemmas; |
113 |
|
/** (processed) conjunctions of refinement lemmas that are not unit */ |
114 |
|
std::unordered_set<Node> d_refinement_lemma_conj; |
115 |
|
/** (processed) conjunctions of refinement lemmas that are unit */ |
116 |
|
std::unordered_set<Node> d_refinement_lemma_unit; |
117 |
|
/** substitution entailed by d_refinement_lemma_unit */ |
118 |
|
std::vector<Node> d_rl_eval_hds; |
119 |
|
std::vector<Node> d_rl_vals; |
120 |
|
/** all variables appearing in refinement lemmas */ |
121 |
|
std::unordered_set<Node> d_refinement_lemma_vars; |
122 |
|
/** |
123 |
|
* Are the counterexamples we are handling in this class of only closed |
124 |
|
* enumerable types (see TypeNode::isClosedEnumerable). If this is false, |
125 |
|
* then CEGIS refinement lemmas can contain terms that are unhandled by |
126 |
|
* theory solvers, e.g. uninterpreted constants. |
127 |
|
*/ |
128 |
|
bool d_cexClosedEnum; |
129 |
|
|
130 |
|
/** adds lem as a refinement lemma */ |
131 |
|
void addRefinementLemma(Node lem); |
132 |
|
/** add refinement lemma conjunct |
133 |
|
* |
134 |
|
* This is a helper function for addRefinementLemma. |
135 |
|
* |
136 |
|
* This adds waiting[wcounter] to the proper vector (d_refinement_lemma_conj |
137 |
|
* or d_refinement_lemma_unit). In the case that waiting[wcounter] corresponds |
138 |
|
* to a value propagation, e.g. it is of the form: |
139 |
|
* (eval x c1...cn) = c |
140 |
|
* then it is added to d_refinement_lemma_unit, (eval x c1...cn) -> c is added |
141 |
|
* as a substitution in d_rl_eval_hds/d_rl_eval_vals, and applied to previous |
142 |
|
* lemmas in d_refinement_lemma_conj and lemmas waiting[k] for k>wcounter. |
143 |
|
* Each lemma in d_refinement_lemma_conj that is modifed in this process is |
144 |
|
* moved to the vector waiting. |
145 |
|
*/ |
146 |
|
void addRefinementLemmaConjunct(unsigned wcounter, |
147 |
|
std::vector<Node>& waiting); |
148 |
|
/** sample add refinement lemma |
149 |
|
* |
150 |
|
* This function will check if there is a sample point in d_sampler that |
151 |
|
* refutes the candidate solution (d_quant_vars->vals). If so, it adds a |
152 |
|
* refinement lemma to the lists d_refinement_lemmas that corresponds to that |
153 |
|
* sample point, and adds a lemma to d_qim pending lemmas if cegisSample mode |
154 |
|
* is not trust. |
155 |
|
*/ |
156 |
|
bool sampleAddRefinementLemma(const std::vector<Node>& candidates, |
157 |
|
const std::vector<Node>& vals); |
158 |
|
|
159 |
|
/** evaluates candidate values on current refinement lemmas |
160 |
|
* |
161 |
|
* This method performs techniques that ensure that |
162 |
|
* { candidates -> candidate_values } is a candidate solution that should |
163 |
|
* be checked by the solution verifier of the CEGIS loop. This method |
164 |
|
* invokes two sub-methods which may reject the current solution. |
165 |
|
* The first is "refinement evaluation", described above the method |
166 |
|
* getRefinementEvalLemmas below. The second is "evaluation unfolding", |
167 |
|
* which eagerly unfolds applications of evaluation functions (see |
168 |
|
* sygus_eval_unfold.h for details). |
169 |
|
* |
170 |
|
* If this method returns true, then { candidates -> candidate_values } |
171 |
|
* is not ready to be tried as a candidate solution. In this case, it may add |
172 |
|
* lemmas to lems. |
173 |
|
* |
174 |
|
* Notice that this method may return true without adding any lemmas to |
175 |
|
* lems, in the case that terms from candidates are "actively-generated |
176 |
|
* enumerators", since the model values of such terms are managed |
177 |
|
* explicitly within getEnumeratedValue. In this case, the owner of the |
178 |
|
* actively-generated enumerators (e.g. SynthConjecture) is responsible for |
179 |
|
* blocking the current value of candidates. |
180 |
|
*/ |
181 |
|
bool addEvalLemmas(const std::vector<Node>& candidates, |
182 |
|
const std::vector<Node>& candidate_values); |
183 |
|
/** Get the node corresponding to the conjunction of all refinement lemmas. */ |
184 |
|
Node getRefinementLemmaFormula(); |
185 |
|
//-----------------------------------end refinement lemmas |
186 |
|
|
187 |
|
/** Get refinement evaluation lemmas |
188 |
|
* |
189 |
|
* This method performs "refinement evaluation", that is, it tests |
190 |
|
* whether the current solution, given by { vs -> ms }, |
191 |
|
* satisfies all current refinement lemmas. If it does not, it may add |
192 |
|
* blocking lemmas L to lems which exclude (a generalization of) the current |
193 |
|
* solution. |
194 |
|
* |
195 |
|
* Given a candidate solution ms for candidates vs, this function adds lemmas |
196 |
|
* to lems based on evaluating the conjecture, instantiated for ms, on lemmas |
197 |
|
* for previous refinements (d_refinement_lemmas). |
198 |
|
* |
199 |
|
* Returns true if any such lemma exists. |
200 |
|
*/ |
201 |
|
bool getRefinementEvalLemmas(const std::vector<Node>& vs, |
202 |
|
const std::vector<Node>& ms, |
203 |
|
std::vector<Node>& lems); |
204 |
|
/** Check refinement evaluation lemmas |
205 |
|
* |
206 |
|
* This method is similar to above, but does not perform any generalization |
207 |
|
* techniques. It is used when we are using only fast enumerators for |
208 |
|
* all functions-to-synthesize. |
209 |
|
* |
210 |
|
* Returns true if a refinement lemma is false for the solution |
211 |
|
* { vs -> ms }. |
212 |
|
*/ |
213 |
|
bool checkRefinementEvalLemmas(const std::vector<Node>& vs, |
214 |
|
const std::vector<Node>& ms); |
215 |
|
/** sampler object for the option cegisSample() |
216 |
|
* |
217 |
|
* This samples points of the type of the inner variables of the synthesis |
218 |
|
* conjecture (d_base_vars). |
219 |
|
*/ |
220 |
|
SygusSampler d_cegis_sampler; |
221 |
|
/** cegis sample refine points |
222 |
|
* |
223 |
|
* Stores the list of indices of sample points in d_cegis_sampler we have |
224 |
|
* added as refinement lemmas. |
225 |
|
*/ |
226 |
|
std::unordered_set<unsigned> d_cegis_sample_refine; |
227 |
|
|
228 |
|
//---------------------------------for symbolic constructors |
229 |
|
/** are we using symbolic constants? |
230 |
|
* |
231 |
|
* This flag is set ot true if at least one of the enumerators allocated |
232 |
|
* by this class has been configured to allow model values with symbolic |
233 |
|
* constructors, such as the "any constant" constructor. |
234 |
|
*/ |
235 |
|
bool d_usingSymCons; |
236 |
|
//---------------------------------end for symbolic constructors |
237 |
|
}; |
238 |
|
|
239 |
|
} // namespace quantifiers |
240 |
|
} // namespace theory |
241 |
|
} // namespace cvc5 |
242 |
|
|
243 |
|
#endif /* CVC5__THEORY__QUANTIFIERS__CEGIS_H */ |