Esempio n. 1
0
vm_obj tactic_to_expr_core(vm_obj const & relaxed, vm_obj const & qe, vm_obj const & _s) {
    tactic_state const & s = to_tactic_state(_s);
    optional<metavar_decl> g = s.get_main_goal_decl();
    if (!g) return mk_no_goals_exception(s);
    if (!g_elaborate) {
        return mk_tactic_exception("elaborator is not available", s);
    }
    metavar_context mctx = s.mctx();
    try {
        environment env = s.env();
        expr r = (*g_elaborate)(env, s.get_options(), mctx, g->get_context(), to_expr(qe), to_bool(relaxed));
        r = mctx.instantiate_mvars(r);
        if (relaxed && has_expr_metavar(r)) {
            buffer<expr> new_goals;
            name_set found;
            for_each(r, [&](expr const & e, unsigned) {
                    if (!has_expr_metavar(e)) return false;
                    if (is_metavar_decl_ref(e) && !found.contains(mlocal_name(e))) {
                        mctx.instantiate_mvars_at_type_of(e);
                        new_goals.push_back(e);
                        found.insert(mlocal_name(e));
                    }
                    return true;
                });
            list<expr> new_gs = cons(head(s.goals()), to_list(new_goals.begin(), new_goals.end(), tail(s.goals())));
            return mk_tactic_success(to_obj(r), set_env_mctx_goals(s, env, mctx, new_gs));
        } else {
            return mk_tactic_success(to_obj(r), set_env_mctx(s, env, mctx));
        }
    } catch (exception & ex) {
        return mk_tactic_exception(ex, s);
    }
}
Esempio n. 2
0
optional<expr> has_expr_metavar_strict(expr const & e) {
    if (!has_expr_metavar(e))
        return none_expr();
    optional<expr> r;
    for_each(e, [&](expr const & e, unsigned) {
            if (r || !has_expr_metavar(e)) return false;
            if (is_meta(e)) { r = e; return false; }
            if (is_local(e)) return false; // do not visit type
            return true;
        });
    return r;
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
action_result assert_cc_action(hypothesis_idx hidx) {
    if (!get_config().m_cc)
        return action_result::failed();
    congruence_closure & cc = get_cc();
    if (has_expr_metavar(curr_state().get_hypothesis_decl(hidx).get_type()))
        return action_result::failed();
    cc.add(hidx);
    // cc.display();
    if (cc.is_inconsistent()) {
        try {
            app_builder & b  = get_app_builder();
            expr false_proof = *cc.get_inconsistency_proof();
            trace_action("contradiction by congruence closure");
            return action_result(b.mk_false_rec(curr_state().get_target(), false_proof));
        } catch (app_builder_exception &) {
            return action_result::failed();
        }
    } else {
        expr const & target = curr_state().get_target();
        name R; expr lhs, rhs;
        if (is_relation_app(target, R, lhs, rhs) && cc.is_eqv(R, lhs, rhs)) {
            expr proof = *cc.get_eqv_proof(R, lhs, rhs);
            trace_action("equivalence by congruence closure");
            return action_result(proof);
        } else if (is_prop(target) && !is_false(target) && cc.proved(target)) {
            expr proof = *cc.get_proof(target);
            trace_action("equivalent to true by congruence closure");
            return action_result(proof);
        } else {
            return action_result::new_branch();
        }
    }
}
Esempio n. 5
0
bool has_idx_metavar(expr const & e) {
    if (!has_univ_metavar(e) && !has_expr_metavar(e))
        return false;
    bool found = false;
    for_each(e, [&](expr const & e, unsigned) {
            if (found) return false;
            if (!has_univ_metavar(e) && !has_expr_metavar(e)) return false;
            if (is_idx_metavar(e))
                found = true;
            else if (is_constant(e) && std::any_of(const_levels(e).begin(), const_levels(e).end(), has_idx_metauniv))
                found = true;
            else if (is_sort(e) && has_idx_metauniv(sort_level(e)))
                found = true;
            return true;
        });
    return found;
}
Esempio n. 6
0
bool is_ceqv(tmp_type_context & tctx, expr e) {
    if (has_expr_metavar(e))
        return false;
    name_set to_find;
    // Define a procedure for removing arguments from to_find.
    auto visitor_fn = [&](expr const & e, unsigned) {
        if (is_local(e)) {
            to_find.erase(mlocal_name(e));
            return false;
        } else if (is_metavar(e)) {
            return false;
        } else {
            return true;
        }
    };
    environment const & env = tctx.env();
    bool is_std = is_standard(env);
    buffer<expr> hypotheses; // arguments that are propositions
    while (is_pi(e)) {
        if (!to_find.empty()) {
            // Support for dependent types.
            // We may find the instantiation for the previous arguments
            // by matching the type.
            for_each(binding_domain(e), visitor_fn);
        }
        expr local = tctx.mk_tmp_local(binding_domain(e));
        if (binding_info(e).is_inst_implicit()) {
            // If the argument can be instantiated by type class resolution, then
            // we don't need to find it in the lhs
        } else if (is_std && tctx.is_prop(binding_domain(e))) {
            // If the argument is a proposition, we store it in hypotheses.
            // We check whether the lhs occurs in hypotheses or not.
            hypotheses.push_back(binding_domain(e));
        } else {
            to_find.insert(mlocal_name(local));
        }
        e = instantiate(binding_body(e), local);
    }
    expr lhs, rhs;
    if (!is_simp_relation(env, e, lhs, rhs))
        return false;
    // traverse lhs, and remove found variables from to_find
    for_each(lhs, visitor_fn);
    if (!to_find.empty())
        return false;
    // basic looping ceq detection: the left-hand-side should not occur in the right-hand-side,
    // nor it should occur in any of the hypothesis
    if (occurs(lhs, rhs))
        return false;
    if (std::any_of(hypotheses.begin(), hypotheses.end(), [&](expr const & h) { return occurs(lhs, h); }))
        return false;
    return true;
}
Esempio n. 7
0
bool substitution::occurs_expr_core(name const & m, expr const & e, name_set & visited) const {
    bool found = false;
    for_each(e, [&](expr const & e, unsigned) {
            if (found || !has_expr_metavar(e)) return false;
            if (is_metavar(e)) {
                name const & n = mlocal_name(e);
                if (n == m)
                    found = true;
                auto s = get_expr(e);
                if (!s || visited.contains(n))
                    return false; // do not visit type
                visited.insert(n);
                if (s && occurs_expr_core(m, *s, visited))
                    found = true;
                return false; // do not visit type
            }
            if (is_local(e)) return false; // do not visit type
            return true;
        });
    return found;
}
Esempio n. 8
0
bool substitution::occurs_expr(name const & m, expr const & e) const {
    if (!has_expr_metavar(e))
        return false;
    name_set visited;
    return occurs_expr_core(m, e, visited);
}