Exemplo n.º 1
0
void initialize_change_tactic() {
    register_tac(get_tactic_change_name(),
                 [](type_checker &, elaborate_fn const & fn, expr const & e, pos_info_provider const *) {
                     check_tactic_expr(app_arg(e), "invalid 'change' tactic, invalid argument");
                     return change_goal_tactic(fn, get_tactic_expr_expr(app_arg(e)));
                 });
}
Exemplo n.º 2
0
 bool apply(expr const & a, expr const & b) {
     if (is_eqp(a, b))          return true;
     if (a.hash() != b.hash())  return false;
     if (a.kind() != b.kind())  return false;
     if (is_var(a))             return var_idx(a) == var_idx(b);
     if (m_cache.check(a, b))
         return true;
     switch (a.kind()) {
     case expr_kind::Var:
         lean_unreachable(); // LCOV_EXCL_LINE
     case expr_kind::Constant:
         return
             const_name(a) == const_name(b) &&
             compare(const_levels(a), const_levels(b), [](level const & l1, level const & l2) { return l1 == l2; });
     case expr_kind::Meta:
         return
             mlocal_name(a) == mlocal_name(b) &&
             apply(mlocal_type(a), mlocal_type(b));
     case expr_kind::Local:
         return
             mlocal_name(a) == mlocal_name(b) &&
             apply(mlocal_type(a), mlocal_type(b)) &&
             (!CompareBinderInfo || local_pp_name(a) == local_pp_name(b)) &&
             (!CompareBinderInfo || local_info(a) == local_info(b));
     case expr_kind::App:
         check_system();
         return
             apply(app_fn(a), app_fn(b)) &&
             apply(app_arg(a), app_arg(b));
     case expr_kind::Lambda: case expr_kind::Pi:
         check_system();
         return
             apply(binding_domain(a), binding_domain(b)) &&
             apply(binding_body(a), binding_body(b)) &&
             (!CompareBinderInfo || binding_name(a) == binding_name(b)) &&
             (!CompareBinderInfo || binding_info(a) == binding_info(b));
     case expr_kind::Let:
         check_system();
         return
             apply(let_type(a), let_type(b)) &&
             apply(let_value(a), let_value(b)) &&
             apply(let_body(a), let_body(b)) &&
             (!CompareBinderInfo || let_name(a) == let_name(b));
     case expr_kind::Sort:
         return sort_level(a) == sort_level(b);
     case expr_kind::Macro:
         check_system();
         if (macro_def(a) != macro_def(b) || macro_num_args(a) != macro_num_args(b))
             return false;
         for (unsigned i = 0; i < macro_num_args(a); i++) {
             if (!apply(macro_arg(a, i), macro_arg(b, i)))
                 return false;
         }
         return true;
     }
     lean_unreachable(); // LCOV_EXCL_LINE
 }
