Skip to content

Commit ce2899f

Browse files
committed
feat: a replacement for Nat.leRecOn' that works with induction (#14431)
Before this PR, we had: * `theorem Nat.le.rec`: induct on `a ≤ b`, but using an annoying `a.le b` spelling * `theorem Nat.le_induction`: induct on `a ≤ b` * `def Nat.leRecOn'`, which is `Nat.le.rec` that works in `Sort*` but does not work with the `induction` keyword. There are no lemmas about this definition. * `def Nat.leRecOn`, a weaker version of `Nat.leRecOn'` that also doesn't work with `induction`. There are lots of lemmas about this definition This PR introduces `Nat.leRec`, which is a `Sort*`-valued version of `Nat.le.rec`, with a signature that coincides in the `Prop` case. Where appropriate, the lemmas about `Nat.leRecOn` are recovered as special cases of lemmas about this new definition. `Nat.leRecOn'` is then deprecated, as it is strictly less useful than `Nat.leRec`. This also changes the signature of `Nat.decreasingInduction` to be usable with the `induction` tactic, with no deprecated alias since there are very few uses. `Nat.decreasingInduction'` is left alone, as it is unclear to me how to state it in a way understood by `induction`.
1 parent 9d09e65 commit ce2899f

File tree

5 files changed

+145
-83
lines changed

5 files changed

+145
-83
lines changed

Mathlib/Data/Nat/Choose/Basic.lean

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -304,12 +304,10 @@ theorem choose_le_succ_of_lt_half_left {r n : ℕ} (h : r < n / 2) :
304304

305305
/-- Show that for small values of the right argument, the middle value is largest. -/
306306
private theorem choose_le_middle_of_le_half_left {n r : ℕ} (hr : r ≤ n / 2) :
307-
choose n r ≤ choose n (n / 2) :=
308-
decreasingInduction
309-
(fun _ k a =>
310-
(eq_or_lt_of_le a).elim (fun t => t.symm ▸ le_rfl) fun h =>
311-
(choose_le_succ_of_lt_half_left h).trans (k h))
312-
hr (fun _ => le_rfl) hr
307+
choose n r ≤ choose n (n / 2) := by
308+
induction hr using decreasingInduction with
309+
| self => rfl
310+
| of_succ k hk ih => exact (choose_le_succ_of_lt_half_left hk).trans ih
313311

314312
/-- `choose n r` is maximised when `r` is `n/2`. -/
315313
theorem choose_le_middle (r n : ℕ) : choose n r ≤ choose n (n / 2) := by

Mathlib/Data/Nat/Defs.lean

Lines changed: 131 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -854,52 +854,112 @@ lemma rec_add_one {C : ℕ → Sort*} (h0 : C 0) (h : ∀ n, C n → C (n + 1))
854854
Nat.rec (motive := C) h0 h 1 = h 0 h0 := rfl
855855

