@@ -158,7 +158,7 @@ enode_vector induction_lemmas::induction_positions(enode* n) {
158
158
for (unsigned i = 0 ; i < todo.size (); ++i) {
159
159
n = todo[i];
160
160
for (enode* a : smt::enode::args (n)) {
161
- add_todo (a);
161
+ add_todo (a);
162
162
if (!a->is_marked2 () && viable_induction_term (n, a)) {
163
163
result.push_back (a);
164
164
a->set_mark2 ();
@@ -171,86 +171,7 @@ enode_vector induction_lemmas::induction_positions(enode* n) {
171
171
n->unset_mark2 ();
172
172
return result;
173
173
}
174
-
175
- void induction_lemmas::abstract1 (enode* n, enode* t, expr* x, abstractions& result) {
176
- expr_safe_replace rep (m);
177
- rep.insert (t->get_owner (), x);
178
- expr_ref e (n->get_owner (), m);
179
- rep (e);
180
- result.push_back (abstraction (e));
181
- }
182
-
183
- /* *
184
- * abstraction candidates for replacing different occurrence of t in n by x
185
- * it returns all possible non-empty subsets of t replaced by x.
186
- *
187
- * TBD: add term sharing throttle.
188
- * TDD: add depth throttle.
189
- */
190
- void induction_lemmas::abstract (enode* n, enode* t, expr* x, abstractions& result) {
191
- std::cout << " abs: " << result.size () << " : " << mk_pp (n->get_owner (), m) << " \n " ;
192
- if (n->get_root () == t->get_root ()) {
193
- result.push_back (abstraction (m, x, n->get_owner (), t->get_owner ()));
194
- return ;
195
- }
196
- func_decl* f = n->get_owner ()->get_decl ();
197
- // check if n is a s
198
- if (f->is_skolem ()) {
199
- expr_ref e (n->get_owner (), m);
200
- result.push_back (abstraction (e));
201
- }
202
-
203
- abstraction_args r1, r2;
204
- r1.push_back (abstraction_arg (m));
205
- for (enode* arg : enode::args (n)) {
206
- unsigned n = result.size ();
207
- abstract (arg, t, x, result);
208
- std::cout << result.size () << " \n " ;
209
- for (unsigned i = n; i < result.size (); ++i) {
210
- abstraction& a = result[i];
211
- for (auto const & v : r1) {
212
- r2.push_back (v);
213
- r2.back ().push_back (a);
214
- }
215
- }
216
- r1.swap (r2);
217
- r2.reset ();
218
- result.shrink (n);
219
- }
220
- for (auto const & a : r1) {
221
- result.push_back (abstraction (m, m.mk_app (n->get_decl (), a.m_terms ), a.m_eqs ));
222
- }
223
- };
224
174
225
- /* *
226
- * filter generalizations based on value_generator
227
- * If all evaluations are counter-examples, include
228
- * candidate generalization.
229
- */
230
- void induction_lemmas::filter_abstractions (bool sign, abstractions& abs) {
231
- vector<expr_ref_vector> values;
232
- expr_ref_vector fmls (m);
233
- for (auto & a : abs ) fmls.push_back (a.m_term );
234
- std::cout << " sweep\n " ;
235
- vs (fmls, values);
236
- std::cout << " done sweep\n " ;
237
- unsigned j = 0 ;
238
- for (unsigned i = 0 ; i < fmls.size (); ++i) {
239
- bool all_cex = true ;
240
- for (auto const & vec : values) {
241
- if (vec[i] && (m.is_true (vec[i]) == sign))
242
- continue ;
243
- all_cex = false ;
244
- break ;
245
- }
246
- if (all_cex) {
247
- abs [j++] = abs .get (i);
248
- }
249
- }
250
- std::cout << " resulting size: " << j << " down from " << abs .size () << " \n " ;
251
- abs .shrink (j);
252
- }
253
-
254
175
/* *
255
176
extract substitutions for x into accessor values of the same sort.
256
177
collect side-conditions for the accessors to be well defined.
@@ -308,35 +229,21 @@ void induction_lemmas::mk_hypothesis_substs_rec(unsigned depth, sort* s, expr* y
308
229
*/
309
230
310
231
void induction_lemmas::mk_hypothesis_lemma (expr_ref_vector const & conds, expr_pair_vector const & subst, literal alpha) {
311
- expr* alpha_e = ctx. bool_var2expr (alpha. var () );
312
- expr_ref beta (alpha_e, m);
232
+ expr_ref beta (m );
233
+ ctx. literal2expr (alpha, beta);
313
234
expr_safe_replace rep (m);
314
235
for (auto const & p : subst) {
315
236
rep.insert (p.first , p.second );
316
237
}
317
238
rep (beta); // set beta := alpha[sk/acc(acc2(sk))]
318
- literal b_lit = mk_literal (beta);
319
- if (alpha.sign ()) b_lit.neg ();
239
+ // alpha & is-c(sk) => ~alpha[sk/acc(sk)]
320
240
literal_vector lits;
321
241
lits.push_back (~alpha);
322
242
for (expr* c : conds) lits.push_back (~mk_literal (c));
323
- lits.push_back (b_lit );
243
+ lits.push_back (~mk_literal (beta) );
324
244
add_th_lemma (lits);
325
245
}
326
246
327
- void induction_lemmas::create_hypotheses (unsigned depth, expr* sk, literal alpha) {
328
- expr_ref_vector conds (m);
329
- cond_substs_t subst;
330
- expr* alpha_e = ctx.bool_var2expr (alpha.var ());
331
- mk_hypothesis_substs (depth, sk, subst);
332
- for (auto & p : subst) {
333
- expr_pair_vector vec;
334
- vec.push_back (std::make_pair (sk, p.second ));
335
- mk_hypothesis_lemma (p.first , vec, alpha);
336
- }
337
- }
338
-
339
- #if 0
340
247
void induction_lemmas::create_hypotheses (unsigned depth, expr_ref_vector const & sks, literal alpha) {
341
248
if (sks.empty ())
342
249
return ;
@@ -350,55 +257,33 @@ void induction_lemmas::create_hypotheses(unsigned depth, expr_ref_vector const&
350
257
// append the identity substitution:
351
258
expr_ref_vector conds (m);
352
259
subst.push_back (std::make_pair (conds, expr_ref (sk, m)));
353
-
354
260
substs.push_back (std::make_pair (sk, subst));
355
261
}
356
262
357
263
// create cross-product of instantiations:
358
264
vector<std::pair<expr_ref_vector, expr_pair_vector>> s1, s2;
359
- si .push_back(std::make_pair(expr_ref_vector(m), expr_pair_vector()));
265
+ s1 .push_back (std::make_pair (expr_ref_vector (m), expr_pair_vector ()));
360
266
for (auto const & x2cond_sub : substs) {
267
+ s2.reset ();
361
268
for (auto const & cond_sub : x2cond_sub.second ) {
362
- s2.reset();
363
269
for (auto const & cond_subs : s1) {
364
270
expr_pair_vector pairs (cond_subs.second );
365
271
expr_ref_vector conds (cond_subs.first );
366
- pairs.push_back(x2cond_sub.first, cond_sub.second);
272
+ pairs.push_back (std::make_pair ( x2cond_sub.first , cond_sub.second ) );
367
273
conds.append (cond_sub.first );
368
274
s2.push_back (std::make_pair (conds, pairs));
369
275
}
370
- s1.swap(s2);
371
276
}
277
+ s1.swap (s2);
372
278
}
373
- s1.pop_back(); // last substitution is the identity.
279
+ s1.pop_back (); // last substitution is the identity
374
280
375
281
// extract lemmas from instantiations
376
282
for (auto & p : s1) {
377
- mk_hypothesis_lemam (p.first, p.second, alpha);
283
+ mk_hypothesis_lemma (p.first , p.second , alpha);
378
284
}
379
285
}
380
- #endif
381
286
382
- void induction_lemmas::create_lemmas (expr* sk, abstraction& a, literal lit) {
383
- std::cout << " abstraction: " << a.m_term << " \n " ;
384
- sort* s = m.get_sort (sk);
385
- if (!m_dt.is_datatype (s))
386
- return ;
387
- expr_ref alpha = a.m_term ;
388
- literal alpha_lit = mk_literal (alpha);
389
- if (lit.sign ()) alpha_lit.neg ();
390
-
391
- create_hypotheses (1 , sk, alpha_lit);
392
-
393
- literal_vector lits;
394
- // phi & eqs => alpha
395
- lits.push_back (~lit);
396
- for (auto const & p : a.m_eqs ) {
397
- lits.push_back (~mk_literal (m.mk_eq(p.first, p.second)));
398
- }
399
- lits.push_back (alpha_lit);
400
- add_th_lemma (lits);
401
- }
402
287
403
288
void induction_lemmas::add_th_lemma (literal_vector const & lits) {
404
289
IF_VERBOSE (0 , ctx.display_literals_verbose (verbose_stream () << " lemma:\n " , lits) << " \n " );
@@ -420,21 +305,35 @@ literal induction_lemmas::mk_literal(expr* e) {
420
305
bool induction_lemmas::operator ()(literal lit) {
421
306
unsigned num = m_num_lemmas;
422
307
enode* r = ctx.bool_var2enode (lit.var ());
423
- unsigned position = 0 ;
308
+ expr_ref_vector sks (m);
309
+ expr_safe_replace rep (m);
310
+
311
+ // have to be non-overlapping:
424
312
for (enode* n : induction_positions (r)) {
425
313
expr* t = n->get_owner ();
426
- sort* s = m.get_sort (t);
427
- expr_ref sk (m.mk_fresh_const (" sk" , s), m);
428
- std::cout << " abstract " << mk_pp (t, m) << " " << sk << " \n " ;
429
- abstractions abs ;
430
- abstract1 (r, n, sk, abs );
431
- if (abs .size () > 1 ) filter_abstractions (lit.sign (), abs );
432
- for (abstraction& a : abs ) {
433
- create_lemmas (sk, a, lit);
314
+ if (is_uninterp_const (t)) { // for now, to avoid overlapping terms
315
+ sort* s = m.get_sort (t);
316
+ expr_ref sk (m.mk_fresh_const (" sk" , s), m);
317
+ sks.push_back (sk);
318
+ rep.insert (t, sk);
434
319
}
435
- ++position;
436
320
}
437
- return m_num_lemmas > num;
321
+ expr_ref alpha (m);
322
+ ctx.literal2expr (lit, alpha);
323
+ rep (alpha);
324
+ literal alpha_lit = mk_literal (alpha);
325
+
326
+ // alpha is the minimal instance of induction_positions where lit holds
327
+ // alpha & is-c(sk) => ~alpha[sk/acc(sk)]
328
+ create_hypotheses (1 , sks, alpha_lit);
329
+ if (m_num_lemmas == num)
330
+ return false ;
331
+ // lit => alpha
332
+ literal_vector lits;
333
+ lits.push_back (~lit);
334
+ lits.push_back (alpha_lit);
335
+ add_th_lemma (lits);
336
+ return true ;
438
337
}
439
338
440
339
induction_lemmas::induction_lemmas (context& ctx, ast_manager& m, value_sweep& vs):
0 commit comments