Esempio n. 1
0
// Monotonic total order on universe level terms.
bool is_lt(level const & a, level const & b, bool use_hash) {
    if (is_eqp(a, b))              return false;
    unsigned da = get_depth(a);
    unsigned db = get_depth(b);
    if (da < db)                   return true;
    if (da > db)                   return false;
    if (kind(a) != kind(b))        return kind(a) < kind(b);
    if (use_hash) {
        if (hash(a) < hash(b))         return true;
        if (hash(a) > hash(b))         return false;
    }
    if (a == b)                    return false;
    switch (kind(a)) {
    case level_kind::Zero:
        lean_unreachable(); // LCOV_EXCL_LINE
    case level_kind::Param: case level_kind::Global: case level_kind::Meta:
        return to_param_core(a).m_id < to_param_core(b).m_id;
    case level_kind::Max: case level_kind::IMax:
        if (to_max_core(a).m_lhs != to_max_core(b).m_lhs)
            return is_lt(to_max_core(a).m_lhs, to_max_core(b).m_lhs, use_hash);
        else
            return is_lt(to_max_core(a).m_rhs, to_max_core(b).m_rhs, use_hash);
    case level_kind::Succ:
        return is_lt(succ_of(a), succ_of(b), use_hash);
    }
    lean_unreachable(); // LCOV_EXCL_LINE
}
Esempio n. 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();
}
Esempio n. 3
0
bool operator==(level const & l1, level const & l2) {
    if (kind(l1) != kind(l2)) return false;
    if (hash(l1) != hash(l2)) return false;
    if (is_eqp(l1, l2))       return true;
    switch (kind(l1)) {
    case level_kind::Zero:
        return true;
    case level_kind::Param: case level_kind::Global: case level_kind::Meta:
        return to_param_core(l1).m_id == to_param_core(l2).m_id;
    case level_kind::Max: case level_kind::IMax: case level_kind::Succ:
        if (to_composite(l1).m_depth != to_composite(l2).m_depth)
            return false;
        break;
    }
    switch (kind(l1)) {
    case level_kind::Zero: case level_kind::Param: case level_kind::Global: case level_kind::Meta:
        lean_unreachable(); // LCOV_EXCL_LINE
    case level_kind::Max: case level_kind::IMax:
        return
            to_max_core(l1).m_lhs == to_max_core(l2).m_lhs &&
            to_max_core(l1).m_rhs == to_max_core(l2).m_rhs;
    case level_kind::Succ:
        if (is_explicit(l1) != is_explicit(l2)) {
            return false;
        } else if (is_explicit(l1)) {
            lean_assert(get_depth(l1) == get_depth(l2));
            // the depths are equal, then l1 and l2 must be the same universe
            return true;
        } else {
            return succ_of(l1) == succ_of(l2);
        }
    }
    lean_unreachable(); // LCOV_EXCL_LINE
}
Esempio n. 4
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());
}
Esempio n. 5
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;
        }
    }
}
Esempio n. 6
0
/** \brief Convert (succ^k l) into (l, k). If l is not a succ, then return (l, 0) */
pair<level, unsigned> to_offset(level l) {
    unsigned k = 0;
    while (is_succ(l)) {
        l = succ_of(l);
        k++;
    }
    return mk_pair(l, k);
}
Esempio n. 7
0
void for_each_level_fn::apply(level const & l) {
    if (!m_f(l))
        return;
    switch (l.kind()) {
    case level_kind::Succ:                          apply(succ_of(l)); break;
    case level_kind::Max: case level_kind::IMax:    apply(to_max_core(l).m_lhs); apply(to_max_core(l).m_rhs); break;
    case level_kind::Zero: case level_kind::Param:
    case level_kind::Meta: case level_kind::Global: break;
    }
}
Esempio n. 8
0
level replace_level_fn::apply(level const & l) {
    optional<level> r = m_f(l);
    if (r)
        return *r;
    switch (l.kind()) {
    case level_kind::Succ:
        return update_succ(l, apply(succ_of(l)));
    case level_kind::Max: case level_kind::IMax:
        return update_max(l, apply(to_max_core(l).m_lhs), apply(to_max_core(l).m_rhs));
    case level_kind::Zero: case level_kind::Param: case level_kind::Meta: case level_kind::Global:
        return l;
    }
    lean_unreachable(); // LCOV_EXCL_LINE
}
Esempio n. 9
0
 level apply(level const & l) {
     auto r = m_lvl_cache.find(l);
     if (r != m_lvl_cache.end())
         return *r;
     level res;
     switch (l.kind()) {
     case level_kind::Zero:   case level_kind::Param:
     case level_kind::Global: case level_kind::Meta:
         res = l;
         break;
     case level_kind::Succ:
         res = update_succ(l, apply(succ_of(l)));
         break;
     case level_kind::Max:
         res = update_max(l, apply(max_lhs(l)), apply(max_rhs(l)));
         break;
     case level_kind::IMax:
         res = update_max(l, apply(imax_lhs(l)), apply(imax_rhs(l)));
         break;
     }
     m_lvl_cache.insert(res);
     return res;
 }
Esempio n. 10
0
level update_succ(level const & l, level const & new_arg) {
    if (is_eqp(succ_of(l), new_arg))
        return l;
    else
        return mk_succ(new_arg);
}