bool projection_converter::postpone_is_def_eq(expr const & t, expr const & s) {
    if (has_expr_metavar(t) || has_expr_metavar(s)) {
        auto it1 = is_projection(t);
        auto it2 = is_projection(s);
        if (it1 && it2) {
            return true;
        }
        if (it1 && is_stuck(t, *m_tc))
            return true;
        if (it2 && is_stuck(s, *m_tc))
            return true;
    }
    return default_converter::postpone_is_def_eq(t, s);
}
Exemple #2
0
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();
    }
}
optional<pair<expr, constraint_seq>> projection_converter::reduce_projection(expr const & t) {
    projection_info const * info = is_projection(t);
    if (!info)
        return optional<pair<expr, constraint_seq>>();
    buffer<expr> args;
    get_app_args(t, args);
    if (args.size() <= info->m_nparams) {
        return optional<pair<expr, constraint_seq>>();
    }
    unsigned mkidx  = info->m_nparams;
    expr const & mk = args[mkidx];
    pair<expr, constraint_seq> new_mk_cs = whnf(mk);
    expr new_mk     = new_mk_cs.first;
    expr const & new_mk_fn = get_app_fn(new_mk);
    if (!is_constant(new_mk_fn) || const_name(new_mk_fn) != info->m_constructor) {
        return optional<pair<expr, constraint_seq>>();
    }
    buffer<expr> mk_args;
    get_app_args(new_mk, mk_args);
    unsigned i = info->m_nparams + info->m_i;
    if (i >= mk_args.size()) {
        return optional<pair<expr, constraint_seq>>();
    }
    expr r = mk_args[i];
    r = mk_app(r, args.size() - mkidx - 1, args.data() + mkidx + 1);
    return optional<pair<expr, constraint_seq>>(r, new_mk_cs.second);
}
optional<expr> projection_converter::is_stuck(expr const & e, type_checker & c) {
    projection_info const * info = is_projection(e);
    if (!info)
        return default_converter::is_stuck(e, c);
    buffer<expr> args;
    get_app_args(e, args);
    if (args.size() <= info->m_nparams)
        return none_expr();
    expr mk = whnf(args[info->m_nparams], c).first;
    return c.is_stuck(mk);
}
 virtual expr visit_app(expr const & e) override {
     buffer<expr> args;
     expr const & fn = get_app_args(e, args);
     if (is_constant(fn)) {
         name const & n = const_name(fn);
         if (is_cases_on_recursor(env(), n)) {
             return visit_cases_on(n, args);
         } else if (inductive::is_intro_rule(env(), n)) {
             return visit_constructor(n, args);
         } else if (is_projection(env(), n)) {
             return visit_projection(n, args);
         }
     }
     return compiler_step_visitor::visit_app(e);
 }