@@ -105,33 +105,49 @@ literal_vector collect_induction_literals::operator()() {
105
105
// --------------------------------------
106
106
// create_induction_lemmas
107
107
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) {
112
114
bool in_good_context = false ;
113
115
for (enode* p : n->get_parents ()) {
114
116
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
+ }
117
127
}
118
- if (! in_good_context)
119
- return false ;
128
+ return in_good_context;
129
+ }
120
130
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))
123
134
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 )
127
136
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) ;
132
141
return false ;
133
142
}
134
143
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
+
135
151
/* *
136
152
* positions in n that can be used for induction
137
153
* the positions are distinct roots
@@ -152,7 +168,7 @@ enode_vector create_induction_lemmas::induction_positions(enode* n) {
152
168
n = todo[i];
153
169
for (enode* a : smt::enode::args (n))
154
170
add_todo (a);
155
- if (is_induction_candidate (n))
171
+ if (viable_induction_position (n))
156
172
result.push_back (n);
157
173
}
158
174
for (enode* n : todo)
@@ -365,6 +381,7 @@ create_induction_lemmas::create_induction_lemmas(context& ctx, ast_manager& m, v
365
381
vs(vs),
366
382
m_dt(m),
367
383
m_a(m),
384
+ m_rec(m),
368
385
m_num_lemmas(0 )
369
386
{}
370
387
0 commit comments