856856
/-- Recursion starting at a non-zero number: given a map `C k → C (k+1)` for each `k ≥ n`,
857-
there is a map from `C n` to each `C m`, `n ≤ m`. -/
857+
there is a map from `C n` to each `C m`, `n ≤ m`.
858+
859+
This is a version of `Nat.le.rec` that works for `Sort u`.
860+
Similarly to `Nat.le.rec`, it can be used as
861+
```
862+
induction hle using Nat.leRec with
863+
| refl => sorry
864+
| le_succ_of_le hle ih => sorry
865+
```
866+
-/
858867
@[elab_as_elim]
859-
def leRecOn' {C : ℕ → Sort*} : ∀ {m}, n ≤ m → (∀ ⦃k⦄, n ≤ k → C k → C (k + 1)) → C n → C m
860-
| 0, H, _, x => Eq.recOn (Nat.eq_zero_of_le_zero H) x
861-
| m + 1, H, next, x => (le_succ_iff.1 H).by_cases (fun h : n ≤ m ↦ next h <| leRecOn' h next x)
862-
fun h : n = m + 1 ↦ Eq.recOn h x
868+
def leRec {n} {motive : (m : ℕ) → n ≤ m → Sort*}
869+
(refl : motive n le_rfl)
870+
(le_succ_of_le : ∀ ⦃k⦄ (h : n ≤ k), motive k h → motive (k + 1) (le_succ_of_le h)) :
871+
∀ {m} (h : n ≤ m), motive m h
872+
| 0, H => Nat.eq_zero_of_le_zero H ▸ refl
873+
| m + 1, H =>
874+
(le_succ_iff.1 H).by_cases
875+
(fun h : n ≤ m ↦ le_succ_of_le h <| leRec refl le_succ_of_le h)
876+
(fun h : n = m + 1 ↦ h ▸ refl)
877+
878+
-- This verifies the signatures of the recursor matches the builtin one, as promised in the
879+
-- above.
880+
theorem leRec_eq_leRec : @Nat.leRec.{0} = @Nat.le.rec := rfl
881+
882+
@[simp]
883+
lemma leRec_self {n} {motive : (m : ℕ) → n ≤ m → Sort*}
884+
(refl : motive n le_rfl)
885+
(le_succ_of_le : ∀ ⦃k⦄ (h : n ≤ k), motive k h → motive (k + 1) (le_succ_of_le h)) :
886+
(leRec (motive := motive) refl le_succ_of_le le_rfl : motive n le_rfl) = refl := by
887+
cases n <;> simp [leRec, Or.by_cases, dif_neg]
888+
889+
@[simp]
890+
lemma leRec_succ {n} {motive : (m : ℕ) → n ≤ m → Sort*}
891+
(refl : motive n le_rfl)
892+
(le_succ_of_le : ∀ ⦃k⦄ (h : n ≤ k), motive k h → motive (k + 1) (le_succ_of_le h))
893+
(h1 : n ≤ m) {h2 : n ≤ m + 1} :
894+
(leRec (motive := motive) refl le_succ_of_le h2) =
895+
le_succ_of_le h1 (leRec (motive := motive) refl le_succ_of_le h1) := by
896+
conv =>
897+
lhs
898+
rw [leRec, Or.by_cases, dif_pos h1]
899+
900+
lemma leRec_succ' {n} {motive : (m : ℕ) → n ≤ m → Sort*} (refl le_succ_of_le) :
901+
(leRec (motive := motive) refl le_succ_of_le (le_succ _)) = le_succ_of_le _ refl := by
902+
rw [leRec_succ, leRec_self]
903+
904+
lemma leRec_trans {n m k} {motive : (m : ℕ) → n ≤ m → Sort*} (refl le_succ_of_le)
905+
(hnm : n ≤ m) (hmk : m ≤ k) :
906+
leRec (motive := motive) refl le_succ_of_le (Nat.le_trans hnm hmk) =
907+
leRec
908+
(leRec refl (fun _ h => le_succ_of_le h) hnm)
909+
(fun _ h => le_succ_of_le <| Nat.le_trans hnm h) hmk := by
910+
induction hmk with
911+
| refl => rw [leRec_self]
912+
| step hmk ih => rw [leRec_succ _ _ (Nat.le_trans hnm hmk), ih, leRec_succ]
913+
914+
lemma leRec_succ_left {motive : (m : ℕ) → n ≤ m → Sort*}
915+
(refl le_succ_of_le) {m} (h1 : n ≤ m) (h2 : n + 1 ≤ m) :
916+
-- the `@` is needed for this to elaborate, even though we only provide explicit arguments!
917+
@leRec _ _ (le_succ_of_le le_rfl refl) (fun k h ih => le_succ_of_le (le_of_succ_le h) ih) _ h2 =
918+
leRec (motive := motive) refl le_succ_of_le h1 := by
919+
rw [leRec_trans _ _ (le_succ n) h2, leRec_succ']
920+
921+
/-- Recursion starting at a non-zero number: given a map `C k → C (k+1)` for each `k ≥ n`,
922+
there is a map from `C n` to each `C m`, `n ≤ m`.
923+
924+
Prefer `Nat.leRec`, which can be used as `induction h using Nat.leRec`. -/
925+
@[elab_as_elim, deprecated Nat.leRec (since := "2024-07-05")]
926+
def leRecOn' {C : ℕ → Sort*} : ∀ {m}, n ≤ m → (∀ ⦃k⦄, n ≤ k → C k → C (k + 1)) → C n → C m :=
927+
fun h of_succ self => Nat.leRec self of_succ h
863928
#align nat.le_rec_on' Nat.leRecOn'
864929

865930
/-- Recursion starting at a non-zero number: given a map `C k → C (k + 1)` for each `k`,
866931
there is a map from `C n` to each `C m`, `n ≤ m`. For a version where the assumption is only made
867-
when `k ≥ n`, see `Nat.leRecOn'`. -/
932+
when `k ≥ n`, see `Nat.leRec`. -/
868933
@[elab_as_elim]
869-
def leRecOn {C : ℕ → Sort*} {n : ℕ} : ∀ {m}, n ≤ m → (∀ {k}, C k → C (k + 1)) → C n → C m
870-
| 0, H, _, x => Eq.recOn (Nat.eq_zero_of_le_zero H) x
871-
| m + 1, H, next, x => (le_succ_iff.1 H).by_cases (fun h : n ≤ m ↦ next <| leRecOn h next x)
872-
fun h : n = m + 1 ↦ Eq.recOn h x
934+
def leRecOn {C : ℕ → Sort*} {n : ℕ} : ∀ {m}, n ≤ m → (∀ {k}, C k → C (k + 1)) → C n → C m :=
935+
fun h of_succ self => Nat.leRec self (fun _ _ => @of_succ _) h
873936
#align nat.le_rec_on Nat.leRecOn
874937

875938
lemma leRecOn_self {C : ℕ → Sort*} {n} {next : ∀ {k}, C k → C (k + 1)} (x : C n) :
876-
(leRecOn n.le_refl next x : C n) = x := by cases n <;> simp [leRecOn, Or.by_cases, dif_neg]
939+
(leRecOn n.le_refl next x : C n) = x :=
940+
leRec_self _ _
877941
#align nat.le_rec_on_self Nat.leRecOn_self
878942

879943
lemma leRecOn_succ {C : ℕ → Sort*} {n m} (h1 : n ≤ m) {h2 : n ≤ m + 1} {next} (x : C n) :
880-
(leRecOn h2 next x : C (m + 1)) = next (leRecOn h1 next x : C m) := by
881-
conv =>
882-
lhs
883-
rw [leRecOn, Or.by_cases, dif_pos h1]
944+
(leRecOn h2 next x : C (m + 1)) = next (leRecOn h1 next x : C m) :=
945+
leRec_succ _ _ _
884946
#align nat.le_rec_on_succ Nat.leRecOn_succ
885947

886948
lemma leRecOn_succ' {C : ℕ → Sort*} {n} {h : n ≤ n + 1} {next : ∀ {k}, C k → C (k + 1)} (x : C n) :
887-
(leRecOn h next x : C (n + 1)) = next x := by rw [leRecOn_succ (le_refl n), leRecOn_self]
949+
(leRecOn h next x : C (n + 1)) = next x :=
950+
leRec_succ' _ _
888951
#align nat.le_rec_on_succ' Nat.leRecOn_succ'
889952

890953
lemma leRecOn_trans {C : ℕ → Sort*} {n m k} (hnm : n ≤ m) (hmk : m ≤ k) {next} (x : C n) :
891954
(leRecOn (Nat.le_trans hnm hmk) (@next) x : C k) =
892-
leRecOn hmk (@next) (leRecOn hnm (@next) x) := by
893-
induction hmk with
894-
| refl => rw [leRecOn_self]
895-
| step hmk ih => rw [leRecOn_succ (Nat.le_trans hnm hmk), ih, leRecOn_succ]
955+
leRecOn hmk (@next) (leRecOn hnm (@next) x) :=
956+
leRec_trans _ _ _ _
896957
#align nat.le_rec_on_trans Nat.leRecOn_trans
897958

898-
lemma leRecOn_succ_left {C : ℕ → Sort*} {n m} (h1 : n ≤ m) (h2 : n + 1 ≤ m)
899-
{next : ∀ {k}, C k → C (k + 1)} (x : C n) :
900-
(leRecOn h2 next (next x) : C m) = (leRecOn h1 next x : C m) := by
901-
rw [Subsingleton.elim h1 (Nat.le_trans (le_succ n) h2), leRecOn_trans (le_succ n) h2,
902-
leRecOn_succ']
959+
lemma leRecOn_succ_left {C : ℕ → Sort*} {n m}
960+
{next : ∀ {k}, C k → C (k + 1)} (x : C n) (h1 : n ≤ m) (h2 : n + 1 ≤ m) :
961+
(leRecOn h2 next (next x) : C m) = (leRecOn h1 next x : C m) :=
962+
leRec_succ_left (motive := fun n _ => C n) _ (fun _ _ => @next _) _ _
903963
#align nat.le_rec_on_succ_left Nat.leRecOn_succ_left
904964

905965
lemma leRecOn_injective {C : ℕ → Sort*} {n m} (hnm : n ≤ m) (next : ∀ {k}, C k → C (k + 1))
@@ -946,62 +1006,69 @@ lemma strongRecOn'_beta {P : ℕ → Sort*} {h} :
9461006
simp only [strongRecOn']; rw [Nat.strongRec']
9471007
#align nat.strong_rec_on_beta' Nat.strongRecOn'_beta
9481008

949-
/-- Induction principle starting at a non-zero number. For maps to a `Sort*` see `leRecOn`.
1009+
/-- Induction principle starting at a non-zero number.
9501010
To use in an induction proof, the syntax is `induction n, hn using Nat.le_induction` (or the same
951-
for `induction'`). -/
1011+
for `induction'`).
1012+
1013+
This is an alias of `Nat.leRec`, specialized to `Prop`. -/
9521014
@[elab_as_elim]
9531015
lemma le_induction {m : ℕ} {P : ∀ n, m ≤ n → Prop} (base : P m m.le_refl)
954-
(succ : ∀ n hmn, P n hmn → P (n + 1) (le_succ_of_le hmn)) : ∀ n hmn, P n hmn := fun n hmn ↦ by
955-
apply Nat.le.rec
956-
· exact base
957-
· intros n hn
958-
apply succ n hn
1016+
(succ : ∀ n hmn, P n hmn → P (n + 1) (le_succ_of_le hmn)) : ∀ n hmn, P n hmn :=
1017+
@Nat.leRec (motive := P) base succ
9591018
#align nat.le_induction Nat.le_induction
9601019

961-
/-- Decreasing induction: if `P (k+1)` implies `P k`, then `P n` implies `P m` for all `m ≤ n`.
962-
Also works for functions to `Sort*`. For m version assuming only the assumption for `k < n`, see
963-
`decreasing_induction'`. -/
1020+
/-- Decreasing induction: if `P (k+1)` implies `P k` for all `k < n`, then `P n` implies `P m` for
1021+
all `m ≤ n`.
1022+
Also works for functions to `Sort*`.
1023+
1024+
For a version also assuming `m ≤ k`, see `Nat.decreasingInduction'`. -/
9641025
@[elab_as_elim]
965-
def decreasingInduction {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n) (mn : m ≤ n) (hP : P n) : P m :=
966-
leRecOn mn (fun {k} ih hsk ↦ ih <| h k hsk) (fun h ↦ h) hP
1026+
def decreasingInduction {n} {motive : (m : ℕ) → m ≤ n → Sort*}
1027+
(of_succ : ∀ k (h : k < n), motive (k + 1) h → motive k (le_of_succ_le h))
1028+
(self : motive n le_rfl) {m} (mn : m ≤ n) : motive m mn := by
1029+
induction mn using leRec with
1030+
| refl => exact self
1031+
| @le_succ_of_le k _ ih =>
1032+
apply ih (fun i hi => of_succ i (le_succ_of_le hi)) (of_succ k (lt_succ_self _) self)
9671033
#align nat.decreasing_induction Nat.decreasingInduction
9681034

9691035
@[simp]
970-
lemma decreasingInduction_self {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n) (nn : n ≤ n)
971-
(hP : P n) :
972-
(decreasingInduction h nn hP : P n) = hP := by
1036+
lemma decreasingInduction_self {n} {motive : (m : ℕ) → m ≤ n → Sort*} (of_succ self) :
1037+
(decreasingInduction (motive := motive) of_succ self le_rfl) = self := by
9731038
dsimp only [decreasingInduction]
974-
rw [leRecOn_self]
1039+
rw [leRec_self]
9751040
#align nat.decreasing_induction_self Nat.decreasingInduction_self
9761041

977-
lemma decreasingInduction_succ {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n) (mn : m ≤ n)
978-
(msn : m ≤ n + 1) (hP : P (n + 1)) :
979-
(decreasingInduction h msn hP : P m) = decreasingInduction h mn (h n hP) := by
980-
dsimp only [decreasingInduction]; rw [leRecOn_succ]
1042+
lemma decreasingInduction_succ {n} {motive : (m : ℕ) → m ≤ n + 1Sort*} (of_succ self)
1043+
(mn : m ≤ n) (msn : m ≤ n + 1) :
1044+
(decreasingInduction (motive := motive) of_succ self msn : motive m msn) =
1045+
decreasingInduction (motive := fun m h => motive m (le_succ_of_le h))
1046+
(fun i hi => of_succ _ _) (of_succ _ _ self) mn := by
1047+
dsimp only [decreasingInduction]; rw [leRec_succ]
9811048
#align nat.decreasing_induction_succ Nat.decreasingInduction_succ
9821049

9831050
@[simp]
984-
lemma decreasingInduction_succ' {P : ℕ → Sort*} (h : ∀ n, P (n + 1)P n) {m : ℕ}
985-
(msm : m ≤ m + 1) (hP : P (m + 1)) : decreasingInduction h msm hP = h m hP := by
986-
dsimp only [decreasingInduction]; rw [leRecOn_succ']
1051+
lemma decreasingInduction_succ' {n} {motive : (m : ℕ) → m ≤ n + 1Sort*} (of_succ self) :
1052+
decreasingInduction (motive := motive) of_succ self n.le_succ = of_succ _ _ self := by
1053+
dsimp only [decreasingInduction]; rw [leRec_succ']
9871054
#align nat.decreasing_induction_succ' Nat.decreasingInduction_succ'
9881055

989-
lemma decreasingInduction_trans {P : Sort*} (h : ∀ n, P (n + 1) → P n)
990-
(hmn : m ≤ n) (hnk : n ≤ k) (hP : P k) :
991-
(decreasingInduction h (Nat.le_trans hmn hnk) hP : P m) =
992-
decreasingInduction h hmn (decreasingInduction h hnk hP) := by
1056+
lemma decreasingInduction_trans {motive : (m : ℕ)m ≤ k → Sort*} (hmn : m ≤ n) (hnk : n ≤ k)
1057+
(of_succ self) :
1058+
(decreasingInduction (motive := motive) of_succ self (Nat.le_trans hmn hnk) : motive m _) =
1059+
decreasingInduction (fun n ih => of_succ _ _) (decreasingInduction of_succ self hnk) hmn := by
9931060
induction hnk with
9941061
| refl => rw [decreasingInduction_self]
9951062
| step hnk ih =>
996-
rw [decreasingInduction_succ h (Nat.le_trans hmn hnk), ih, decreasingInduction_succ]
1063+
rw [decreasingInduction_succ _ _ (Nat.le_trans hmn hnk), ih, decreasingInduction_succ]
9971064
#align nat.decreasing_induction_trans Nat.decreasingInduction_trans
9981065

999-
lemma decreasingInduction_succ_left {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n)
1000-
(smn : m + 1 ≤ n) (mn : m ≤ n) (hP : P n) :
1001-
decreasingInduction h mn hP = h m (decreasingInduction h smn hP) := by
1066+
lemma decreasingInduction_succ_left {motive : (m : ℕ) → m ≤ n → Sort*} (of_succ self)
1067+
(smn : m + 1 ≤ n) (mn : m ≤ n) :
1068+
decreasingInduction (motive := motive) of_succ self mn =
1069+
of_succ m smn (decreasingInduction of_succ self smn) := by
10021070
rw [Subsingleton.elim mn (Nat.le_trans (le_succ m) smn), decreasingInduction_trans,
10031071
decreasingInduction_succ']
1004-
apply Nat.le_succ
10051072
#align nat.decreasing_induction_succ_left Nat.decreasingInduction_succ_left
10061073

10071074
/-- Given `P : ℕ → ℕ → Sort*`, if for all `m n : ℕ` we can extend `P` from the rectangle
@@ -1029,18 +1096,16 @@ def pincerRecursion {P : ℕ → ℕ → Sort*} (Ha0 : ∀ m : ℕ, P m 0) (H0b
10291096
#align nat.pincer_recursion Nat.pincerRecursion
10301097

10311098
/-- Decreasing induction: if `P (k+1)` implies `P k` for all `m ≤ k < n`, then `P n` implies `P m`.
1032-
Also works for functions to `Sort*`. Weakens the assumptions of `decreasing_induction`. -/
1099+
Also works for functions to `Sort*`.
1100+
1101+
Weakens the assumptions of `Nat.decreasingInduction`. -/
10331102
@[elab_as_elim]
10341103
def decreasingInduction' {P : ℕ → Sort*} (h : ∀ k < n, m ≤ k → P (k + 1) → P k)
10351104
(mn : m ≤ n) (hP : P n) : P m := by
1036-
revert h hP
1037-
refine leRecOn' mn ?_ ?_
1038-
· intro n mn ih h hP
1039-
apply ih
1040-
· exact fun k hk ↦ h k (Nat.lt.step hk)
1041-
· exact h n (lt_succ_self n) mn hP
1042-
· intro _ hP
1043-
exact hP
1105+
induction mn using decreasingInduction with
1106+
| self => exact hP
1107+
| of_succ k hk ih =>
1108+
exact h _ (lt_of_succ_le hk) le_rfl (ih fun k' hk' h'' => h k' hk' <| le_of_succ_le h'')
10441109
#align nat.decreasing_induction' Nat.decreasingInduction'
10451110

10461111
/-- Given a predicate on two naturals `P : ℕ → ℕ → Prop`, `P a b` is true for all `a < b` if

Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,7 @@ private theorem toStepOfLE'.succ (m n : ℕ) (h : m ≤ n) :
211211
toStepOfLE' k m (Nat.succ n) (h.trans n.le_succ) =
212212
(toStepSucc k n) ∘ toStepOfLE' k m n h := by
213213
ext x
214-
convert Nat.leRecOn_succ h x
215-
exact h.trans n.le_succ
214+
exact Nat.leRecOn_succ h x
216215

217216
/-- The canonical ring homomorphism to a step with a greater index. -/
218217
def toStepOfLE (m n : ℕ) (h : m ≤ n) : Step k m →+* Step k n where

Mathlib/LinearAlgebra/Matrix/Transvection.lean

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -370,13 +370,13 @@ def listTransvecRow : List (Matrix (Sum (Fin r) Unit) (Sum (Fin r) Unit) 𝕜) :
370370
/-- Multiplying by some of the matrices in `listTransvecCol M` does not change the last row. -/
371371
theorem listTransvecCol_mul_last_row_drop (i : Sum (Fin r) Unit) {k : ℕ} (hk : k ≤ r) :
372372
(((listTransvecCol M).drop k).prod * M) (inr unit) i = M (inr unit) i := by
373-
-- Porting note: `apply` didn't work anymore, because of the implicit arguments
374-
refine Nat.decreasingInduction' ?_ hk ?_
375-
· intro n hn _ IH
373+
induction hk using Nat.decreasingInduction with
374+
| of_succ n hn IH =>
376375
have hn' : n < (listTransvecCol M).length := by simpa [listTransvecCol] using hn
377376
rw [List.drop_eq_getElem_cons hn']
378377
simpa [listTransvecCol, Matrix.mul_assoc]
379-
· simp only [listTransvecCol, List.length_ofFn, le_refl, List.drop_eq_nil_of_le, List.prod_nil,
378+
| self =>
379+
simp only [listTransvecCol, List.length_ofFn, le_refl, List.drop_eq_nil_of_le, List.prod_nil,
380380
Matrix.one_mul]
381381
#align matrix.pivot.list_transvec_col_mul_last_row_drop Matrix.Pivot.listTransvecCol_mul_last_row_drop
382382

@@ -397,9 +397,8 @@ theorem listTransvecCol_mul_last_col (hM : M (inr unit) (inr unit) ≠ 0) (i : F
397397
if k ≤ i then 0 else M (inl i) (inr unit) by
398398
simpa only [List.drop, _root_.zero_le, ite_true] using H 0 (zero_le _)
399399
intro k hk
400-
-- Porting note: `apply` didn't work anymore, because of the implicit arguments
401-
refine Nat.decreasingInduction' ?_ hk ?_
402-
· intro n hn hk IH
400+
induction hk using Nat.decreasingInduction with
401+
| of_succ n hn IH =>
403402
have hn' : n < (listTransvecCol M).length := by simpa [listTransvecCol] using hn
404403
let n' : Fin r := ⟨n, hn⟩
405404
rw [List.drop_eq_getElem_cons hn']
@@ -427,7 +426,8 @@ theorem listTransvecCol_mul_last_col (hM : M (inr unit) (inr unit) ≠ 0) (i : F
427426
· rw [if_neg, if_neg]
428427
· simpa only [hni.symm, not_le, or_false_iff] using Nat.lt_succ_iff_lt_or_eq.1 hi
429428
· simpa only [not_le] using hi
430-
· simp only [listTransvecCol, List.length_ofFn, le_refl, List.drop_eq_nil_of_le, List.prod_nil,
429+
| self =>
430+
simp only [listTransvecCol, List.length_ofFn, le_refl, List.drop_eq_nil_of_le, List.prod_nil,
431431
Matrix.one_mul]
432432
rw [if_neg]
433433
simpa only [not_le] using i.2

Mathlib/Order/Interval/Finset/Nat.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ variable {P : ℕ → Prop} (h : ∀ n, P (n + 1) → P n)
310310

311311
theorem Nat.decreasing_induction_of_not_bddAbove (hP : ¬BddAbove { x | P x }) (n : ℕ) : P n :=
312312
let ⟨_, hm, hl⟩ := not_bddAbove_iff.1 hP n
313-
decreasingInduction h hl.le hm
313+
decreasingInduction (fun _ _ => h _) hm hl.le
314314
#align nat.decreasing_induction_of_not_bdd_above Nat.decreasing_induction_of_not_bddAbove
315315

316316
@[elab_as_elim]

0 commit comments

Comments
 (0)