fix(frontends/lean/elaborator): fixes #687
This commit is contained in:
parent
ecfc01b2d0
commit
95720b1670
3 changed files with 54 additions and 12 deletions
|
@ -81,13 +81,15 @@ struct elaborator::choice_expr_elaborator : public choice_iterator {
|
||||||
elaborator & m_elab;
|
elaborator & m_elab;
|
||||||
local_context m_context;
|
local_context m_context;
|
||||||
local_context m_full_context;
|
local_context m_full_context;
|
||||||
|
bool m_in_equation_lhs;
|
||||||
expr m_meta;
|
expr m_meta;
|
||||||
expr m_type;
|
expr m_type;
|
||||||
expr m_choice;
|
expr m_choice;
|
||||||
unsigned m_idx;
|
unsigned m_idx;
|
||||||
choice_expr_elaborator(elaborator & elab, local_context const & ctx, local_context const & full_ctx,
|
|
||||||
|
choice_expr_elaborator(elaborator & elab, local_context const & ctx, local_context const & full_ctx, bool in_equation_lhs,
|
||||||
expr const & meta, expr const & type, expr const & c):
|
expr const & meta, expr const & type, expr const & c):
|
||||||
m_elab(elab), m_context(ctx), m_full_context(full_ctx), m_meta(meta),
|
m_elab(elab), m_context(ctx), m_full_context(full_ctx), m_in_equation_lhs(in_equation_lhs), m_meta(meta),
|
||||||
m_type(type), m_choice(c), m_idx(get_num_choices(m_choice)) {
|
m_type(type), m_choice(c), m_idx(get_num_choices(m_choice)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,6 +102,7 @@ struct elaborator::choice_expr_elaborator : public choice_iterator {
|
||||||
try {
|
try {
|
||||||
flet<local_context> set1(m_elab.m_context, m_context);
|
flet<local_context> set1(m_elab.m_context, m_context);
|
||||||
flet<local_context> set2(m_elab.m_full_context, m_full_context);
|
flet<local_context> set2(m_elab.m_full_context, m_full_context);
|
||||||
|
flet<bool> set3(m_elab.m_in_equation_lhs, m_in_equation_lhs);
|
||||||
pair<expr, constraint_seq> rcs = m_elab.visit(c);
|
pair<expr, constraint_seq> rcs = m_elab.visit(c);
|
||||||
expr r = rcs.first;
|
expr r = rcs.first;
|
||||||
constraint_seq cs = rcs.second;
|
constraint_seq cs = rcs.second;
|
||||||
|
@ -314,9 +317,10 @@ expr elaborator::visit_choice(expr const & e, optional<expr> const & t, constrai
|
||||||
register_meta(m);
|
register_meta(m);
|
||||||
local_context ctx = m_context;
|
local_context ctx = m_context;
|
||||||
local_context full_ctx = m_full_context;
|
local_context full_ctx = m_full_context;
|
||||||
|
bool in_equation_lhs = m_in_equation_lhs;
|
||||||
auto fn = [=](expr const & meta, expr const & type, substitution const & /* s */,
|
auto fn = [=](expr const & meta, expr const & type, substitution const & /* s */,
|
||||||
name_generator && /* ngen */) {
|
name_generator && /* ngen */) {
|
||||||
return choose(std::make_shared<choice_expr_elaborator>(*this, ctx, full_ctx, meta, type, e));
|
return choose(std::make_shared<choice_expr_elaborator>(*this, ctx, full_ctx, in_equation_lhs, meta, type, e));
|
||||||
};
|
};
|
||||||
auto pp_fn = [=](formatter const & fmt, pos_info_provider const * pos_prov, substitution const &, bool is_main, bool) {
|
auto pp_fn = [=](formatter const & fmt, pos_info_provider const * pos_prov, substitution const &, bool is_main, bool) {
|
||||||
format r = pp_previous_error_header(fmt, pos_prov, some_expr(e), is_main);
|
format r = pp_previous_error_header(fmt, pos_prov, some_expr(e), is_main);
|
||||||
|
@ -553,12 +557,13 @@ pair<expr, constraint_seq> elaborator::mk_delayed_coercion(
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Given a term <tt>a : a_type</tt>, ensure it has type \c expected_type. Apply coercions if needed */
|
/** \brief Given a term <tt>a : a_type</tt>, ensure it has type \c expected_type. Apply coercions if needed */
|
||||||
pair<expr, constraint_seq> elaborator::ensure_has_type(
|
pair<expr, constraint_seq> elaborator::ensure_has_type_core(
|
||||||
expr const & a, expr const & a_type, expr const & expected_type, justification const & j) {
|
expr const & a, expr const & a_type, expr const & expected_type, bool use_expensive_coercions, justification const & j) {
|
||||||
bool lifted_coe = false;
|
bool lifted_coe = false;
|
||||||
if (has_coercions_from(a_type, lifted_coe) && ((!lifted_coe && is_meta(expected_type)) || (lifted_coe && is_pi_meta(expected_type)))) {
|
if (use_expensive_coercions &&
|
||||||
|
has_coercions_from(a_type, lifted_coe) && ((!lifted_coe && is_meta(expected_type)) || (lifted_coe && is_pi_meta(expected_type)))) {
|
||||||
return mk_delayed_coercion(a, a_type, expected_type, j);
|
return mk_delayed_coercion(a, a_type, expected_type, j);
|
||||||
} else if (!m_in_equation_lhs && is_meta(a_type) && has_coercions_to(expected_type)) {
|
} else if (use_expensive_coercions && !m_in_equation_lhs && is_meta(a_type) && has_coercions_to(expected_type)) {
|
||||||
return mk_delayed_coercion(a, a_type, expected_type, j);
|
return mk_delayed_coercion(a, a_type, expected_type, j);
|
||||||
} else {
|
} else {
|
||||||
pair<bool, constraint_seq> dcs;
|
pair<bool, constraint_seq> dcs;
|
||||||
|
@ -668,7 +673,10 @@ expr elaborator::visit_app(expr const & e, constraint_seq & cs) {
|
||||||
expr a_type = infer_type(a, a_cs);
|
expr a_type = infer_type(a, a_cs);
|
||||||
expr r = mk_app(f, a, e.get_tag());
|
expr r = mk_app(f, a, e.get_tag());
|
||||||
justification j = mk_app_justification(r, f_type, a, a_type);
|
justification j = mk_app_justification(r, f_type, a, a_type);
|
||||||
auto new_a_cs = ensure_has_type(a, a_type, d_type, j);
|
// If the application is an equations expression, then we are compiling a match-with, and expensive
|
||||||
|
// coercions should not be considered.
|
||||||
|
bool use_expensive_coercions = !is_equations(app_fn(e));
|
||||||
|
auto new_a_cs = ensure_has_type_core(a, a_type, d_type, use_expensive_coercions, j);
|
||||||
expr new_a = new_a_cs.first;
|
expr new_a = new_a_cs.first;
|
||||||
cs += f_cs + new_a_cs.second + a_cs;
|
cs += f_cs + new_a_cs.second + a_cs;
|
||||||
return update_app(r, app_fn(r), new_a);
|
return update_app(r, app_fn(r), new_a);
|
||||||
|
|
|
@ -124,9 +124,12 @@ class elaborator : public coercion_info_manager {
|
||||||
expr apply_coercion(expr const & a, expr a_type, expr d_type);
|
expr apply_coercion(expr const & a, expr a_type, expr d_type);
|
||||||
pair<expr, constraint_seq> mk_delayed_coercion(expr const & a, expr const & a_type, expr const & expected_type,
|
pair<expr, constraint_seq> mk_delayed_coercion(expr const & a, expr const & a_type, expr const & expected_type,
|
||||||
justification const & j);
|
justification const & j);
|
||||||
|
pair<expr, constraint_seq> ensure_has_type_core(expr const & a, expr const & a_type, expr const & expected_type,
|
||||||
|
bool use_expensive_coercions, justification const & j);
|
||||||
pair<expr, constraint_seq> ensure_has_type(expr const & a, expr const & a_type, expr const & expected_type,
|
pair<expr, constraint_seq> ensure_has_type(expr const & a, expr const & a_type, expr const & expected_type,
|
||||||
justification const & j);
|
justification const & j) {
|
||||||
|
return ensure_has_type_core(a, a_type, expected_type, true, j);
|
||||||
|
}
|
||||||
bool is_choice_app(expr const & e);
|
bool is_choice_app(expr const & e);
|
||||||
expr visit_choice_app(expr const & e, constraint_seq & cs);
|
expr visit_choice_app(expr const & e, constraint_seq & cs);
|
||||||
expr visit_app(expr const & e, constraint_seq & cs);
|
expr visit_app(expr const & e, constraint_seq & cs);
|
||||||
|
|
31
tests/lean/run/687.lean
Normal file
31
tests/lean/run/687.lean
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import data.fin
|
||||||
|
|
||||||
|
section rot
|
||||||
|
open nat fin eq.ops algebra
|
||||||
|
open eq.ops
|
||||||
|
|
||||||
|
definition rotr₀ {n : nat} : fin n → fin n :=
|
||||||
|
match n with
|
||||||
|
| 0 := take i, elim0 i
|
||||||
|
| (succ k) := madd (-maxi)
|
||||||
|
end
|
||||||
|
|
||||||
|
definition rotr₁ {n : nat} : fin n → fin n :=
|
||||||
|
match n with
|
||||||
|
| zero := take i, elim0 i
|
||||||
|
| (succ k) := madd (-maxi)
|
||||||
|
end
|
||||||
|
|
||||||
|
definition rotr₂ : ∀ {n : nat}, fin n → fin n
|
||||||
|
| 0 i := elim0 i
|
||||||
|
| (succ n) i := madd (has_neg.neg maxi) i
|
||||||
|
|
||||||
|
definition rotr₃ : ∀ {n : nat}, fin n → fin n
|
||||||
|
| 0 := take i, elim0 i
|
||||||
|
| (succ n) := madd (-maxi)
|
||||||
|
|
||||||
|
definition rotr₄ : ∀ {n : nat}, fin n → fin n
|
||||||
|
| 0 i := elim0 i
|
||||||
|
| (succ n) i := madd (-maxi) i
|
||||||
|
|
||||||
|
end rot
|
Loading…
Reference in a new issue