expr collect(expr const & e) { return replace(e, [&](expr const & e, unsigned) { if (is_metavar(e)) { name const & id = mlocal_name(e); if (auto r = m_meta_to_param.find(id)) { return some_expr(*r); } else { expr type = m_ctx.infer(e); expr x = m_ctx.push_local("_x", type); m_meta_to_param.insert(id, x); m_meta_to_param_inv.insert(mlocal_name(x), e); m_params.push_back(x); return some_expr(x); } } else if (is_local(e)) { name const & id = mlocal_name(e); if (!m_found_local.contains(id)) { m_found_local.insert(id); m_params.push_back(e); } } else if (is_sort(e)) { return some_expr(update_sort(e, collect(sort_level(e)))); } else if (is_constant(e)) { return some_expr(update_constant(e, collect(const_levels(e)))); } return none_expr(); }); }
level collect(level const & l) { return replace(l, [&](level const & l) { if (is_meta(l)) { name const & id = meta_id(l); if (auto r = m_univ_meta_to_param.find(id)) { return some_level(*r); } else { name n = m_prefix.append_after(m_next_idx); m_next_idx++; level new_r = mk_param_univ(n); m_univ_meta_to_param.insert(id, new_r); m_univ_meta_to_param_inv.insert(n, l); m_level_params.push_back(n); return some_level(new_r); } } else if (is_param(l)) { name const & id = param_id(l); if (!m_found_univ_params.contains(id)) { m_found_univ_params.insert(id); m_level_params.push_back(id); } } return none_level(); }); }
void get_constructor_info(name const & n, buffer<bool> & rel_fields) { if (auto r = m_constructor_info.find(n)) { to_buffer(*r, rel_fields); } else { get_constructor_relevant_fields(env(), n, rel_fields); m_constructor_info.insert(n, to_list(rel_fields)); } }
// Rename universe parameters occurring in l using the given mapping static level rename_param_levels(level const & l, name_map<name> const & param_name_map) { return replace(l, [&](level const & l) { if (is_param(l)) { if (auto it = param_name_map.find(param_id(l))) { return some_level(mk_param_univ(*it)); } } return none_level(); }); }
// Return a new ls s.t. there is no conflict between the names in ls and globals. // Store the mapping between old and new names in param_name_map. static level_param_names sanitize_level_params(level_param_names const & ls, name_set const & globals, name_map<name> & param_name_map) { buffer<name> new_params; for (name const & n : ls) { if (globals.contains(n)) { unsigned i = 1; name new_n = n.append_after(i); while (globals.contains(new_n)) { i++; name new_n = n.append_after(i); } param_name_map.insert(n, new_n); new_params.push_back(new_n); } else { new_params.push_back(n); } } if (param_name_map.empty()) return ls; return to_list(new_params.begin(), new_params.end()); }
pair<environment, expr> operator()(name const & c, expr const & type, expr const & value, bool is_lemma, optional<bool> const & is_meta) { lean_assert(!is_lemma || is_meta); lean_assert(!is_lemma || *is_meta == false); expr new_type = collect(m_ctx.instantiate_mvars(type)); expr new_value = collect(m_ctx.instantiate_mvars(value)); buffer<expr> norm_params; collect_and_normalize_dependencies(norm_params); new_type = replace_locals(new_type, m_params, norm_params); new_value = replace_locals(new_value, m_params, norm_params); expr def_type = m_ctx.mk_pi(norm_params, new_type); expr def_value = m_ctx.mk_lambda(norm_params, new_value); environment const & env = m_ctx.env(); declaration d; if (is_lemma) { d = mk_theorem(c, to_list(m_level_params), def_type, def_value); } else if (is_meta) { bool use_self_opt = true; d = mk_definition(env, c, to_list(m_level_params), def_type, def_value, use_self_opt, !*is_meta); } else { bool use_self_opt = true; d = mk_definition_inferring_trusted(env, c, to_list(m_level_params), def_type, def_value, use_self_opt); } environment new_env = module::add(env, check(env, d, true)); buffer<level> ls; for (name const & n : m_level_params) { if (level const * l = m_univ_meta_to_param_inv.find(n)) ls.push_back(*l); else ls.push_back(mk_param_univ(n)); } buffer<expr> ps; for (expr const & x : m_params) { if (expr const * m = m_meta_to_param_inv.find(mlocal_name(x))) ps.push_back(*m); else ps.push_back(x); } expr r = mk_app(mk_constant(c, to_list(ls)), ps); return mk_pair(new_env, r); }