예제 #1
0
파일: expr_lt.cpp 프로젝트: bmalehorn/lean
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();
}
예제 #2
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());
}
예제 #3
0
파일: level.cpp 프로젝트: pazthor/lean
bool is_geq_core(level l1, level l2) {
    if (l1 == l2 || is_zero(l2))
        return true;
    if (is_max(l2))
        return is_geq(l1, max_lhs(l2)) && is_geq(l1, max_rhs(l2));
    if (is_max(l1) && (is_geq(max_lhs(l1), l2) || is_geq(max_rhs(l1), l2)))
        return true;
    if (is_imax(l2))
        return is_geq(l1, imax_lhs(l2)) && is_geq(l1, imax_rhs(l2));
    if (is_imax(l1))
        return is_geq(imax_rhs(l1), l2);
    auto p1 = to_offset(l1);
    auto p2 = to_offset(l2);
    if (p1.first == p2.first || is_zero(p2.first))
        return p1.second >= p2.second;
    if (p1.second == p2.second && p1.second > 0)
        return is_geq(p1.first, p2.first);
    return false;
}
예제 #4
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;
 }
예제 #5
0
파일: level.cpp 프로젝트: pazthor/lean
level normalize(level const & l) {
    auto p = to_offset(l);
    level const & r = p.first;
    switch (kind(r)) {
    case level_kind::Succ:
        lean_unreachable(); // LCOV_EXCL_LINE
    case level_kind::Zero:   case level_kind::Param:
    case level_kind::Global: case level_kind::Meta:
        return l;
    case level_kind::IMax: {
        auto l1 = normalize(imax_lhs(r));
        auto l2 = normalize(imax_rhs(r));
        if (!is_eqp(l1, imax_lhs(r)) || !is_eqp(l2, imax_rhs(r)))
            return mk_succ(mk_imax(l1, l2), p.second);
        else
            return l;
    }
    case level_kind::Max: {
        buffer<level> todo;
        buffer<level> args;
        push_max_args(r, todo);
        for (level const & a : todo)
            push_max_args(normalize(a), args);
        std::sort(args.begin(), args.end(), is_norm_lt);
        buffer<level> & rargs = todo;
        rargs.clear();
        unsigned i = 0;
        if (is_explicit(args[i])) {
            // find max explicit univierse
            while (i+1 < args.size() && is_explicit(args[i+1]))
                i++;
            lean_assert(is_explicit(args[i]));
            unsigned k = to_offset(args[i]).second;
            // an explicit universe k is subsumed by succ^k(l)
            unsigned j = i+1;
            for (; j < args.size(); j++) {
                if (to_offset(args[j]).second >= k)
                    break;
            }
            if (j < args.size()) {
                // explicit universe was subsumed by succ^k'(l) where k' >= k
                i++;
            }
        }
        rargs.push_back(args[i]);
        auto p_prev = to_offset(args[i]);
        i++;
        for (; i < args.size(); i++) {
            auto p_curr = to_offset(args[i]);
            if (p_prev.first == p_curr.first) {
                if (p_prev.second < p_curr.second) {
                    p_prev = p_curr;
                    rargs.pop_back();
                    rargs.push_back(args[i]);
                }
            } else {
                p_prev = p_curr;
                rargs.push_back(args[i]);
            }
        }
        for (level & a : rargs)
            a = mk_succ(a, p.second);
        return mk_max(rargs);
    }}
    lean_unreachable(); // LCOV_EXCL_LINE
}