Exemplo n.º 3
0
bool is_lt(expr const & a, expr const & b, bool use_hash) {
    if (is_eqp(a, b))                    return false;
    unsigned wa = get_weight(a);
    unsigned wb = get_weight(b);
    if (wa < wb)                         return true;
    if (wa > wb)                         return false;
    if (a.kind() != b.kind())            return a.kind() < b.kind();
    if (use_hash) {
        if (a.hash() < b.hash())         return true;
        if (a.hash() > b.hash())         return false;
    }
    if (a == b)                          return false;
    switch (a.kind()) {
    case expr_kind::Var:
        return var_idx(a) < var_idx(b);
    case expr_kind::Constant:
        if (const_name(a) != const_name(b))
            return const_name(a) < const_name(b);
        else
            return is_lt(const_levels(a), const_levels(b), use_hash);
    case expr_kind::App:
        if (app_fn(a) != app_fn(b))
            return is_lt(app_fn(a), app_fn(b), use_hash);
        else
            return is_lt(app_arg(a), app_arg(b), use_hash);
    case expr_kind::Lambda: case expr_kind::Pi:
        if (binding_domain(a) != binding_domain(b))
            return is_lt(binding_domain(a), binding_domain(b), use_hash);
        else
            return is_lt(binding_body(a), binding_body(b), use_hash);
    case expr_kind::Let:
        if (let_type(a) != let_type(b))
            return is_lt(let_type(a), let_type(b), use_hash);
        else if (let_value(a) != let_value(b))
            return is_lt(let_value(a), let_value(b), use_hash);
        else
            return is_lt(let_body(a), let_body(b), use_hash);
    case expr_kind::Sort:
        return is_lt(sort_level(a), sort_level(b), use_hash);
    case expr_kind::Local: case expr_kind::Meta:
        if (mlocal_name(a) != mlocal_name(b))
            return mlocal_name(a) < mlocal_name(b);
        else
            return is_lt(mlocal_type(a), mlocal_type(b), use_hash);
    case expr_kind::Macro:
        if (macro_def(a) != macro_def(b))
            return macro_def(a) < macro_def(b);
        if (macro_num_args(a) != macro_num_args(b))
            return macro_num_args(a) < macro_num_args(b);
        for (unsigned i = 0; i < macro_num_args(a); i++) {
            if (macro_arg(a, i) != macro_arg(b, i))
                return is_lt(macro_arg(a, i), macro_arg(b, i), use_hash);
        }
        return false;
    }
    lean_unreachable(); // LCOV_EXCL_LINE
}
Exemplo n.º 4
0
bool expr_eq_fn::apply(expr const & a, expr const & b) {
    if (is_eqp(a, b))          return true;
    if (a.hash() != b.hash())  return false;
    if (a.kind() != b.kind())  return false;
    if (is_var(a))             return var_idx(a) == var_idx(b);
    if (m_counter >= LEAN_EQ_CACHE_THRESHOLD && is_shared(a) && is_shared(b)) {
        auto p = std::make_pair(a.raw(), b.raw());
        if (!m_eq_visited)
            m_eq_visited.reset(new expr_cell_pair_set);
        if (m_eq_visited->find(p) != m_eq_visited->end())
            return true;
        m_eq_visited->insert(p);
    }
    check_system("expression equality test");
    switch (a.kind()) {
    case expr_kind::Var:
        lean_unreachable(); // LCOV_EXCL_LINE
    case expr_kind::Constant:
        return
            const_name(a) == const_name(b) &&
            compare(const_levels(a), const_levels(b), [](level const & l1, level const & l2) { return l1 == l2; });
    case expr_kind::Local: case expr_kind::Meta:
        return
            mlocal_name(a) == mlocal_name(b) &&
            apply(mlocal_type(a), mlocal_type(b));
    case expr_kind::App:
        m_counter++;
        return
            apply(app_fn(a), app_fn(b)) &&
            apply(app_arg(a), app_arg(b));
    case expr_kind::Lambda: case expr_kind::Pi:
        m_counter++;
        return
            apply(binding_domain(a), binding_domain(b)) &&
            apply(binding_body(a), binding_body(b)) &&
            (!m_compare_binder_info || binding_info(a) == binding_info(b));
    case expr_kind::Sort:
        return sort_level(a) == sort_level(b);
    case expr_kind::Macro:
        m_counter++;
        if (macro_def(a) != macro_def(b) || macro_num_args(a) != macro_num_args(b))
            return false;
        for (unsigned i = 0; i < macro_num_args(a); i++) {
            if (!apply(macro_arg(a, i), macro_arg(b, i)))
                return false;
        }
        return true;
    case expr_kind::Let:
        m_counter++;
        return
            apply(let_type(a), let_type(b)) &&
            apply(let_value(a), let_value(b)) &&
            apply(let_body(a), let_body(b));
    }
    lean_unreachable(); // LCOV_EXCL_LINE
}
Exemplo n.º 5
0
void initialize_check_expr_tactic() {
    register_tac(get_tactic_check_expr_name(),
                 [](type_checker &, elaborate_fn const & fn, expr const & e, pos_info_provider const * p) {
                     check_tactic_expr(app_arg(e), "invalid 'check_expr' tactic, invalid argument");
                     expr arg = get_tactic_expr_expr(app_arg(e));
                     if (p) {
                         if (auto it = p->get_pos_info(e))
                             return check_expr_tactic(fn, arg, std::string(p->get_file_name()), *it);
                     }
                     return check_expr_tactic(fn, arg, "<unknown file>", mk_pair(0, 0));
                 });
}
Exemplo n.º 6
0
void initialize_intros_tactic() {
    register_tac(get_tactic_intro_name(),
                 [](type_checker &, elaborate_fn const &, expr const & e, pos_info_provider const *) {
                     name const & id = tactic_expr_to_id(app_arg(e), "invalid 'intro' tactic, argument must be an identifier");
                     return intros_tactic(to_list(id));
                 });
    register_tac(get_tactic_intros_name(),
                 [](type_checker &, elaborate_fn const &, expr const & e, pos_info_provider const *) {
                     buffer<name> ns;
                     get_tactic_id_list_elements(app_arg(e), ns, "invalid 'intros' tactic, arguments must be identifiers");
                     return intros_tactic(to_list(ns.begin(), ns.end()));
                 });
}
Exemplo n.º 7
0
bool is_lt_no_level_params(expr const & a, expr const & b) {
    if (is_eqp(a, b))                    return false;
    unsigned wa = get_weight(a);
    unsigned wb = get_weight(b);
    if (wa < wb)                         return true;
    if (wa > wb)                         return false;
    if (a.kind() != b.kind())            return a.kind() < b.kind();
    switch (a.kind()) {
    case expr_kind::Var:
        return var_idx(a) < var_idx(b);
    case expr_kind::Constant:
        if (const_name(a) != const_name(b))
            return const_name(a) < const_name(b);
        else
            return is_lt_no_level_params(const_levels(a), const_levels(b));
    case expr_kind::App:
        if (is_lt_no_level_params(app_fn(a), app_fn(b)))
            return true;
        else if (is_lt_no_level_params(app_fn(b), app_fn(a)))
            return false;
        else
            return is_lt_no_level_params(app_arg(a), app_arg(b));
    case expr_kind::Lambda: case expr_kind::Pi:
        if (is_lt_no_level_params(binding_domain(a), binding_domain(b)))
            return true;
        else if (is_lt_no_level_params(binding_domain(b), binding_domain(a)))
            return false;
        else
            return is_lt_no_level_params(binding_body(a), binding_body(b));
    case expr_kind::Sort:
        return is_lt_no_level_params(sort_level(a), sort_level(b));
    case expr_kind::Local: case expr_kind::Meta:
        if (mlocal_name(a) != mlocal_name(b))
            return mlocal_name(a) < mlocal_name(b);
        else
            return is_lt_no_level_params(mlocal_type(a), mlocal_type(b));
    case expr_kind::Macro:
        if (macro_def(a) != macro_def(b))
            return macro_def(a) < macro_def(b);
        if (macro_num_args(a) != macro_num_args(b))
            return macro_num_args(a) < macro_num_args(b);
        for (unsigned i = 0; i < macro_num_args(a); i++) {
            if (is_lt_no_level_params(macro_arg(a, i), macro_arg(b, i)))
                return true;
            else if (is_lt_no_level_params(macro_arg(b, i), macro_arg(a, i)))
                return false;
        }
        return false;
    }
    lean_unreachable();
}
Exemplo n.º 8
0
void forward_branch_extension::index_expr(expr const & e) {
    // TODO(dhs): index the target when it gets updated

    if (auto head_idx = to_head_index(e)) {
        m_index.insert(head_index(e), e);
    }
    switch (e.kind()) {
    case expr_kind::Var:
        lean_unreachable();  // LCOV_EXCL_LINE
    case expr_kind::Local:
    case expr_kind::Meta:
    case expr_kind::Sort:
    case expr_kind::Constant:
    case expr_kind::Macro: // TODO(dhs): do I unfold macros?
        break;
    case expr_kind::Lambda:
    case expr_kind::Pi:
        // TODO(dhs): confirm that I only index quantified-free hypotheses
        break;
    case expr_kind::Let:
        // Let-expressions must be unfolded before invoking this method
        lean_unreachable();
    case expr_kind::App:
        index_expr(app_fn(e));
        index_expr(app_arg(e));
        break;
    }
}
Exemplo n.º 9
0
 expr apply(expr const & a) {
     check_system("max_sharing");
     auto r = m_expr_cache.find(a);
     if (r != m_expr_cache.end())
         return *r;
     expr res;
     switch (a.kind()) {
     case expr_kind::Var:
         res = a;
         break;
     case expr_kind::Constant:
         res = update_constant(a, map(const_levels(a), [&](level const & l) { return apply(l); }));
         break;
     case expr_kind::Sort:
         res = update_sort(a, apply(sort_level(a)));
         break;
     case expr_kind::App:
         res = update_app(a, apply(app_fn(a)), apply(app_arg(a)));
         break;
     case expr_kind::Lambda: case expr_kind::Pi:
         res = update_binding(a, apply(binding_domain(a)), apply(binding_body(a)));
         break;
     case expr_kind::Meta:  case expr_kind::Local:
         res = update_mlocal(a, apply(mlocal_type(a)));
         break;
     case expr_kind::Macro: {
         buffer<expr> new_args;
         for (unsigned i = 0; i < macro_num_args(a); i++)
             new_args.push_back(macro_arg(a, i));
         res = update_macro(a, new_args.size(), new_args.data());
         break;
     }}
     m_expr_cache.insert(res);
     return res;
 }
