Пример #1
0
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);
}
Пример #2
0
bool is_lt_no_level_params(level const & a, level const & b) {
    if (is_eqp(a, b))              return false;
    if (kind(a) != kind(b)) {
        if (kind(a) == level_kind::Param || kind(b) == level_kind::Param)
            return false;
        return kind(a) < kind(b);
    }
    switch (kind(a)) {
    case level_kind::Zero:
        lean_unreachable(); // LCOV_EXCL_LINE
    case level_kind::Param:
        return false;
    case level_kind::Global:
        return global_id(a) < global_id(b);
    case level_kind::Meta:
        return meta_id(a) < meta_id(b);
    case level_kind::Max:
        if (is_lt_no_level_params(max_lhs(a), max_lhs(b)))
            return true;
        else if (is_lt_no_level_params(max_lhs(b), max_lhs(a)))
            return false;
        else
            return is_lt_no_level_params(max_rhs(a), max_rhs(b));
    case level_kind::IMax:
        if (is_lt_no_level_params(imax_lhs(a), imax_lhs(b)))
            return true;
        else if (is_lt_no_level_params(imax_lhs(b), imax_lhs(a)))
            return false;
        else
            return is_lt_no_level_params(imax_rhs(a), imax_rhs(b));
    case level_kind::Succ:
        return is_lt_no_level_params(succ_of(a), succ_of(b));
    }
    lean_unreachable();
}
Пример #3
0
unsigned level_cases_on(vm_obj const & o, buffer<vm_obj> & data) {
    level const & l = to_level(o);
    switch (l.kind()) {
    case level_kind::Zero:
        break;
    case level_kind::Succ:
        data.push_back(to_obj(succ_of(l)));
        break;
    case level_kind::Max:
        data.push_back(to_obj(max_lhs(l)));
        data.push_back(to_obj(max_rhs(l)));
        break;
    case level_kind::IMax:
        data.push_back(to_obj(imax_lhs(l)));
        data.push_back(to_obj(imax_rhs(l)));
        break;
    case level_kind::Param:
        data.push_back(to_obj(param_id(l)));
        break;
    case level_kind::Global:
        data.push_back(to_obj(global_id(l)));
        break;
    case level_kind::Meta:
        data.push_back(to_obj(meta_id(l)));
        break;
    }
    return static_cast<unsigned>(l.kind());
}
Пример #4
0
 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();
         });
 }
Пример #5
0
format pp(level l, bool unicode, unsigned indent) {
    if (is_explicit(l)) {
        lean_assert(get_depth(l) > 0);
        return format(get_depth(l) - 1);
    } else {
        switch (kind(l)) {
        case level_kind::Zero:
            lean_unreachable(); // LCOV_EXCL_LINE
        case level_kind::Param: case level_kind::Global:
            return format(to_param_core(l).m_id);
        case level_kind::Meta:
            return format("?") + format(meta_id(l));
        case level_kind::Succ: {
            auto p = to_offset(l);
            return pp_child(p.first, unicode, indent) + format("+") + format(p.second);
        }
        case level_kind::Max: case level_kind::IMax: {
            format r = format(is_max(l) ? "max" : "imax");
            r += nest(indent, compose(line(), pp_child(to_max_core(l).m_lhs, unicode, indent)));
            // max and imax are right associative
            while (kind(to_max_core(l).m_rhs) == kind(l)) {
                l = to_max_core(l).m_rhs;
                r += nest(indent, compose(line(), pp_child(to_max_core(l).m_lhs, unicode, indent)));
            }
            r += nest(indent, compose(line(), pp_child(to_max_core(l).m_rhs, unicode, indent)));
            return group(r);
        }}
        lean_unreachable(); // LCOV_EXCL_LINE
    }
}
Пример #6
0
static void print(std::ostream & out, level l) {
    if (is_explicit(l)) {
        lean_assert(get_depth(l) > 0);
        out << get_depth(l) - 1;
    } else {
        switch (kind(l)) {
        case level_kind::Zero:
            lean_unreachable(); // LCOV_EXCL_LINE
        case level_kind::Param: case level_kind::Global:
            out << to_param_core(l).m_id; break;
        case level_kind::Meta:
            out << "?" << meta_id(l); break;
        case level_kind::Succ:
            out << "succ "; print_child(out, succ_of(l)); break;
        case level_kind::Max: case level_kind::IMax:
            if (is_max(l))
                out << "max ";
            else
                out << "imax ";
            print_child(out, to_max_core(l).m_lhs);
            // max and imax are right associative
            while (kind(to_max_core(l).m_rhs) == kind(l)) {
                l = to_max_core(l).m_rhs;
                out << " ";
                print_child(out, to_max_core(l).m_lhs);
            }
            out << " ";
            print_child(out, to_max_core(l).m_rhs);
            break;
        }
    }
}
Пример #7
0
unsigned to_meta_idx(level const & l) {
    lean_assert(is_idx_metauniv(l));
    return meta_id(l).get_numeral();
}
Пример #8
0
bool is_idx_metauniv(level const & l) {
    if (!is_meta(l))
        return false;
    name const & n = meta_id(l);
    return !n.is_atomic() && n.is_numeral() && n.get_prefix() == *g_tmp_prefix;
}