コード例 #1
0
ファイル: fun_info.cpp プロジェクト: sakas--/lean
/* Store parameter info for fn in \c pinfos and return the dependencies of the resulting type
   (if compute_resulting_deps == true). */
static list<unsigned> get_core(type_context & ctx,
                               expr const & fn, buffer<param_info> & pinfos,
                               unsigned max_args, bool compute_resulting_deps) {
    expr type = ctx.relaxed_try_to_pi(ctx.infer(fn));
    type_context::tmp_locals locals(ctx);
    unsigned i = 0;
    while (is_pi(type)) {
        if (i == max_args)
            break;
        expr local      = locals.push_local_from_binding(type);
        expr local_type = ctx.infer(local);
        expr new_type   = ctx.relaxed_try_to_pi(instantiate(binding_body(type), local));
        bool is_prop    = ctx.is_prop(local_type);
        bool is_dep     = !closed(binding_body(type));
        pinfos.emplace_back(binding_info(type).is_implicit(),
                            binding_info(type).is_inst_implicit(),
                            is_prop, is_dep, collect_deps(local_type, locals.as_buffer()));
        type = new_type;
        i++;
    }
    if (compute_resulting_deps)
        return collect_deps(type, locals.as_buffer());
    else
        return list<unsigned>();
}
コード例 #2
0
ファイル: dsimplify.cpp プロジェクト: avigad/lean
optional<expr> unfold_step(type_context & ctx, expr const & e, name_set const & to_unfold, bool unfold_reducible) {
    if (!unfold_reducible && to_unfold.empty())
        return none_expr();
    if (!is_app(e) && !is_constant(e))
        return none_expr();
    expr const & fn = get_app_fn(e);
    if (!is_constant(fn))
        return none_expr();
    name const & fn_name = const_name(fn);

    bool in_to_unfold = to_unfold.contains(const_name(fn));

    if (!in_to_unfold && !unfold_reducible)
        return none_expr();

    if (is_projection(ctx.env(), const_name(fn))) {
        if (in_to_unfold) {
            type_context::transparency_scope scope(ctx, transparency_mode::Instances);
            return ctx.reduce_projection(e);
        } else {
            return none_expr();
        }
    } else if (in_to_unfold) {
        return unfold_term(ctx.env(), e);
    } else if (unfold_reducible && is_reducible(ctx.env(), fn_name)) {
        type_context::transparency_scope scope(ctx, transparency_mode::Reducible);
        return unfold_term(ctx.env(), e);
    } else {
        return none_expr();
    }
}
コード例 #3
0
ファイル: backward_lemmas.cpp プロジェクト: avigad/lean
backward_lemma_index::backward_lemma_index(type_context & ctx):
    m_index(get_intro_attribute().get_instances_by_prio(ctx.env())) {
    buffer<name> lemmas;
    get_intro_attribute().get_instances(ctx.env(), lemmas);
    unsigned i = lemmas.size();
    while (i > 0) {
        --i;
        optional<head_index> target = get_backward_target(ctx, lemmas[i]);
        if (!target || target->kind() != expr_kind::Constant) {
            lean_trace(name({"tactic", "back_chaining"}),
                       tout() << "discarding [intro] lemma '" << lemmas[i] << "', failed to find target type\n";);
        } else {
コード例 #4
0
ファイル: gexpr.cpp プロジェクト: GallagherCommaJack/lean
expr gexpr::to_expr(type_context & ctx) const {
    if (m_univ_poly) {
        declaration const & fdecl = ctx.env().get(const_name(m_expr));
        buffer<level> ls_buffer;
        unsigned num_univ_ps = fdecl.get_num_univ_params();
        for (unsigned i = 0; i < num_univ_ps; i++)
            ls_buffer.push_back(ctx.mk_uvar());
        levels ls = to_list(ls_buffer.begin(), ls_buffer.end());
        return mk_constant(const_name(m_expr), ls);
    } else {
        return m_expr;
    }
}
コード例 #5
0
ファイル: fun_info.cpp プロジェクト: sakas--/lean
static void trace_if_unsupported(type_context & ctx, expr const & fn,
                                 buffer<expr> const & args, unsigned prefix_sz, ss_param_infos const & result) {
    lean_assert(args.size() >= length(result));
    if (!is_fun_info_trace_enabled())
        return;
    fun_info info = get_fun_info(ctx, fn, args.size());
    buffer<param_info> pinfos;
    to_buffer(info.get_params_info(), pinfos);
    buffer<ss_param_info> ssinfos;
    to_buffer(get_subsingleton_info(ctx, fn, args.size()), ssinfos);
    lean_assert(pinfos.size() == ssinfos.size());
    /* Check if all remaining arguments are nondependent or
       dependent (but all forward dependencies are subsingletons) */
    unsigned i = prefix_sz;
    for (; i < pinfos.size(); i++) {
        param_info const & pinfo = pinfos[i];
        if (!pinfo.has_fwd_deps())
            continue; /* nondependent argument */
        if (has_nonsubsingleton_fwd_dep(i, pinfos, ssinfos))
            break; /* failed i-th argument has a forward dependent that is not a prop nor a subsingleton */
    }
    if (i == pinfos.size())
        return; // It is *cheap* case

    /* Expensive case */
    /* We generate a trace message IF it would be possible to compute more precise information.
       That is, there is an argument that is a proposition and/or subsingleton, but
       the corresponding pinfo is not a marked a prop/subsingleton.
    */
    i = 0;
    for (ss_param_info const & ssinfo : result) {
        if (ssinfo.is_subsingleton())
            continue;
        expr arg_type = ctx.infer(args[i]);
        if (ctx.mk_subsingleton_instance(arg_type)) {
            lean_trace_fun_info(
                tout() << "approximating function information for '" << fn
                << "', this may affect the effectiveness of the simplifier and congruence closure modules, "
                << "more precise information can be efficiently computed if all parameters are moved to the "
                << "beginning of the function\n";);
            return;
        }
コード例 #6
0
ファイル: fun_info.cpp プロジェクト: sakas--/lean
/* Store subsingleton parameter info for fn in \c ssinfos */
static void get_ss_core(type_context & ctx, expr const & fn, buffer<ss_param_info> & ssinfos,
                        unsigned max_args) {
    expr type = ctx.relaxed_try_to_pi(ctx.infer(fn));
    type_context::tmp_locals locals(ctx);
    unsigned i = 0;
    while (is_pi(type)) {
        if (i == max_args)
            break;
        expr local      = locals.push_local_from_binding(type);
        expr local_type = ctx.infer(local);
        expr new_type   = ctx.relaxed_try_to_pi(instantiate(binding_body(type), local));
        bool spec       = false;
        bool is_prop    = ctx.is_prop(local_type);
        bool is_sub     = is_prop;
        if (!is_sub) {
            // TODO(Leo): check if the following line is a performance bottleneck.
            is_sub = static_cast<bool>(ctx.mk_subsingleton_instance(local_type));
        }
        ssinfos.emplace_back(spec, is_sub);
        type = new_type;
        i++;
    }
}
コード例 #7
0
ファイル: util.cpp プロジェクト: sakas--/lean
bool is_comp_irrelevant(type_context & ctx, expr const & e) {
    expr type = ctx.whnf(ctx.infer(e));
    return is_sort(type) || ctx.is_prop(type);
}
コード例 #8
0
ファイル: backward_lemmas.cpp プロジェクト: avigad/lean
static optional<head_index> get_backward_target(type_context & ctx, name const & c) {
    declaration const & d = ctx.env().get(c);
    list<level> us = param_names_to_levels(d.get_univ_params());
    expr type      = ctx.try_to_pi(instantiate_type_univ_params(d, us));
    return get_backward_target(ctx, type);
}
コード例 #9
0
ファイル: cases_tactic.cpp プロジェクト: avigad/lean
 expr whnf_inductive(type_context & ctx, expr const & e) {
     if (m_unfold_ginductive)
         return ctx.relaxed_whnf(e);
     else
         return ::lean::whnf_ginductive(ctx, e);
 }