Exemplo n.º 10
0
void Structure::assert_valid() {
    POMAGMA_INFO("Validating solver::Structure");

    // Check atoms.
    POMAGMA_ASSERT(term_arity(TermAtom::TOP) == TermArity::TOP, "Missing TOP");
    POMAGMA_ASSERT(term_arity(TermAtom::BOT) == TermArity::BOT, "Missing BOT");
    POMAGMA_ASSERT(term_arity(TermAtom::I) == TermArity::I, "Missing I");
    POMAGMA_ASSERT(term_arity(TermAtom::K) == TermArity::K, "Missing K");
    POMAGMA_ASSERT(term_arity(TermAtom::B) == TermArity::B, "Missing B");
    POMAGMA_ASSERT(term_arity(TermAtom::C) == TermArity::C, "Missing C");
    POMAGMA_ASSERT(term_arity(TermAtom::S) == TermArity::S, "Missing S");

    // Check terms.
    const Term max_term = term_arity_.size() - 1;
    for (Term term = 1; term <= max_term; ++term) {
        const TermArity arity = term_arity(term);
        switch (arity) {
            case TermArity::IVAR: {
                const unsigned rank = ivar_arg(term);
                POMAGMA_ASSERT_EQ(term, ivar(rank));
                break;
            }
            case TermArity::NVAR: {
                const std::string& name = nvar_arg(term);
                POMAGMA_ASSERT_EQ(term, nvar(name));
                break;
            }
            case TermArity::APP: {
                Term lhs;
                Term rhs;
                std::tie(lhs, rhs) = app_arg(term);
                POMAGMA_ASSERT_EQ(term, app(lhs, rhs));
                break;
            }
            case TermArity::JOIN: {
                Term lhs;
                Term rhs;
                std::tie(lhs, rhs) = join_arg(term);
                POMAGMA_ASSERT_EQ(term, join(lhs, rhs));
                break;
            }
            default:
                break;
        }
    }

    // Check literals.
    const Literal max_lit = less_arg_.size() - 1;
    for (Literal lit = 1; lit <= max_lit; ++lit) {
        Term lhs;
        Term rhs;

        std::tie(lhs, rhs) = literal_arg(lit);
        POMAGMA_ASSERT_EQ(lit, less(lhs, rhs));

        std::tie(lhs, rhs) = literal_arg(-lit);
        POMAGMA_ASSERT_EQ(-lit, nless(lhs, rhs));
    }
}
Exemplo n.º 11
0
expr const & get_app_rev_args(expr const & e, buffer<expr> & args) {
    expr const * it = &e;
    while (is_app(*it)) {
        args.push_back(app_arg(*it));
        it = &(app_fn(*it));
    }
    return *it;
}
Exemplo n.º 12
0
 expr pack(unsigned i, unsigned arity, buffer<expr> const & args, expr const & type) {
     lean_assert(arity > 0);
     if (i == arity - 1) {
         return args[i];
     } else {
         lean_assert(is_constant(get_app_fn(type), get_psigma_name()));
         expr a        = args[i];
         expr A        = app_arg(app_fn(type));
         expr B        = app_arg(type);
         lean_assert(is_lambda(B));
         expr new_type = instantiate(binding_body(B), a);
         expr b        = pack(i+1, arity, args, new_type);
         bool mask[2]  = {true, true};
         expr AB[2]    = {A, B};
         return mk_app(mk_app(m_ctx, get_psigma_mk_name(), 2, mask, AB), a, b);
     }
 }
