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