1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Haniel Barbosa, Andrew Reynolds, 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 |
|
* Class for streaming concrete values (through substitutions) from |
14 |
|
* enumerated abstract ones. |
15 |
|
*/ |
16 |
|
|
17 |
|
#include "theory/quantifiers/sygus/enum_stream_substitution.h" |
18 |
|
|
19 |
|
#include "expr/dtype_cons.h" |
20 |
|
#include "options/base_options.h" |
21 |
|
#include "options/datatypes_options.h" |
22 |
|
#include "options/quantifiers_options.h" |
23 |
|
#include "printer/printer.h" |
24 |
|
#include "theory/quantifiers/sygus/term_database_sygus.h" |
25 |
|
|
26 |
|
#include <numeric> // for std::iota |
27 |
|
#include <sstream> |
28 |
|
|
29 |
|
using namespace cvc5::kind; |
30 |
|
|
31 |
|
namespace cvc5 { |
32 |
|
namespace theory { |
33 |
|
namespace quantifiers { |
34 |
|
|
35 |
1 |
EnumStreamPermutation::EnumStreamPermutation(quantifiers::TermDbSygus* tds) |
36 |
1 |
: d_tds(tds), d_first(true), d_curr_ind(0) |
37 |
|
{ |
38 |
1 |
} |
39 |
|
|
40 |
1 |
void EnumStreamPermutation::reset(Node value) |
41 |
|
{ |
42 |
|
// clean state |
43 |
1 |
d_var_classes.clear(); |
44 |
1 |
d_var_tn_cons.clear(); |
45 |
1 |
d_first = true; |
46 |
1 |
d_perm_state_class.clear(); |
47 |
1 |
d_perm_values.clear(); |
48 |
1 |
d_value = value; |
49 |
|
// get variables in value's type |
50 |
2 |
TypeNode tn = value.getType(); |
51 |
2 |
Node var_list = tn.getDType().getSygusVarList(); |
52 |
1 |
NodeManager* nm = NodeManager::currentNM(); |
53 |
|
// get subtypes in value's type |
54 |
1 |
SygusTypeInfo& ti = d_tds->getTypeInfo(tn); |
55 |
2 |
std::vector<TypeNode> sf_types; |
56 |
1 |
ti.getSubfieldTypes(sf_types); |
57 |
|
// associate variables with constructors in all subfield types |
58 |
2 |
std::map<Node, Node> cons_var; |
59 |
3 |
for (const Node& v : var_list) |
60 |
|
{ |
61 |
|
// collect constructors for variable in all subtypes |
62 |
4 |
for (const TypeNode& stn : sf_types) |
63 |
|
{ |
64 |
2 |
const DType& dt = stn.getDType(); |
65 |
8 |
for (unsigned i = 0, size = dt.getNumConstructors(); i < size; ++i) |
66 |
|
{ |
67 |
6 |
if (dt[i].getNumArgs() == 0 && dt[i].getSygusOp() == v) |
68 |
|
{ |
69 |
4 |
Node cons = nm->mkNode(APPLY_CONSTRUCTOR, dt[i].getConstructor()); |
70 |
2 |
d_var_tn_cons[v][stn] = cons; |
71 |
2 |
cons_var[cons] = v; |
72 |
|
} |
73 |
|
} |
74 |
|
} |
75 |
|
} |
76 |
|
// collect variables occurring in value |
77 |
2 |
std::vector<Node> vars; |
78 |
2 |
std::unordered_set<Node> visited; |
79 |
1 |
collectVars(value, vars, visited); |
80 |
|
// partition permutation variables |
81 |
1 |
d_curr_ind = 0; |
82 |
1 |
Trace("synth-stream-concrete") << " ..permutting vars :"; |
83 |
2 |
std::unordered_set<Node> seen_vars; |
84 |
2 |
for (const Node& v_cons : vars) |
85 |
|
{ |
86 |
1 |
Assert(cons_var.find(v_cons) != cons_var.end()); |
87 |
2 |
Node var = cons_var[v_cons]; |
88 |
1 |
if (seen_vars.insert(var).second) |
89 |
|
{ |
90 |
|
// do not add repeated vars |
91 |
1 |
d_var_classes[ti.getSubclassForVar(var)].push_back(var); |
92 |
|
} |
93 |
|
} |
94 |
2 |
for (const std::pair<const unsigned, std::vector<Node>>& p : d_var_classes) |
95 |
|
{ |
96 |
1 |
d_perm_state_class.push_back(PermutationState(p.second)); |
97 |
1 |
if (Trace.isOn("synth-stream-concrete")) |
98 |
|
{ |
99 |
|
Trace("synth-stream-concrete") << " " << p.first << " -> ["; |
100 |
|
for (const Node& var : p.second) |
101 |
|
{ |
102 |
|
std::stringstream ss; |
103 |
|
TermDbSygus::toStreamSygus(ss, var); |
104 |
|
Trace("synth-stream-concrete") << " " << ss.str(); |
105 |
|
} |
106 |
|
Trace("synth-stream-concrete") << " ]"; |
107 |
|
} |
108 |
|
} |
109 |
1 |
Trace("synth-stream-concrete") << "\n"; |
110 |
1 |
} |
111 |
|
|
112 |
2 |
Node EnumStreamPermutation::getNext() |
113 |
|
{ |
114 |
2 |
if (Trace.isOn("synth-stream-concrete")) |
115 |
|
{ |
116 |
|
std::stringstream ss; |
117 |
|
TermDbSygus::toStreamSygus(ss, d_value); |
118 |
|
Trace("synth-stream-concrete") |
119 |
|
<< " ....streaming next permutation for value : " << ss.str() |
120 |
|
<< " with " << d_perm_state_class.size() << " permutation classes\n"; |
121 |
|
} |
122 |
|
// initial value |
123 |
2 |
if (d_first) |
124 |
|
{ |
125 |
1 |
d_first = false; |
126 |
2 |
Node bultin_value = d_tds->sygusToBuiltin(d_value, d_value.getType()); |
127 |
1 |
d_perm_values.insert( |
128 |
2 |
d_tds->getExtRewriter()->extendedRewrite(bultin_value)); |
129 |
1 |
return d_value; |
130 |
|
} |
131 |
1 |
unsigned n_classes = d_perm_state_class.size(); |
132 |
2 |
Node perm_value, bultin_perm_value; |
133 |
|
do |
134 |
|
{ |
135 |
1 |
bool new_perm = false; |
136 |
3 |
while (!new_perm && d_curr_ind < n_classes) |
137 |
|
{ |
138 |
1 |
if (d_perm_state_class[d_curr_ind].getNextPermutation()) |
139 |
|
{ |
140 |
|
new_perm = true; |
141 |
|
Trace("synth-stream-concrete-debug2") |
142 |
|
<< " ....class " << d_curr_ind << " has new perm\n"; |
143 |
|
d_curr_ind = 0; |
144 |
|
} |
145 |
|
else |
146 |
|
{ |
147 |
2 |
Trace("synth-stream-concrete-debug2") |
148 |
1 |
<< " ....class " << d_curr_ind << " reset\n"; |
149 |
1 |
d_perm_state_class[d_curr_ind].reset(); |
150 |
1 |
d_curr_ind++; |
151 |
|
} |
152 |
|
} |
153 |
|
// no new permutation |
154 |
1 |
if (!new_perm) |
155 |
|
{ |
156 |
1 |
Trace("synth-stream-concrete") << " ....no new perm, return null\n"; |
157 |
1 |
return Node::null(); |
158 |
|
} |
159 |
|
// building substitution |
160 |
|
std::vector<Node> domain_sub, range_sub; |
161 |
|
for (unsigned i = 0, size = d_perm_state_class.size(); i < size; ++i) |
162 |
|
{ |
163 |
|
Trace("synth-stream-concrete") << " ..perm for class " << i << " is"; |
164 |
|
std::vector<Node> raw_sub; |
165 |
|
d_perm_state_class[i].getLastPerm(raw_sub); |
166 |
|
// retrieve variables for substitution domain |
167 |
|
const std::vector<Node>& domain_sub_class = |
168 |
|
d_perm_state_class[i].getVars(); |
169 |
|
Assert(domain_sub_class.size() == raw_sub.size()); |
170 |
|
// build proper substitution based on variables types and constructors |
171 |
|
for (unsigned j = 0, size_j = raw_sub.size(); j < size_j; ++j) |
172 |
|
{ |
173 |
|
for (std::pair<const TypeNode, Node>& p : |
174 |
|
d_var_tn_cons[domain_sub_class[j]]) |
175 |
|
{ |
176 |
|
// get constructor of type p.first from variable being permuted |
177 |
|
domain_sub.push_back(p.second); |
178 |
|
// get constructor of type p.first from variable to be permuted for |
179 |
|
range_sub.push_back(d_var_tn_cons[raw_sub[j]][p.first]); |
180 |
|
Trace("synth-stream-concrete-debug2") |
181 |
|
<< "\n ....{ adding " << domain_sub.back() << " [" |
182 |
|
<< domain_sub.back().getType() << "] -> " << range_sub.back() |
183 |
|
<< " [" << range_sub.back().getType() << "] }"; |
184 |
|
} |
185 |
|
} |
186 |
|
Trace("synth-stream-concrete") << "\n"; |
187 |
|
} |
188 |
|
perm_value = d_value.substitute(domain_sub.begin(), |
189 |
|
domain_sub.end(), |
190 |
|
range_sub.begin(), |
191 |
|
range_sub.end()); |
192 |
|
bultin_perm_value = d_tds->sygusToBuiltin(perm_value, perm_value.getType()); |
193 |
|
Trace("synth-stream-concrete-debug") |
194 |
|
<< " ......perm builtin is " << bultin_perm_value; |
195 |
|
if (options::sygusSymBreakDynamic()) |
196 |
|
{ |
197 |
|
bultin_perm_value = |
198 |
|
d_tds->getExtRewriter()->extendedRewrite(bultin_perm_value); |
199 |
|
Trace("synth-stream-concrete-debug") |
200 |
|
<< " and rewrites to " << bultin_perm_value; |
201 |
|
} |
202 |
|
Trace("synth-stream-concrete-debug") << "\n"; |
203 |
|
// if permuted value is equivalent modulo rewriting to a previous one, look |
204 |
|
// for another |
205 |
|
} while (!d_perm_values.insert(bultin_perm_value).second); |
206 |
|
if (Trace.isOn("synth-stream-concrete")) |
207 |
|
{ |
208 |
|
std::stringstream ss; |
209 |
|
TermDbSygus::toStreamSygus(ss, perm_value); |
210 |
|
Trace("synth-stream-concrete") |
211 |
|
<< " ....return new perm " << ss.str() << "\n"; |
212 |
|
} |
213 |
|
return perm_value; |
214 |
|
} |
215 |
|
|
216 |
2 |
const std::vector<Node>& EnumStreamPermutation::getVarsClass(unsigned id) const |
217 |
|
{ |
218 |
|
std::map<unsigned, std::vector<Node>>::const_iterator it = |
219 |
2 |
d_var_classes.find(id); |
220 |
2 |
Assert(it != d_var_classes.end()); |
221 |
2 |
return it->second; |
222 |
|
} |
223 |
|
|
224 |
1 |
unsigned EnumStreamPermutation::getVarClassSize(unsigned id) const |
225 |
|
{ |
226 |
|
std::map<unsigned, std::vector<Node>>::const_iterator it = |
227 |
1 |
d_var_classes.find(id); |
228 |
1 |
if (it == d_var_classes.end()) |
229 |
|
{ |
230 |
|
return 0; |
231 |
|
} |
232 |
1 |
return it->second.size(); |
233 |
|
} |
234 |
|
|
235 |
1 |
void EnumStreamPermutation::collectVars(Node n, |
236 |
|
std::vector<Node>& vars, |
237 |
|
std::unordered_set<Node>& visited) |
238 |
|
{ |
239 |
1 |
if (visited.find(n) != visited.end()) |
240 |
|
{ |
241 |
|
return; |
242 |
|
} |
243 |
1 |
visited.insert(n); |
244 |
1 |
if (n.getNumChildren() > 0) |
245 |
|
{ |
246 |
|
for (const Node& ni : n) |
247 |
|
{ |
248 |
|
collectVars(ni, vars, visited); |
249 |
|
} |
250 |
|
return; |
251 |
|
} |
252 |
1 |
if (d_tds->sygusToBuiltin(n, n.getType()).getKind() == kind::BOUND_VARIABLE) |
253 |
|
{ |
254 |
1 |
if (std::find(vars.begin(), vars.end(), n) == vars.end()) |
255 |
|
{ |
256 |
1 |
vars.push_back(n); |
257 |
|
} |
258 |
1 |
return; |
259 |
|
} |
260 |
|
} |
261 |
|
|
262 |
1 |
EnumStreamPermutation::PermutationState::PermutationState( |
263 |
1 |
const std::vector<Node>& vars) |
264 |
|
{ |
265 |
1 |
d_vars = vars; |
266 |
1 |
d_curr_ind = 0; |
267 |
1 |
d_seq.resize(vars.size()); |
268 |
1 |
std::fill(d_seq.begin(), d_seq.end(), 0); |
269 |
|
// initialize variable indices |
270 |
1 |
d_last_perm.resize(vars.size()); |
271 |
1 |
std::iota(d_last_perm.begin(), d_last_perm.end(), 0); |
272 |
1 |
} |
273 |
|
|
274 |
1 |
void EnumStreamPermutation::PermutationState::reset() |
275 |
|
{ |
276 |
1 |
d_curr_ind = 0; |
277 |
1 |
std::fill(d_seq.begin(), d_seq.end(), 0); |
278 |
1 |
std::iota(d_last_perm.begin(), d_last_perm.end(), 0); |
279 |
1 |
} |
280 |
|
|
281 |
|
const std::vector<Node>& EnumStreamPermutation::PermutationState::getVars() |
282 |
|
const |
283 |
|
{ |
284 |
|
return d_vars; |
285 |
|
} |
286 |
|
|
287 |
|
void EnumStreamPermutation::PermutationState::getLastPerm( |
288 |
|
std::vector<Node>& vars) |
289 |
|
{ |
290 |
|
for (unsigned i = 0, size = d_last_perm.size(); i < size; ++i) |
291 |
|
{ |
292 |
|
if (Trace.isOn("synth-stream-concrete")) |
293 |
|
{ |
294 |
|
std::stringstream ss; |
295 |
|
TermDbSygus::toStreamSygus(ss, d_vars[d_last_perm[i]]); |
296 |
|
Trace("synth-stream-concrete") << " " << ss.str(); |
297 |
|
} |
298 |
|
vars.push_back(d_vars[d_last_perm[i]]); |
299 |
|
} |
300 |
|
} |
301 |
|
|
302 |
2 |
bool EnumStreamPermutation::PermutationState::getNextPermutation() |
303 |
|
{ |
304 |
|
// exhausted permutations |
305 |
2 |
if (d_curr_ind == d_vars.size()) |
306 |
|
{ |
307 |
1 |
Trace("synth-stream-concrete-debug2") << "exhausted perms, "; |
308 |
1 |
return false; |
309 |
|
} |
310 |
1 |
if (d_seq[d_curr_ind] >= d_curr_ind) |
311 |
|
{ |
312 |
1 |
d_seq[d_curr_ind] = 0; |
313 |
1 |
d_curr_ind++; |
314 |
1 |
return getNextPermutation(); |
315 |
|
} |
316 |
|
if (d_curr_ind % 2 == 0) |
317 |
|
{ |
318 |
|
// swap with first element |
319 |
|
std::swap(d_last_perm[0], d_last_perm[d_curr_ind]); |
320 |
|
} |
321 |
|
else |
322 |
|
{ |
323 |
|
// swap with element in index in sequence of current index |
324 |
|
std::swap(d_last_perm[d_seq[d_curr_ind]], d_last_perm[d_curr_ind]); |
325 |
|
} |
326 |
|
d_seq[d_curr_ind] += 1; |
327 |
|
d_curr_ind = 0; |
328 |
|
return true; |
329 |
|
} |
330 |
|
|
331 |
1 |
EnumStreamSubstitution::EnumStreamSubstitution(quantifiers::TermDbSygus* tds) |
332 |
1 |
: d_tds(tds), d_stream_permutations(tds), d_curr_ind(0) |
333 |
|
{ |
334 |
1 |
} |
335 |
|
|
336 |
1 |
void EnumStreamSubstitution::initialize(TypeNode tn) |
337 |
|
{ |
338 |
1 |
d_tn = tn; |
339 |
|
// get variables in value's type |
340 |
2 |
Node var_list = tn.getDType().getSygusVarList(); |
341 |
|
// get subtypes in value's type |
342 |
1 |
NodeManager* nm = NodeManager::currentNM(); |
343 |
1 |
SygusTypeInfo& ti = d_tds->getTypeInfo(tn); |
344 |
2 |
std::vector<TypeNode> sf_types; |
345 |
1 |
ti.getSubfieldTypes(sf_types); |
346 |
|
// associate variables with constructors in all subfield types |
347 |
3 |
for (const Node& v : var_list) |
348 |
|
{ |
349 |
|
// collect constructors for variable in all subtypes |
350 |
4 |
for (const TypeNode& stn : sf_types) |
351 |
|
{ |
352 |
2 |
const DType& dt = stn.getDType(); |
353 |
8 |
for (unsigned i = 0, size = dt.getNumConstructors(); i < size; ++i) |
354 |
|
{ |
355 |
6 |
if (dt[i].getNumArgs() == 0 && dt[i].getSygusOp() == v) |
356 |
|
{ |
357 |
2 |
d_var_tn_cons[v][stn] = |
358 |
4 |
nm->mkNode(APPLY_CONSTRUCTOR, dt[i].getConstructor()); |
359 |
|
} |
360 |
|
} |
361 |
|
} |
362 |
|
} |
363 |
|
// split initial variables into classes |
364 |
3 |
for (const Node& v : var_list) |
365 |
|
{ |
366 |
2 |
Assert(ti.getSubclassForVar(v) > 0); |
367 |
2 |
d_var_classes[ti.getSubclassForVar(v)].push_back(v); |
368 |
|
} |
369 |
1 |
} |
370 |
|
|
371 |
1 |
void EnumStreamSubstitution::resetValue(Node value) |
372 |
|
{ |
373 |
1 |
if (Trace.isOn("synth-stream-concrete")) |
374 |
|
{ |
375 |
|
std::stringstream ss; |
376 |
|
TermDbSygus::toStreamSygus(ss, value); |
377 |
|
Trace("synth-stream-concrete") |
378 |
|
<< " * Streaming concrete: registering value " << ss.str() << "\n"; |
379 |
|
} |
380 |
1 |
d_last = Node::null(); |
381 |
1 |
d_value = value; |
382 |
|
// reset permutation util |
383 |
1 |
d_stream_permutations.reset(value); |
384 |
|
// reset combination utils |
385 |
1 |
d_curr_ind = 0; |
386 |
1 |
d_comb_state_class.clear(); |
387 |
1 |
Trace("synth-stream-concrete") << " ..combining vars :"; |
388 |
2 |
for (const std::pair<const unsigned, std::vector<Node>>& p : d_var_classes) |
389 |
|
{ |
390 |
|
// ignore classes without variables being permuted |
391 |
1 |
unsigned perm_var_class_sz = d_stream_permutations.getVarClassSize(p.first); |
392 |
1 |
if (perm_var_class_sz == 0) |
393 |
|
{ |
394 |
|
continue; |
395 |
|
} |
396 |
3 |
d_comb_state_class.push_back(CombinationState( |
397 |
2 |
p.second.size(), perm_var_class_sz, p.first, p.second)); |
398 |
1 |
if (Trace.isOn("synth-stream-concrete")) |
399 |
|
{ |
400 |
|
Trace("synth-stream-concrete") |
401 |
|
<< " " << p.first << " -> " << perm_var_class_sz << " from [ "; |
402 |
|
for (const Node& var : p.second) |
403 |
|
{ |
404 |
|
std::stringstream ss; |
405 |
|
TermDbSygus::toStreamSygus(ss, var); |
406 |
|
Trace("synth-stream-concrete") << " " << ss.str(); |
407 |
|
} |
408 |
|
Trace("synth-stream-concrete") << " ]"; |
409 |
|
} |
410 |
|
} |
411 |
1 |
Trace("synth-stream-concrete") << "\n"; |
412 |
1 |
} |
413 |
|
|
414 |
3 |
Node EnumStreamSubstitution::getNext() |
415 |
|
{ |
416 |
3 |
if (Trace.isOn("synth-stream-concrete")) |
417 |
|
{ |
418 |
|
std::stringstream ss; |
419 |
|
TermDbSygus::toStreamSygus(ss, d_value); |
420 |
|
Trace("synth-stream-concrete") |
421 |
|
<< " ..streaming next combination of " << ss.str() << "\n"; |
422 |
|
} |
423 |
3 |
unsigned n_classes = d_comb_state_class.size(); |
424 |
|
// intial case |
425 |
3 |
if (d_last.isNull()) |
426 |
|
{ |
427 |
1 |
d_last = d_stream_permutations.getNext(); |
428 |
|
} |
429 |
|
else |
430 |
|
{ |
431 |
2 |
bool new_comb = false; |
432 |
6 |
while (!new_comb && d_curr_ind < n_classes) |
433 |
|
{ |
434 |
2 |
if (d_comb_state_class[d_curr_ind].getNextCombination()) |
435 |
|
{ |
436 |
1 |
new_comb = true; |
437 |
2 |
Trace("synth-stream-concrete-debug2") |
438 |
1 |
<< " ....class " << d_curr_ind << " has new comb\n"; |
439 |
1 |
d_curr_ind = 0; |
440 |
|
} |
441 |
|
else |
442 |
|
{ |
443 |
2 |
Trace("synth-stream-concrete-debug2") |
444 |
1 |
<< " ....class " << d_curr_ind << " reset\n"; |
445 |
1 |
d_comb_state_class[d_curr_ind].reset(); |
446 |
1 |
d_curr_ind++; |
447 |
|
} |
448 |
|
} |
449 |
|
// no new combination |
450 |
2 |
if (!new_comb) |
451 |
|
{ |
452 |
2 |
Trace("synth-stream-concrete") |
453 |
|
<< " ..no new comb, get next permutation\n ....total combs until " |
454 |
1 |
"here : " |
455 |
1 |
<< d_comb_values.size() << "\n"; |
456 |
1 |
d_last = d_stream_permutations.getNext(); |
457 |
|
// exhausted permutations |
458 |
1 |
if (d_last.isNull()) |
459 |
|
{ |
460 |
1 |
Trace("synth-stream-concrete") << " ..no new comb, return null\n"; |
461 |
1 |
return Node::null(); |
462 |
|
} |
463 |
|
// reset combination classes for next permutation |
464 |
|
d_curr_ind = 0; |
465 |
|
for (unsigned i = 0, size = d_comb_state_class.size(); i < size; ++i) |
466 |
|
{ |
467 |
|
d_comb_state_class[i].reset(); |
468 |
|
} |
469 |
|
} |
470 |
|
} |
471 |
2 |
if (Trace.isOn("synth-stream-concrete-debug")) |
472 |
|
{ |
473 |
|
std::stringstream ss; |
474 |
|
TermDbSygus::toStreamSygus(ss, d_last); |
475 |
|
Trace("synth-stream-concrete-debug") |
476 |
|
<< " ..using base perm " << ss.str() << "\n"; |
477 |
|
} |
478 |
|
// building substitution |
479 |
4 |
std::vector<Node> domain_sub, range_sub; |
480 |
4 |
for (unsigned i = 0, size = d_comb_state_class.size(); i < size; ++i) |
481 |
|
{ |
482 |
4 |
Trace("synth-stream-concrete") |
483 |
4 |
<< " ..comb for class " << d_comb_state_class[i].getSubclassId() |
484 |
2 |
<< " is"; |
485 |
4 |
std::vector<Node> raw_sub; |
486 |
2 |
d_comb_state_class[i].getLastComb(raw_sub); |
487 |
|
// retrieve variables for substitution domain |
488 |
|
const std::vector<Node>& domain_sub_class = |
489 |
|
d_stream_permutations.getVarsClass( |
490 |
2 |
d_comb_state_class[i].getSubclassId()); |
491 |
2 |
Assert(domain_sub_class.size() == raw_sub.size()); |
492 |
|
// build proper substitution based on variables types and constructors |
493 |
4 |
for (unsigned j = 0, size_j = raw_sub.size(); j < size_j; ++j) |
494 |
|
{ |
495 |
2 |
for (std::pair<const TypeNode, Node>& p : |
496 |
2 |
d_var_tn_cons[domain_sub_class[j]]) |
497 |
|
{ |
498 |
|
// get constructor of type p.first from variable being permuted |
499 |
2 |
domain_sub.push_back(p.second); |
500 |
|
// get constructor of type p.first from variable to be permuted for |
501 |
2 |
range_sub.push_back(d_var_tn_cons[raw_sub[j]][p.first]); |
502 |
4 |
Trace("synth-stream-concrete-debug2") |
503 |
2 |
<< "\n ....{ adding " << domain_sub.back() << " [" |
504 |
4 |
<< domain_sub.back().getType() << "] -> " << range_sub.back() |
505 |
2 |
<< " [" << range_sub.back().getType() << "] }"; |
506 |
|
} |
507 |
|
} |
508 |
2 |
Trace("synth-stream-concrete") << "\n"; |
509 |
|
} |
510 |
|
Node comb_value = d_last.substitute( |
511 |
4 |
domain_sub.begin(), domain_sub.end(), range_sub.begin(), range_sub.end()); |
512 |
|
// the new combination value should be fresh, modulo rewriting, by |
513 |
|
// construction (unless it's equiv to a constant, e.g. true / false) |
514 |
|
Node builtin_comb_value = |
515 |
4 |
d_tds->sygusToBuiltin(comb_value, comb_value.getType()); |
516 |
2 |
if (options::sygusSymBreakDynamic()) |
517 |
|
{ |
518 |
2 |
builtin_comb_value = |
519 |
4 |
d_tds->getExtRewriter()->extendedRewrite(builtin_comb_value); |
520 |
|
} |
521 |
2 |
if (Trace.isOn("synth-stream-concrete")) |
522 |
|
{ |
523 |
|
std::stringstream ss; |
524 |
|
TermDbSygus::toStreamSygus(ss, comb_value); |
525 |
|
Trace("synth-stream-concrete") |
526 |
|
<< " ....register new comb value " << ss.str() |
527 |
|
<< " with rewritten form " << builtin_comb_value |
528 |
|
<< (builtin_comb_value.isConst() ? " (isConst)" : "") << "\n"; |
529 |
|
} |
530 |
4 |
if (!builtin_comb_value.isConst() |
531 |
2 |
&& !d_comb_values.insert(builtin_comb_value).second) |
532 |
|
{ |
533 |
|
if (Trace.isOn("synth-stream-concrete")) |
534 |
|
{ |
535 |
|
std::stringstream ss, ss1; |
536 |
|
TermDbSygus::toStreamSygus(ss, comb_value); |
537 |
|
Trace("synth-stream-concrete") |
538 |
|
<< " ..term " << ss.str() << " is REDUNDANT with " << builtin_comb_value |
539 |
|
<< "\n ..excluding all other concretizations (had " |
540 |
|
<< d_comb_values.size() << " already)\n\n"; |
541 |
|
} |
542 |
|
return Node::null(); |
543 |
|
} |
544 |
2 |
if (Trace.isOn("synth-stream-concrete")) |
545 |
|
{ |
546 |
|
std::stringstream ss; |
547 |
|
TermDbSygus::toStreamSygus(ss, comb_value); |
548 |
|
Trace("synth-stream-concrete") |
549 |
|
<< " ..return new comb " << ss.str() << "\n\n"; |
550 |
|
} |
551 |
2 |
return comb_value; |
552 |
|
} |
553 |
|
|
554 |
1 |
EnumStreamSubstitution::CombinationState::CombinationState( |
555 |
1 |
unsigned n, unsigned k, unsigned subclass_id, const std::vector<Node>& vars) |
556 |
1 |
: d_n(n), d_k(k) |
557 |
|
{ |
558 |
1 |
Assert(!vars.empty()); |
559 |
1 |
Assert(k <= n); |
560 |
1 |
d_last_comb.resize(k); |
561 |
1 |
std::iota(d_last_comb.begin(), d_last_comb.end(), 0); |
562 |
1 |
d_vars = vars; |
563 |
1 |
d_subclass_id = subclass_id; |
564 |
1 |
} |
565 |
|
|
566 |
4 |
const unsigned EnumStreamSubstitution::CombinationState::getSubclassId() const |
567 |
|
{ |
568 |
4 |
return d_subclass_id; |
569 |
|
} |
570 |
|
|
571 |
1 |
void EnumStreamSubstitution::CombinationState::reset() |
572 |
|
{ |
573 |
1 |
std::iota(d_last_comb.begin(), d_last_comb.end(), 0); |
574 |
1 |
} |
575 |
|
|
576 |
2 |
void EnumStreamSubstitution::CombinationState::getLastComb( |
577 |
|
std::vector<Node>& vars) |
578 |
|
{ |
579 |
4 |
for (unsigned i = 0, size = d_last_comb.size(); i < size; ++i) |
580 |
|
{ |
581 |
2 |
if (Trace.isOn("synth-stream-concrete")) |
582 |
|
{ |
583 |
|
std::stringstream ss; |
584 |
|
TermDbSygus::toStreamSygus(ss, d_vars[d_last_comb[i]]); |
585 |
|
Trace("synth-stream-concrete") << " " << ss.str(); |
586 |
|
} |
587 |
2 |
vars.push_back(d_vars[d_last_comb[i]]); |
588 |
|
} |
589 |
2 |
} |
590 |
|
|
591 |
2 |
bool EnumStreamSubstitution::CombinationState::getNextCombination() |
592 |
|
{ |
593 |
|
// find what to increment |
594 |
2 |
bool new_comb = false; |
595 |
3 |
for (int i = d_k - 1; i >= 0; --i) |
596 |
|
{ |
597 |
2 |
if (d_last_comb[i] < d_n - d_k + i) |
598 |
|
{ |
599 |
1 |
unsigned j = d_last_comb[i] + 1; |
600 |
3 |
while (static_cast<unsigned>(i) <= d_k - 1) |
601 |
|
{ |
602 |
1 |
d_last_comb[i++] = j++; |
603 |
|
} |
604 |
1 |
new_comb = true; |
605 |
1 |
break; |
606 |
|
} |
607 |
|
} |
608 |
2 |
return new_comb; |
609 |
|
} |
610 |
|
|
611 |
1 |
void EnumStreamConcrete::initialize(Node e) { d_ess.initialize(e.getType()); } |
612 |
1 |
void EnumStreamConcrete::addValue(Node v) |
613 |
|
{ |
614 |
1 |
d_ess.resetValue(v); |
615 |
1 |
d_currTerm = d_ess.getNext(); |
616 |
1 |
} |
617 |
2 |
bool EnumStreamConcrete::increment() |
618 |
|
{ |
619 |
2 |
d_currTerm = d_ess.getNext(); |
620 |
2 |
return !d_currTerm.isNull(); |
621 |
|
} |
622 |
2 |
Node EnumStreamConcrete::getCurrent() { return d_currTerm; } |
623 |
|
} // namespace quantifiers |
624 |
|
} // namespace theory |
625 |
29508 |
} // namespace cvc5 |