Exemplo n.º 13
0
void initialize_clear_tactic() {
    register_tac(get_tactic_clear_name(),
                 [](type_checker &, elaborate_fn const &, expr const & e, pos_info_provider const *) {
                     name n = tactic_expr_to_id(app_arg(e), "invalid 'clear' tactic, argument must be an identifier");
                     return clear_tactic(n);
                 });
    register_tac(get_tactic_clears_name(),
                 [](type_checker &, elaborate_fn const &, expr const & e, pos_info_provider const *) {
                     buffer<name> ns;
                     get_tactic_id_list_elements(app_arg(e), ns, "invalid 'clears' tactic, list of identifiers expected");
                     tactic r = clear_tactic(ns.back());
                     ns.pop_back();
                     while (!ns.empty()) {
                         r = then(clear_tactic(ns.back()), r);
                         ns.pop_back();
                     }
                     return r;
                 });
}
Exemplo n.º 14
0
expr const & get_app_args(expr const & e, buffer<expr> & args) {
    unsigned sz = args.size();
    expr const * it = &e;
    while (is_app(*it)) {
        args.push_back(app_arg(*it));
        it = &(app_fn(*it));
    }
    std::reverse(args.begin() + sz, args.end());
    return *it;
}
Exemplo n.º 15
0
 /** \brief Given l : H, and R == (or ... l ...), create a proof term for R using or_intro_left and or_intro_right */
 expr mk_or_intro(expr const & l, expr const & H, expr const & R, extension_context & ctx) const {
     check_system("resolve macro");
     if (is_or_app(R)) {
         expr lhs = app_arg(app_fn(R));
         expr rhs = app_arg(R);
         // or_intro_left {a : Prop} (H : a) (b : Prop) : a ∨ b
         // or_intro_right {b : Prop} (a : Prop) (H : b) : a ∨ b
         if (is_def_eq(l, lhs, ctx)) {
             return mk_app(*g_or_intro_left, l, H, rhs);
         } else if (is_def_eq(l, rhs, ctx)) {
             return mk_app(*g_or_intro_right, l, lhs, H);
         } else {
             return mk_app(*g_or_intro_right, rhs, lhs, mk_or_intro(l, H, rhs, ctx));
         }
     } else if (is_def_eq(l, R, ctx)) {
         return H;
     } else {
         throw_kernel_exception(ctx.env(), "bug in resolve macro");
     }
 }
