@@ -181,6 +181,10 @@ inline void pattern_inference_cfg::collect::save(expr * n, unsigned delta, info
181181}
182182
183183void pattern_inference_cfg::collect::save_candidate (expr * n, unsigned delta) {
184+ if (m_owner.m_params .m_pi_legacy_nested_binders ) {
185+ save_candidate_legacy (n, delta);
186+ return ;
187+ }
184188 switch (n->get_kind ()) {
185189 case AST_VAR : {
186190 uint_set free_vars, bound_vars;
@@ -189,7 +193,7 @@ void pattern_inference_cfg::collect::save_candidate(expr * n, unsigned delta) {
189193 free_vars.insert (idx - delta);
190194 else if (idx < delta)
191195 bound_vars.insert (idx);
192- info * i = alloc (info, free_vars, bound_vars, 1 );
196+ info * i = alloc (info, m, n, free_vars, bound_vars, 1 );
193197 save (n, delta, i);
194198 return ;
195199 }
@@ -201,7 +205,7 @@ void pattern_inference_cfg::collect::save_candidate(expr * n, unsigned delta) {
201205 }
202206
203207 if (c->get_num_args () == 0 ) {
204- save (n, delta, alloc (info, uint_set (), uint_set (), 1 ));
208+ save (n, delta, alloc (info, m, n, uint_set (), uint_set (), 1 ));
205209 return ;
206210 }
207211
@@ -219,7 +223,7 @@ void pattern_inference_cfg::collect::save_candidate(expr * n, unsigned delta) {
219223 size += child_info->m_size ;
220224 }
221225
222- save (n, delta, alloc (info, free_vars, bound_vars, size));
226+ save (n, delta, alloc (info, m, n, free_vars, bound_vars, size));
223227 // Remark: arithmetic patterns are only used if they are nested inside other terms.
224228 // That is, we never consider x + 1 as pattern. On the other hand, f(x+1) can be a pattern
225229 // if arithmetic is not in the forbidden list.
@@ -251,7 +255,82 @@ void pattern_inference_cfg::collect::save_candidate(expr * n, unsigned delta) {
251255 if (b >= num_decls)
252256 bound_vars.insert (b - num_decls);
253257
254- save (n, delta, alloc (info, body_info->m_free_vars , bound_vars, body_info->m_size + 1 ));
258+ save (n, delta, alloc (info, m, n, body_info->m_free_vars , bound_vars, body_info->m_size + 1 ));
259+ return ;
260+ }
261+ default :
262+ save (n, delta, nullptr );
263+ return ;
264+ }
265+ }
266+
267+ void pattern_inference_cfg::collect::save_candidate_legacy (expr * n, unsigned delta) {
268+ switch (n->get_kind ()) {
269+ case AST_VAR : {
270+ unsigned idx = to_var (n)->get_idx ();
271+ if (idx < delta) {
272+ save (n, delta, nullptr );
273+ return ;
274+ }
275+ idx -= delta;
276+ uint_set free_vars;
277+ if (idx < m_num_bindings)
278+ free_vars.insert (idx);
279+ expr * new_node = delta == 0 ? n : m.mk_var (idx, to_var (n)->get_sort ());
280+ save (n, delta, alloc (info, m, new_node, free_vars, 1 ));
281+ return ;
282+ }
283+ case AST_APP : {
284+ app * c = to_app (n);
285+ if (m_owner.is_forbidden (c)) {
286+ save (n, delta, nullptr );
287+ return ;
288+ }
289+ if (c->get_num_args () == 0 ) {
290+ save (n, delta, alloc (info, m, n, uint_set (), 1 ));
291+ return ;
292+ }
293+ ptr_buffer<expr> args;
294+ bool changed = false ;
295+ uint_set free_vars;
296+ unsigned size = 1 ;
297+ for (expr * child : *c) {
298+ info * child_info = nullptr ;
299+ VERIFY (m_cache.find (entry (child, delta), child_info));
300+ if (!child_info) {
301+ save (n, delta, nullptr );
302+ return ;
303+ }
304+ args.push_back (child_info->m_node );
305+ free_vars |= child_info->m_free_vars ;
306+ size += child_info->m_size ;
307+ changed |= child != child_info->m_node ;
308+ }
309+ app * new_node = changed ? m.mk_app (c->get_decl (), args.size (), args.data ()) : c;
310+ save (n, delta, alloc (info, m, new_node, free_vars, size));
311+ family_id fid = c->get_family_id ();
312+ decl_kind k = c->get_decl_kind ();
313+ if (!free_vars.empty () &&
314+ (fid != m_afid || (fid == m_afid && !m_owner.m_nested_arith_only &&
315+ (k == OP_DIV || k == OP_IDIV || k == OP_MOD || k == OP_REM || k == OP_MUL ))))
316+ m_owner.add_candidate (new_node, free_vars, size);
317+ return ;
318+ }
319+ case AST_QUANTIFIER : {
320+ quantifier * q = to_quantifier (n);
321+ unsigned num_decls = q->get_num_decls ();
322+ info * body_info = nullptr ;
323+ m_cache.find (entry (q->get_expr (), delta + num_decls), body_info);
324+ if (!body_info) {
325+ save (n, delta, nullptr );
326+ return ;
327+ }
328+ expr_ref new_body (m);
329+ var_shifter shift (m);
330+ shift (body_info->m_node , num_decls, new_body);
331+ quantifier_ref new_q (m);
332+ new_q = new_body == q->get_expr () ? q : m.update_quantifier (q, new_body);
333+ save (n, delta, alloc (info, m, new_q, body_info->m_free_vars , body_info->m_size + 1 ));
255334 return ;
256335 }
257336 default :
0 commit comments