expr replace_visitor::visit_macro(expr const & e) { lean_assert(is_macro(e)); buffer<expr> new_args; for (unsigned i = 0; i < macro_num_args(e); i++) new_args.push_back(visit(macro_arg(e, i))); return update_macro(e, new_args.size(), new_args.data()); }
expr apply(expr const & a) { check_system("max_sharing"); auto r = m_expr_cache.find(a); if (r != m_expr_cache.end()) return *r; expr res; switch (a.kind()) { case expr_kind::Var: res = a; break; case expr_kind::Constant: res = update_constant(a, map(const_levels(a), [&](level const & l) { return apply(l); })); break; case expr_kind::Sort: res = update_sort(a, apply(sort_level(a))); break; case expr_kind::App: res = update_app(a, apply(app_fn(a)), apply(app_arg(a))); break; case expr_kind::Lambda: case expr_kind::Pi: res = update_binding(a, apply(binding_domain(a)), apply(binding_body(a))); break; case expr_kind::Meta: case expr_kind::Local: res = update_mlocal(a, apply(mlocal_type(a))); break; case expr_kind::Macro: { buffer<expr> new_args; for (unsigned i = 0; i < macro_num_args(a); i++) new_args.push_back(macro_arg(a, i)); res = update_macro(a, new_args.size(), new_args.data()); break; }} m_expr_cache.insert(res); return res; }
expr visit_macro(expr const & e) { buffer<expr> new_args; for (unsigned i = 0; i < macro_num_args(e); i++) new_args.push_back(visit(macro_arg(e, i))); auto def = macro_def(e); expr r = update_macro(e, new_args.size(), new_args.data()); if (def.trust_level() >= m_trust_lvl) { if (optional<expr> new_r = m_tc.expand_macro(r)) { return *new_r; } else { throw_generic_exception("failed to expand macro", e); } } else { return r; } }
virtual expr visit_macro(expr const & e) override { buffer<expr> new_args; for (unsigned i = 0; i < macro_num_args(e); i++) new_args.push_back(visit(macro_arg(e, i))); auto def = macro_def(e); expr r = update_macro(e, new_args.size(), new_args.data()); if (!m_trust_lvl || def.trust_level() >= *m_trust_lvl) { if (optional<expr> new_r = m_ctx.expand_macro(r)) { return visit(*new_r); } else { throw generic_exception(e, "failed to expand macro"); } } else { return r; } }
expr apply(expr const & e, unsigned offset) { bool shared = false; if (m_use_cache && is_shared(e)) { if (auto r = m_cache->find(e, offset)) return *r; shared = true; } check_interrupted(); check_memory("replace"); if (optional<expr> r = m_f(e, offset)) { return save_result(e, offset, *r, shared); } else { switch (e.kind()) { case expr_kind::Constant: case expr_kind::Sort: case expr_kind::Var: return save_result(e, offset, e, shared); case expr_kind::Meta: case expr_kind::Local: { expr new_t = apply(mlocal_type(e), offset); return save_result(e, offset, update_mlocal(e, new_t), shared); } case expr_kind::App: { expr new_f = apply(app_fn(e), offset); expr new_a = apply(app_arg(e), offset); return save_result(e, offset, update_app(e, new_f, new_a), shared); } case expr_kind::Pi: case expr_kind::Lambda: { expr new_d = apply(binding_domain(e), offset); expr new_b = apply(binding_body(e), offset+1); return save_result(e, offset, update_binding(e, new_d, new_b), shared); } case expr_kind::Macro: { buffer<expr> new_args; unsigned nargs = macro_num_args(e); for (unsigned i = 0; i < nargs; i++) new_args.push_back(apply(macro_arg(e, i), offset)); return save_result(e, offset, update_macro(e, new_args.size(), new_args.data()), shared); }} lean_unreachable(); } }
expr dsimplify_core_fn::visit_macro(expr const & e) { buffer<expr> new_args; for (unsigned i = 0; i < macro_num_args(e); i++) new_args.push_back(visit(macro_arg(e, i))); return update_macro(e, new_args.size(), new_args.data()); }