Exemplo n.º 16
0
static optional<pair<expr, unsigned>> find_hyp_core(expr const & meta, F && pred) {
    expr const * it = &meta;
    unsigned i = 0;
    while (is_app(*it)) {
        expr const & h = app_arg(*it);
        if (pred(h))
            return some(mk_pair(h, i));
        i++;
        it = &app_fn(*it);
    }
    return optional<pair<expr, unsigned>>();
}
Exemplo n.º 17
0
void initialize_revert_tactic() {
    auto fn = [](type_checker &, elaborate_fn const &, expr const & e, pos_info_provider const *) {
        buffer<name> ns;
        get_tactic_id_list_elements(app_arg(e), ns, "invalid 'reverts' tactic, list of identifiers expected");
        tactic r = revert_tactic(ns[0]);
        for (unsigned i = 1; i < ns.size(); i++)
            r = then(revert_tactic(ns[i]), r);
        return r;
    };
    register_tac(get_tactic_revert_name(), fn);
    register_tac(get_tactic_reverts_name(), fn);
}
Exemplo n.º 18
0
static bool is_permutation(expr const & lhs, expr const & rhs, unsigned offset, buffer<optional<unsigned>> & p) {
    if (lhs.kind() != rhs.kind())
        return false;
    switch (lhs.kind()) {
    case expr_kind::Constant: case expr_kind::Sort:
    case expr_kind::Meta: case expr_kind::Local:
        return lhs == rhs;
    case expr_kind::Var:
        if (var_idx(lhs) < offset) {
            return lhs == rhs; // locally bound variable
        } else if (var_idx(lhs) - offset < p.size()) {
            if (p[var_idx(lhs) - offset]) {
                return *(p[var_idx(lhs) - offset]) == var_idx(rhs);
            } else {
                p[var_idx(lhs) - offset] = var_idx(rhs);
                return true;
            }
        } else {
            return lhs == rhs; // free variable
        }
    case expr_kind::Lambda: case expr_kind::Pi:
        return
            is_permutation(binding_domain(lhs), binding_domain(rhs), offset, p) &&
            is_permutation(binding_body(lhs), binding_body(rhs), offset+1, p);
    case expr_kind::App:
        return
            is_permutation(app_fn(lhs), app_fn(rhs), offset, p) &&
            is_permutation(app_arg(lhs), app_arg(rhs), offset, p);
    case expr_kind::Macro:
        if (macro_def(lhs) != macro_def(rhs) ||
            macro_num_args(lhs) != macro_num_args(rhs))
            return false;
        for (unsigned i = 0; i < macro_num_args(lhs); i++) {
            if (!is_permutation(macro_arg(lhs, i), macro_arg(rhs, i), offset, p))
                return false;
        }
        return true;
    }
    lean_unreachable();
}
Exemplo n.º 19
0
expr const & get_app_args_at_most(expr const & e, unsigned num, buffer<expr> & args) {
    unsigned sz = args.size();
    expr const * it = &e;
    unsigned i = 0;
    while (is_app(*it)) {
        if (i == num)
            break;
        args.push_back(app_arg(*it));
        it = &(app_fn(*it));
        i++;
    }
    std::reverse(args.begin() + sz, args.end());
    return *it;
}
Exemplo n.º 20
0
void collect_locals(expr const & e, collected_locals & ls, bool restricted) {
    if (!has_local(e))
        return;
    expr_set visited;
    std::function<void(expr const & e)> visit = [&](expr const & e) {
        if (!has_local(e))
            return;
        if (restricted && is_meta(e))
            return;
        if (visited.find(e) != visited.end())
            return;
        visited.insert(e);
        switch (e.kind()) {
        case expr_kind::Var: case expr_kind::Constant: case expr_kind::Sort:
            break; // do nothing
        case expr_kind::Local:
            if (!restricted)
                visit(mlocal_type(e));
            ls.insert(e);
            break;
        case expr_kind::Meta:
            lean_assert(!restricted);
            visit(mlocal_type(e));
            break;
        case expr_kind::Macro:
            for (unsigned i = 0; i < macro_num_args(e); i++)
                visit(macro_arg(e, i));
            break;
        case expr_kind::App:
            visit(app_fn(e));
            visit(app_arg(e));
            break;
        case expr_kind::Lambda:
        case expr_kind::Pi:
            visit(binding_domain(e));
            visit(binding_body(e));
            break;
        case expr_kind::Let:
            visit(let_type(e));
            visit(let_value(e));
            visit(let_body(e));
            break;
        }
    };
    visit(e);
}
Exemplo n.º 21
0
// Return true iff lhs is of the form (B (x : ?m1), ?m2) or (B (x : ?m1), ?m2 x),
// where B is lambda or Pi
static bool is_valid_congr_rule_binding_lhs(expr const & lhs, name_set & found_mvars) {
    lean_assert(is_binding(lhs));
    expr const & d = binding_domain(lhs);
    expr const & b = binding_body(lhs);
    if (!is_metavar(d))
        return false;
    if (is_metavar(b) && b != d) {
        found_mvars.insert(mlocal_name(b));
        found_mvars.insert(mlocal_name(d));
        return true;
    }
    if (is_app(b) && is_metavar(app_fn(b)) && is_var(app_arg(b), 0) && app_fn(b) != d) {
        found_mvars.insert(mlocal_name(app_fn(b)));
        found_mvars.insert(mlocal_name(d));
        return true;
    }
    return false;
}
Exemplo n.º 22
0
unsigned light_lt_manager::get_weight_core(expr const & e) {
    switch (e.kind()) {
    case expr_kind::Var:  case expr_kind::Constant: case expr_kind::Sort:
    case expr_kind::Meta: case expr_kind::Local:
        return 1;
    case expr_kind::Lambda: case expr_kind::Pi:
        return safe_add(1, safe_add(get_weight(binding_domain(e)), get_weight(binding_body(e))));
    case expr_kind::Macro:
        return safe_add(1, add_weight(macro_num_args(e), macro_args(e)));
    case expr_kind::App:
        buffer<expr> args;
        expr fn = get_app_args(e, args);
        if (is_constant(fn)) {
            unsigned const * light_arg = m_lrs.find(const_name(fn));
            if (light_arg && args.size() > *light_arg) return get_weight(args[*light_arg]);
        }
        return safe_add(1, safe_add(get_weight(app_fn(e)), get_weight(app_arg(e))));
    }
    lean_unreachable(); // LCOV_EXCL_LINE
}
Exemplo n.º 23
0
    expr apply(expr const & e, unsigned offset) {
        bool shared = false;
        if (m_use_cache && is_shared(e)) {
            if (auto r = m_cache->find(e, offset))
                return *r;
            shared = true;
        }
        check_interrupted();
        check_memory("replace");

        if (optional<expr> r = m_f(e, offset)) {
            return save_result(e, offset, *r, shared);
        } else {
            switch (e.kind()) {
            case expr_kind::Constant: case expr_kind::Sort: case expr_kind::Var:
                return save_result(e, offset, e, shared);
            case expr_kind::Meta:     case expr_kind::Local: {
                expr new_t = apply(mlocal_type(e), offset);
                return save_result(e, offset, update_mlocal(e, new_t), shared);
            }
            case expr_kind::App: {
                expr new_f = apply(app_fn(e), offset);
                expr new_a = apply(app_arg(e), offset);
                return save_result(e, offset, update_app(e, new_f, new_a), shared);
            }
            case expr_kind::Pi: case expr_kind::Lambda: {
                expr new_d = apply(binding_domain(e), offset);
                expr new_b = apply(binding_body(e), offset+1);
                return save_result(e, offset, update_binding(e, new_d, new_b), shared);
            }
            case expr_kind::Macro: {
                buffer<expr> new_args;
                unsigned nargs = macro_num_args(e);
                for (unsigned i = 0; i < nargs; i++)
                    new_args.push_back(apply(macro_arg(e, i), offset));
                return save_result(e, offset, update_macro(e, new_args.size(), new_args.data()), shared);
            }}
            lean_unreachable();
        }
    }
