Skip to content

Commit 3985943

Browse files
na
Signed-off-by: Nikolaj Bjorner <[email protected]>
1 parent a34c5a9 commit 3985943

File tree

3 files changed

+38
-167
lines changed

3 files changed

+38
-167
lines changed

src/smt/smt_context.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1601,7 +1601,7 @@ namespace smt {
16011601
if (inconsistent())
16021602
return false;
16031603
}
1604-
#if 0
1604+
#if 1
16051605
if (at_search_level() && induction::should_try(*this)) {
16061606
get_induction()();
16071607
}

src/smt/smt_induction.cpp

Lines changed: 36 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ enode_vector induction_lemmas::induction_positions(enode* n) {
158158
for (unsigned i = 0; i < todo.size(); ++i) {
159159
n = todo[i];
160160
for (enode* a : smt::enode::args(n)) {
161-
add_todo(a);
161+
add_todo(a);
162162
if (!a->is_marked2() && viable_induction_term(n, a)) {
163163
result.push_back(a);
164164
a->set_mark2();
@@ -171,86 +171,7 @@ enode_vector induction_lemmas::induction_positions(enode* n) {
171171
n->unset_mark2();
172172
return result;
173173
}
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-
};
224174

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-
254175
/**
255176
extract substitutions for x into accessor values of the same sort.
256177
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
308229
*/
309230

310231
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);
313234
expr_safe_replace rep(m);
314235
for (auto const& p : subst) {
315236
rep.insert(p.first, p.second);
316237
}
317238
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)]
320240
literal_vector lits;
321241
lits.push_back(~alpha);
322242
for (expr* c : conds) lits.push_back(~mk_literal(c));
323-
lits.push_back(b_lit);
243+
lits.push_back(~mk_literal(beta));
324244
add_th_lemma(lits);
325245
}
326246

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
340247
void induction_lemmas::create_hypotheses(unsigned depth, expr_ref_vector const& sks, literal alpha) {
341248
if (sks.empty())
342249
return;
@@ -350,55 +257,33 @@ void induction_lemmas::create_hypotheses(unsigned depth, expr_ref_vector const&
350257
// append the identity substitution:
351258
expr_ref_vector conds(m);
352259
subst.push_back(std::make_pair(conds, expr_ref(sk, m)));
353-
354260
substs.push_back(std::make_pair(sk, subst));
355261
}
356262

357263
// create cross-product of instantiations:
358264
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()));
360266
for (auto const& x2cond_sub : substs) {
267+
s2.reset();
361268
for (auto const& cond_sub : x2cond_sub.second) {
362-
s2.reset();
363269
for (auto const& cond_subs : s1) {
364270
expr_pair_vector pairs(cond_subs.second);
365271
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));
367273
conds.append(cond_sub.first);
368274
s2.push_back(std::make_pair(conds, pairs));
369275
}
370-
s1.swap(s2);
371276
}
277+
s1.swap(s2);
372278
}
373-
s1.pop_back(); // last substitution is the identity.
279+
s1.pop_back(); // last substitution is the identity
374280

375281
// extract lemmas from instantiations
376282
for (auto& p : s1) {
377-
mk_hypothesis_lemam(p.first, p.second, alpha);
283+
mk_hypothesis_lemma(p.first, p.second, alpha);
378284
}
379285
}
380-
#endif
381286

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-
}
402287

403288
void induction_lemmas::add_th_lemma(literal_vector const& lits) {
404289
IF_VERBOSE(0, ctx.display_literals_verbose(verbose_stream() << "lemma:\n", lits) << "\n");
@@ -420,21 +305,35 @@ literal induction_lemmas::mk_literal(expr* e) {
420305
bool induction_lemmas::operator()(literal lit) {
421306
unsigned num = m_num_lemmas;
422307
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:
424312
for (enode* n : induction_positions(r)) {
425313
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);
434319
}
435-
++position;
436320
}
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;
438337
}
439338

440339
induction_lemmas::induction_lemmas(context& ctx, ast_manager& m, value_sweep& vs):

src/smt/smt_induction.h

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -58,30 +58,6 @@ namespace smt {
5858
unsigned m_num_lemmas;
5959

6060
typedef svector<std::pair<expr*,expr*>> expr_pair_vector;
61-
62-
struct abstraction {
63-
expr_ref m_term;
64-
expr_pair_vector m_eqs;
65-
abstraction(expr_ref& e): m_term(e) {}
66-
abstraction(ast_manager& m, expr* e, expr* n1, expr* n2): m_term(e, m) {
67-
if (n1 != n2) m_eqs.push_back(std::make_pair(n1, n2));
68-
}
69-
abstraction(ast_manager& m, expr* e, expr_pair_vector const& eqs):
70-
m_term(e, m), m_eqs(eqs) {
71-
}
72-
};
73-
typedef vector<abstraction> abstractions;
74-
75-
struct abstraction_arg {
76-
expr_ref_vector m_terms;
77-
expr_pair_vector m_eqs;
78-
abstraction_arg(ast_manager& m): m_terms(m) {}
79-
void push_back(abstraction& a) {
80-
m_terms.push_back(a.m_term);
81-
m_eqs.append(a.m_eqs);
82-
}
83-
};
84-
typedef vector<abstraction_arg> abstraction_args;
8561
typedef std::pair<expr_ref_vector, expr_ref> cond_subst_t;
8662
typedef vector<cond_subst_t> cond_substs_t;
8763

@@ -90,14 +66,10 @@ namespace smt {
9066
bool viable_induction_children(enode* n);
9167
bool viable_induction_term(enode* p , enode* n);
9268
enode_vector induction_positions(enode* n);
93-
void abstract(enode* n, enode* t, expr* x, abstractions& result);
94-
void abstract1(enode* n, enode* t, expr* x, abstractions& result);
95-
void filter_abstractions(bool sign, abstractions& abs);
96-
void create_lemmas(expr* sk, abstraction& a, literal lit);
9769
void mk_hypothesis_substs(unsigned depth, expr* x, cond_substs_t& subst);
9870
void mk_hypothesis_substs_rec(unsigned depth, sort* s, expr* y, expr_ref_vector& conds, cond_substs_t& subst);
9971
void mk_hypothesis_lemma(expr_ref_vector const& conds, expr_pair_vector const& subst, literal alpha);
100-
void create_hypotheses(unsigned depth, expr* sk, literal alpha);
72+
void create_hypotheses(unsigned depth, expr_ref_vector const& sks, literal alpha);
10173
literal mk_literal(expr* e);
10274
void add_th_lemma(literal_vector const& lits);
10375

0 commit comments

Comments
 (0)