feat(frontends/lean/elaborator) add trick for improving error messages when mixing tactics, elaboration and exact tactic

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2014-07-02 18:58:32 -07:00
parent c3abf81382
commit 138267b53a
3 changed files with 20 additions and 1 deletions

View file

@ -640,10 +640,25 @@ public:
} }
} }
// For each occurrence of \c exact_tac in \c pre_tac, display its unassigned metavariables.
// This is a trick to improve the quality of the error messages.
void check_exact_tacs(expr const & pre_tac, substitution const & s) {
for_each(pre_tac, [&](expr const & e, unsigned) {
expr const & f = get_app_fn(e);
if (is_constant(f) && const_name(f) == get_exact_tac_name()) {
display_unassigned_mvars(e, s);
return false;
} else {
return true;
}
});
}
optional<expr> get_pre_tactic_for(substitution & subst, expr const & mvar, name_set & visited) { optional<expr> get_pre_tactic_for(substitution & subst, expr const & mvar, name_set & visited) {
if (auto it = m_tactic_hints.find(mlocal_name(mvar))) { if (auto it = m_tactic_hints.find(mlocal_name(mvar))) {
expr pre_tac = subst.instantiate(*it); expr pre_tac = subst.instantiate(*it);
pre_tac = solve_unassigned_mvars(subst, pre_tac, visited); pre_tac = solve_unassigned_mvars(subst, pre_tac, visited);
check_exact_tacs(pre_tac, subst);
return some_expr(pre_tac); return some_expr(pre_tac);
} else { } else {
// TODO(Leo): m_env tactic hints // TODO(Leo): m_env tactic hints

View file

@ -81,6 +81,8 @@ register_unary_tac::register_unary_tac(name const & n, std::function<tactic(tact
} }
static name g_tac("tactic"); static name g_tac("tactic");
static name g_exact_tac_name(g_tac, "exact");
name const & get_exact_tac_name() { return g_exact_tac_name; }
static register_simple_tac reg_id(name(g_tac, "id"), []() { return id_tactic(); }); static register_simple_tac reg_id(name(g_tac, "id"), []() { return id_tactic(); });
static register_simple_tac reg_now(name(g_tac, "now"), []() { return now_tactic(); }); static register_simple_tac reg_now(name(g_tac, "now"), []() { return now_tactic(); });
static register_simple_tac reg_assumption(name(g_tac, "assumption"), []() { return assumption_tactic(); }); static register_simple_tac reg_assumption(name(g_tac, "assumption"), []() { return assumption_tactic(); });
@ -110,7 +112,7 @@ static register_tac reg_trace(name(g_tac, "trace"), [](type_checker & tc, expr c
static register_tac reg_apply(name(g_tac, "apply"), [](type_checker &, expr const & e, pos_info_provider const *) { static register_tac reg_apply(name(g_tac, "apply"), [](type_checker &, expr const & e, pos_info_provider const *) {
return apply_tactic(app_arg(e)); return apply_tactic(app_arg(e));
}); });
static register_tac reg_exact(name(g_tac, "exact"), [](type_checker &, expr const & e, pos_info_provider const *) { static register_tac reg_exact(g_exact_tac_name, [](type_checker &, expr const & e, pos_info_provider const *) {
return exact_tactic(app_arg(e)); return exact_tactic(app_arg(e));
}); });
static register_tac reg_unfold(name(g_tac, "unfold"), [](type_checker &, expr const & e, pos_info_provider const *) { static register_tac reg_unfold(name(g_tac, "unfold"), [](type_checker &, expr const & e, pos_info_provider const *) {

View file

@ -28,6 +28,8 @@ struct register_unary_tac {
register_unary_tac(name const & n, std::function<tactic(tactic const &)> f); register_unary_tac(name const & n, std::function<tactic(tactic const &)> f);
}; };
name const & get_exact_tac_name();
tactic expr_to_tactic(environment const & env, expr const & e, pos_info_provider const *p); tactic expr_to_tactic(environment const & env, expr const & e, pos_info_provider const *p);
expr mk_by(expr const & e); expr mk_by(expr const & e);
bool is_by(expr const & e); bool is_by(expr const & e);