Exemplo n.º 24
0
void initialize_apply_tactic() {
    g_apply_class_instance = new name{"apply", "class_instance"};
    register_bool_option(*g_apply_class_instance, LEAN_DEFAULT_APPLY_CLASS_INSTANCE,
                         "(apply tactic) if true apply tactic uses class-instances "
                         "resolution for instance implicit arguments");

    register_tac(get_tactic_apply_name(),
                 [](type_checker &, elaborate_fn const & fn, expr const & e, pos_info_provider const *) {
                     check_tactic_expr(app_arg(e), "invalid 'apply' tactic, invalid argument");
                     return apply_tactic(fn, get_tactic_expr_expr(app_arg(e)));
                 });

    register_tac(get_tactic_eapply_name(),
                 [](type_checker &, elaborate_fn const & fn, expr const & e, pos_info_provider const *) {
                     check_tactic_expr(app_arg(e), "invalid 'eapply' tactic, invalid argument");
                     return eapply_tactic(fn, get_tactic_expr_expr(app_arg(e)));
                 });

    register_tac(get_tactic_fapply_name(),
                 [](type_checker &, elaborate_fn const & fn, expr const & e, pos_info_provider const *) {
                     check_tactic_expr(app_arg(e), "invalid 'fapply' tactic, invalid argument");
                     return fapply_tactic(fn, get_tactic_expr_expr(app_arg(e)));
                 });
}
Exemplo n.º 25
0
Arquivo: num.cpp Projeto: avigad/lean
optional<expr> is_bit1(expr const & e) {
    if (!is_const_app(e, get_bit1_name(), 4))
        return none_expr();
    return some_expr(app_arg(e));
}
Exemplo n.º 26
0
expr update_app(expr const & e, expr const & new_fn, expr const & new_arg) {
    if (!is_eqp(app_fn(e), new_fn) || !is_eqp(app_arg(e), new_arg))
        return mk_app(new_fn, new_arg, e.get_tag());
    else
        return e;
}
Exemplo n.º 27
0
 expr visit_app(expr const & e) {
     expr new_f = visit(app_fn(e));
     expr new_v = visit(app_arg(e));
     return update_app(e, new_f, new_v);
 }
