std::pair<level, justification> substitution::instantiate_metavars(level const & l, bool use_jst) { if (!has_meta(l)) return mk_pair(l, justification()); justification j; auto save_jst = [&](justification const & j2) { j = mk_composite1(j, j2); }; level r = replace(l, [&](level const & l) { if (!has_meta(l)) { return some_level(l); } else if (is_meta(l)) { auto p1 = get_assignment(l); if (p1) { auto p2 = instantiate_metavars(p1->first, use_jst); if (use_jst) { justification new_jst = mk_composite1(p1->second, p2.second); assign(meta_id(l), p2.first, new_jst); save_jst(new_jst); } else { assign(meta_id(l), p2.first); } return some_level(p2.first); } } return none_level(); }); return mk_pair(r, j); }
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(); }); }
level instantiate(level const & l, level_param_names const & ps, levels const & ls) { lean_assert(length(ps) == length(ls)); return replace(l, [=](level const & l) { if (!has_param(l)) { return some_level(l); } else if (is_param(l)) { name const & id = param_id(l); list<name> const *it1 = &ps; list<level> const * it2 = &ls; while (!is_nil(*it1)) { if (head(*it1) == id) return some_level(head(*it2)); it1 = &tail(*it1); it2 = &tail(*it2); } return some_level(l); } else { return none_level(); } }); }
optional<level> substitution::get_level(name const & m) const { auto it = m_level_subst.find(m); return it ? some_level(*it) : none_level(); }