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(); }); }
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); }
optional<level> tmp_type_context::get_assignment(level const & u) const { unsigned idx = to_meta_idx(u); // if the following assetion is violated, we have two options: // 1- We should create the meta-variable using mk_uvar // 2- We create using mk_idx_metauniv, and notify this object using // set_next_uvar_idx if (idx >= m_uassignment.size()) return none_level(); return m_uassignment[idx]; }
void tmp_type_context::pop_core() { lean_assert(!m_scopes.empty()); scope const & s = m_scopes.back(); unsigned old_sz = s.m_trail_sz; unsigned i = m_trail.size(); while (i > old_sz) { --i; pair<trail_kind, unsigned> const & p = m_trail.back(); switch (p.first) { case trail_kind::Level: m_uassignment[p.second] = none_level(); break; case trail_kind::Expr: m_eassignment[p.second] = none_expr(); break; } m_trail.pop_back(); } lean_assert(m_trail.size() == old_sz); m_uassignment.resize(s.m_uassignment_sz); m_eassignment.resize(s.m_eassignment_sz); m_scopes.pop_back(); }
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(); }
level tmp_type_context::mk_uvar() { unsigned idx = m_uassignment.size(); m_uassignment.push_back(none_level()); return mk_idx_metauniv(idx); }