Skip to content

Commit c94a9e8

Browse files
na
1 parent 8dd522d commit c94a9e8

File tree

2 files changed

+40
-19
lines changed

2 files changed

+40
-19
lines changed

src/smt/smt_induction.cpp

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -105,33 +105,49 @@ literal_vector collect_induction_literals::operator()() {
105105
// --------------------------------------
106106
// create_induction_lemmas
107107

108-
bool create_induction_lemmas::is_induction_candidate(enode* n) {
109-
app* e = n->get_owner();
110-
if (m.is_value(e))
111-
return false;
108+
bool create_induction_lemmas::viable_induction_sort(sort* s) {
109+
// potentially also induction on integers, sequences
110+
return m_dt.is_datatype(s) && m_dt.is_recursive(s);
111+
}
112+
113+
bool create_induction_lemmas::viable_induction_parent(enode* n) {
112114
bool in_good_context = false;
113115
for (enode* p : n->get_parents()) {
114116
app* o = p->get_owner();
115-
if (o->get_family_id() != m.get_basic_family_id())
116-
in_good_context = true;
117+
if (o->get_family_id() == m.get_basic_family_id())
118+
continue;
119+
if (o->get_family_id() == m_rec.get_family_id()) {
120+
in_good_context |= m_rec.is_defined(o);
121+
continue;
122+
}
123+
if (o->get_family_id() == m_dt.get_family_id()) {
124+
in_good_context |= m_dt.is_constructor(o);
125+
continue;
126+
}
117127
}
118-
if (!in_good_context)
119-
return false;
128+
return in_good_context;
129+
}
120130

121-
// avoid recursively unfolding skolem terms.
122-
if (e->get_num_args() > 0 && e->get_family_id() == null_family_id) {
131+
bool create_induction_lemmas::viable_induction_term(enode* n) {
132+
app* e = n->get_owner();
133+
if (m.is_value(e))
123134
return false;
124-
}
125-
sort* s = m.get_sort(e);
126-
if (m_dt.is_datatype(s) && m_dt.is_recursive(s))
135+
if (n->get_num_args() == 0)
127136
return true;
128-
129-
// potentially also induction on integers, sequences
130-
// m_arith.is_int(s)
131-
// return true;
137+
if (e->get_family_id() == m_rec.get_family_id())
138+
return m_rec.is_defined(e);
139+
if (e->get_family_id() == m_dt.get_family_id())
140+
return m_dt.is_constructor(e);
132141
return false;
133142
}
134143

144+
bool create_induction_lemmas::viable_induction_position(enode* n) {
145+
return
146+
viable_induction_sort(m.get_sort(n->get_owner())) &&
147+
viable_induction_parent(n) &&
148+
viable_induction_term(n);
149+
}
150+
135151
/**
136152
* positions in n that can be used for induction
137153
* the positions are distinct roots
@@ -152,7 +168,7 @@ enode_vector create_induction_lemmas::induction_positions(enode* n) {
152168
n = todo[i];
153169
for (enode* a : smt::enode::args(n))
154170
add_todo(a);
155-
if (is_induction_candidate(n))
171+
if (viable_induction_position(n))
156172
result.push_back(n);
157173
}
158174
for (enode* n : todo)
@@ -365,6 +381,7 @@ create_induction_lemmas::create_induction_lemmas(context& ctx, ast_manager& m, v
365381
vs(vs),
366382
m_dt(m),
367383
m_a(m),
384+
m_rec(m),
368385
m_num_lemmas(0)
369386
{}
370387

src/smt/smt_induction.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ namespace smt {
5454
value_sweep& vs;
5555
datatype::util m_dt;
5656
arith_util m_a;
57+
recfun::util m_rec;
5758
unsigned m_num_lemmas;
5859

5960
typedef svector<std::pair<expr*,expr*>> expr_pair_vector;
@@ -82,7 +83,10 @@ namespace smt {
8283
};
8384
typedef vector<abstraction_arg> abstraction_args;
8485

85-
bool is_induction_candidate(enode* n);
86+
bool viable_induction_sort(sort* s);
87+
bool viable_induction_parent(enode* n);
88+
bool viable_induction_term(enode* n);
89+
bool viable_induction_position(enode* n);
8690
enode_vector induction_positions(enode* n);
8791
void abstract(enode* n, enode* t, expr* x, abstractions& result);
8892
void abstract1(enode* n, enode* t, expr* x, abstractions& result);

0 commit comments

Comments
 (0)