Exemplo n.º 28
0
Arquivo: num.cpp Projeto: avigad/lean
optional<expr> is_neg(expr const & e) {
    if (!is_const_app(e, get_has_neg_neg_name(), 3))
        return none_expr();
    return some_expr(app_arg(e));
}
Exemplo n.º 29
0
bool light_lt_manager::is_lt(expr const & a, expr const & b) {
    if (is_eqp(a, b)) return false;
    unsigned wa = get_weight(a);
    unsigned wb = get_weight(b);
    if (wa < wb)                         return true;
    if (wa > wb)                         return false;
    if (is_constant(get_app_fn(a))) {
        unsigned const * light_arg = m_lrs.find(const_name(get_app_fn(a)));
        if (light_arg) {
            buffer<expr> args;
            get_app_args(a, args);
            if (args.size() > *light_arg) return is_lt(args[*light_arg], b);
        }
    }
    if (is_constant(get_app_fn(b))) {
        unsigned const * light_arg = m_lrs.find(const_name(get_app_fn(b)));
        if (light_arg) {
            buffer<expr> args;
            get_app_args(b, args);
            if (args.size() > *light_arg) return !is_lt(args[*light_arg], a);
        }
    }
    if (a.kind() != b.kind())            return a.kind() < b.kind();
    if (a == b)                          return false;
    switch (a.kind()) {
    case expr_kind::Var:
        return var_idx(a) < var_idx(b);
    case expr_kind::Constant:
        if (const_name(a) != const_name(b))
            return const_name(a) < const_name(b);
        else
            return ::lean::is_lt(const_levels(a), const_levels(b), false);
    case expr_kind::App:
        if (app_fn(a) != app_fn(b))
            return is_lt(app_fn(a), app_fn(b));
        else
            return is_lt(app_arg(a), app_arg(b));
    case expr_kind::Lambda: case expr_kind::Pi:
        if (binding_domain(a) != binding_domain(b))
            return is_lt(binding_domain(a), binding_domain(b));
        else
            return is_lt(binding_body(a), binding_body(b));
    case expr_kind::Sort:
        return ::lean::is_lt(sort_level(a), sort_level(b), false);
    case expr_kind::Local: case expr_kind::Meta:
        if (mlocal_name(a) != mlocal_name(b))
            return mlocal_name(a) < mlocal_name(b);
        else
            return is_lt(mlocal_type(a), mlocal_type(b));
    case expr_kind::Macro:
        if (macro_def(a) != macro_def(b))
            return macro_def(a) < macro_def(b);
        if (macro_num_args(a) != macro_num_args(b))
            return macro_num_args(a) < macro_num_args(b);
        for (unsigned i = 0; i < macro_num_args(a); i++) {
            if (macro_arg(a, i) != macro_arg(b, i))
                return is_lt(macro_arg(a, i), macro_arg(b, i));
        }
        return false;
    }
    lean_unreachable(); // LCOV_EXCL_LINE
}
Exemplo n.º 30
0
expr replace_visitor::visit_app(expr const & e) {
    lean_assert(is_app(e));
    return update_app(e, visit(app_fn(e)), visit(app_arg(e)));
}