diff --git a/src/library/fun_info.cpp b/src/library/fun_info.cpp index b878dddf0e..fd4a9c0dd2 100644 --- a/src/library/fun_info.cpp +++ b/src/library/fun_info.cpp @@ -198,7 +198,12 @@ static bool has_nonsubsingleton_fwd_dep(unsigned i, buffer const & p static void trace_if_unsupported(type_context & ctx, expr const & fn, buffer const & args, unsigned prefix_sz, ss_param_infos const & result) { - lean_assert(args.size() == length(result)); + // TODO(leo): the following assertion does not hold in cases such as: + // (simple_ite : Prop -> Pi (A : Type*), A -> A) (f g : nat -> nat) + // |- simple_ite true (nat -> nat) f g n + // `args` will have size 5, but `result` will only have length 4. + // The assertion does not seem to be necessary, but you may want to confirm this. + // lean_assert(args.size() == length(result)); if (!is_fun_info_trace_enabled()) return; fun_info info = get_fun_info(ctx, fn, args.size()); diff --git a/src/library/tactic/simplify.cpp b/src/library/tactic/simplify.cpp index 6370f595f9..911f31a74d 100644 --- a/src/library/tactic/simplify.cpp +++ b/src/library/tactic/simplify.cpp @@ -327,7 +327,8 @@ optional simplify_core_fn::try_auto_eq_congr(expr const & e) { buffer args; expr f = get_app_args(e, args); auto congr_lemma = mk_specialized_congr_simp(m_ctx, e); - if (!congr_lemma) return optional(); + if (!congr_lemma || length(congr_lemma->get_arg_kinds()) < args.size()) + return optional(); buffer r_args; buffer new_args; diff --git a/tests/lean/run/auto_eq_congr_extra_args.lean b/tests/lean/run/auto_eq_congr_extra_args.lean new file mode 100644 index 0000000000..ccfd031c29 --- /dev/null +++ b/tests/lean/run/auto_eq_congr_extra_args.lean @@ -0,0 +1,23 @@ +open tactic + +constant my_ite (c : Prop) {A : Type*} (t : A) : A +@[simp] lemma my_ite_true {A : Type*} (t : A) : @my_ite true A t = t := sorry + +def my_true_def : Prop := true +@[simp] lemma m_true_def_true : my_true_def = true := rfl + +constant my_true : Prop +@[simp] lemma m_true_true : my_true = true := sorry + +example (n : ℕ) (f : ℕ → ℕ) : my_ite true f n = f n := by simp +example (n : ℕ) (f g : ℕ → ℕ) : my_ite my_true f n = f n := by simp +example (n : ℕ) (f g : ℕ → ℕ) : my_ite my_true_def f n = f n := by simp +example (A : Type) (a : A) (f : Π (A : Type), A → A) : my_ite true f A a = f A a := by simp + +@[congr] lemma my_ite_congr {A : Type*} (c₁ c₂ : Prop) (t₁ t₂ : A) : + (c₁ ↔ c₂) → (t₁ = t₂) → my_ite c₁ t₁ = my_ite c₂ t₂ := sorry + +example (n : ℕ) (f : ℕ → ℕ) : my_ite true f n = f n := by simp +example (n : ℕ) (f g : ℕ → ℕ) : my_ite my_true f n = f n := by simp +example (n : ℕ) (f g : ℕ → ℕ) : my_ite my_true_def f n = f n := by simp +example (A : Type) (a : A) (f : Π (A : Type), A → A) : my_ite my_true f A a = f A a := by simp