feat(frontends/lean/elaborator): use tactic_hints for unsolved placeholders

This commit is contained in:
Leonardo de Moura 2014-09-25 17:54:10 -07:00
parent bb1c6d44ac
commit 318fec43a4

View file

@ -887,8 +887,11 @@ public:
/** \brief Try to instantiate meta-variable \c mvar (modulo its state ps) using the given tactic. /** \brief Try to instantiate meta-variable \c mvar (modulo its state ps) using the given tactic.
If it succeeds, then update subst with the solution. If it succeeds, then update subst with the solution.
Return true iff the metavariable \c mvar has been assigned. Return true iff the metavariable \c mvar has been assigned.
If \c show_failure == true, then display reason for failure.
*/ */
bool try_using(substitution & subst, expr const & mvar, proof_state const & ps, tactic const & tac) { bool try_using(substitution & subst, expr const & mvar, proof_state const & ps, tactic const & tac,
bool show_failure) {
lean_assert(length(ps.get_goals()) == 1); lean_assert(length(ps.get_goals()) == 1);
// make sure ps is a really a proof state for mvar. // make sure ps is a really a proof state for mvar.
lean_assert(mlocal_name(get_app_fn(head(ps.get_goals()).get_meta())) == mlocal_name(mvar)); lean_assert(mlocal_name(get_app_fn(head(ps.get_goals()).get_meta())) == mlocal_name(mvar));
@ -897,11 +900,13 @@ public:
auto r = seq.pull(); auto r = seq.pull();
if (!r) { if (!r) {
// tactic failed to produce any result // tactic failed to produce any result
display_unsolved_proof_state(mvar, ps, "tactic failed"); if (show_failure)
display_unsolved_proof_state(mvar, ps, "tactic failed");
return false; return false;
} else if (!empty(r->first.get_goals())) { } else if (!empty(r->first.get_goals())) {
// tactic contains unsolved subgoals // tactic contains unsolved subgoals
display_unsolved_proof_state(mvar, r->first, "unsolved subgoals"); if (show_failure)
display_unsolved_proof_state(mvar, r->first, "unsolved subgoals");
return false; return false;
} else { } else {
subst = r->first.get_subst(); subst = r->first.get_subst();
@ -910,9 +915,11 @@ public:
return true; return true;
} }
} catch (tactic_exception & ex) { } catch (tactic_exception & ex) {
auto out = regular(env(), ios()); if (show_failure) {
display_error_pos(out, pip(), ex.get_expr()); auto out = regular(env(), ios());
out << " tactic failed: " << ex.what() << "\n"; display_error_pos(out, pip(), ex.get_expr());
out << " tactic failed: " << ex.what() << "\n";
}
return false; return false;
} }
} }
@ -921,17 +928,26 @@ public:
if (visited.contains(mlocal_name(mvar))) if (visited.contains(mlocal_name(mvar)))
return; return;
visited.insert(mlocal_name(mvar)); visited.insert(mlocal_name(mvar));
auto meta = mvar_to_meta(mvar);
if (!meta)
return;
meta = instantiate_meta(*meta, subst);
// TODO(Leo): we are discarding constraints here
expr type = m_tc[m_relax_main_opaque]->infer(*meta).first;
// first solve unassigned metavariables in type
type = solve_unassigned_mvars(subst, type, visited);
proof_state ps(goals(goal(*meta, type)), subst, m_ngen.mk_child());
if (auto local_hint = get_local_tactic_hint(subst, mvar, visited)) { if (auto local_hint = get_local_tactic_hint(subst, mvar, visited)) {
auto meta = mvar_to_meta(mvar); // using user provided tactic
if (!meta) bool show_failure = true;
return; try_using(subst, mvar, ps, *local_hint, show_failure);
meta = instantiate_meta(*meta, subst); } else {
// TODO(Leo): we are discarding constraints here // using tactic_hints
expr type = m_tc[m_relax_main_opaque]->infer(*meta).first; for (tactic_hint_entry const & tentry : get_tactic_hints(env())) {
// first solve unassigned metavariables in type bool show_failure = false;
type = solve_unassigned_mvars(subst, type, visited); if (try_using(subst, mvar, ps, tentry.get_tactic(), show_failure))
proof_state ps(goals(goal(*meta, type)), subst, m_ngen.mk_child()); return;
try_using(subst, mvar, ps, *local_hint); }
} }
} }