@@ -854,52 +854,112 @@ lemma rec_add_one {C : ℕ → Sort*} (h0 : C 0) (h : ∀ n, C n → C (n + 1))
854
854
Nat.rec (motive := C) h0 h 1 = h 0 h0 := rfl
855
855
856
856
/-- 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
+ -/
858
867
@[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
863
928
#align nat.le_rec_on' Nat.leRecOn'
864
929
865
930
/-- Recursion starting at a non-zero number: given a map `C k → C (k + 1)` for each `k`,
866
931
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 `. -/
868
933
@[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
873
936
#align nat.le_rec_on Nat.leRecOn
874
937
875
938
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 _ _
877
941
#align nat.le_rec_on_self Nat.leRecOn_self
878
942
879
943
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 _ _ _
884
946
#align nat.le_rec_on_succ Nat.leRecOn_succ
885
947
886
948
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' _ _
888
951
#align nat.le_rec_on_succ' Nat.leRecOn_succ'
889
952
890
953
lemma leRecOn_trans {C : ℕ → Sort *} {n m k} (hnm : n ≤ m) (hmk : m ≤ k) {next} (x : C n) :
891
954
(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 _ _ _ _
896
957
#align nat.le_rec_on_trans Nat.leRecOn_trans
897
958
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 _) _ _
903
963
#align nat.le_rec_on_succ_left Nat.leRecOn_succ_left
904
964
905
965
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} :
946
1006
simp only [strongRecOn']; rw [Nat.strongRec']
947
1007
#align nat.strong_rec_on_beta' Nat.strongRecOn'_beta
948
1008
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.
950
1010
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`. -/
952
1014
@[elab_as_elim]
953
1015
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
959
1018
#align nat.le_induction Nat.le_induction
960
1019
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'`. -/
964
1025
@[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)
967
1033
#align nat.decreasing_induction Nat.decreasingInduction
968
1034
969
1035
@[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
973
1038
dsimp only [decreasingInduction]
974
- rw [leRecOn_self ]
1039
+ rw [leRec_self ]
975
1040
#align nat.decreasing_induction_self Nat.decreasingInduction_self
976
1041
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 + 1 → Sort *} (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]
981
1048
#align nat.decreasing_induction_succ Nat.decreasingInduction_succ
982
1049
983
1050
@[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 + 1 → Sort *} (of_succ self) :
1052
+ decreasingInduction (motive := motive) of_succ self n.le_succ = of_succ _ _ self := by
1053
+ dsimp only [decreasingInduction]; rw [leRec_succ ']
987
1054
#align nat.decreasing_induction_succ' Nat.decreasingInduction_succ'
988
1055
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
993
1060
induction hnk with
994
1061
| refl => rw [decreasingInduction_self]
995
1062
| 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]
997
1064
#align nat.decreasing_induction_trans Nat.decreasingInduction_trans
998
1065
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
1002
1070
rw [Subsingleton.elim mn (Nat.le_trans (le_succ m) smn), decreasingInduction_trans,
1003
1071
decreasingInduction_succ']
1004
- apply Nat.le_succ
1005
1072
#align nat.decreasing_induction_succ_left Nat.decreasingInduction_succ_left
1006
1073
1007
1074
/-- 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
1029
1096
#align nat.pincer_recursion Nat.pincerRecursion
1030
1097
1031
1098
/-- 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`. -/
1033
1102
@[elab_as_elim]
1034
1103
def decreasingInduction' {P : ℕ → Sort *} (h : ∀ k < n, m ≤ k → P (k + 1 ) → P k)
1035
1104
(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'')
1044
1109
#align nat.decreasing_induction' Nat.decreasingInduction'
1045
1110
1046
1111
/-- Given a predicate on two naturals `P : ℕ → ℕ → Prop`, `P a b` is true for all `a < b` if
0 commit comments