File: Mathlib/Data/Fin/Basic.lean

full_name: finZeroElim
code: /-- Elimination principle for the empty set `Fin 0`, dependent version. -/
def finZeroElim {α : Fin 0 → Sort*} (x : Fin 0) : α x 
goal: α x

full_name: Fin.instCanLiftNatValLt
code: instance {n : ℕ} : CanLift ℕ (Fin n) Fin.val (· < n) 
goal: CanLift ℕ (Fin n) Fin.val fun x => x < n

full_name: Fin.rec0
code: /-- A dependent variant of `Fin.elim0`. -/
def rec0 {α : Fin 0 → Sort*} (i : Fin 0) : α i 
goal: α i

full_name: Fin.val_injective
code: theorem val_injective : Function.Injective (@Fin.val n) 
goal: Function.Injective Fin.val

full_name: Fin.size_positive
code: /-- If you actually have an element of `Fin n`, then the `n` is always positive -/
lemma size_positive : Fin n → 0 < n 
goal: Fin n → 0 < n

full_name: Fin.size_positive'
code: lemma size_positive' [Nonempty (Fin n)] : 0 < n 
goal: 0 < n

full_name: Fin.prop
code: protected theorem prop (a : Fin n) : a.val < n 
goal: ↑a < n

full_name: Fin.lt_of_le_of_lt
code: protected lemma lt_of_le_of_lt : a ≤ b → b < c → a < c 
goal: a ≤ b → b < c → a < c

full_name: Fin.lt_of_lt_of_le
code: protected lemma lt_of_lt_of_le : a < b → b ≤ c → a < c 
goal: a < b → b ≤ c → a < c

full_name: Fin.le_rfl
code: protected lemma le_rfl : a ≤ a 
goal: a ≤ a

full_name: Fin.lt_iff_le_and_ne
code: protected lemma lt_iff_le_and_ne : a < b ↔ a ≤ b ∧ a ≠ b 
goal: a < b ↔ a ≤ b ∧ a ≠ b

full_name: Fin.lt_or_lt_of_ne
code: protected lemma lt_or_lt_of_ne (h : a ≠ b) : a < b ∨ b < a 
goal: a < b ∨ b < a

full_name: Fin.lt_or_le
code: protected lemma lt_or_le (a b : Fin n) : a < b ∨ b ≤ a 
goal: a < b ∨ b ≤ a

full_name: Fin.le_or_lt
code: protected lemma le_or_lt (a b : Fin n) : a ≤ b ∨ b < a 
goal: a ≤ b ∨ b < a

full_name: Fin.le_of_eq
code: protected lemma le_of_eq (hab : a = b) : a ≤ b 
goal: a ≤ b

full_name: Fin.ge_of_eq
code: protected lemma ge_of_eq (hab : a = b) : b ≤ a 
goal: b ≤ a

full_name: Fin.eq_or_lt_of_le
code: protected lemma eq_or_lt_of_le : a ≤ b → a = b ∨ a < b 
goal: a ≤ b → a = b ∨ a < b

full_name: Fin.lt_or_eq_of_le
code: protected lemma lt_or_eq_of_le : a ≤ b → a < b ∨ a = b 
goal: a ≤ b → a < b ∨ a = b

full_name: Fin.lt_last_iff_ne_last
code: lemma lt_last_iff_ne_last {a : Fin (n + 1)} : a < last n ↔ a ≠ last n 
goal: a < Fin.last n ↔ a ≠ Fin.last n

full_name: Fin.ne_zero_of_lt
code: lemma ne_zero_of_lt {a b : Fin (n + 1)} (hab : a < b) : b ≠ 0 
goal: b ≠ 0

full_name: Fin.ne_last_of_lt
code: lemma ne_last_of_lt {a b : Fin (n + 1)} (hab : a < b) : a ≠ last n 
goal: a ≠ Fin.last n

full_name: Fin.equivSubtype_symm_apply
code: /-- Equivalence between `Fin n` and `{ i // i < n }`. -/
@[simps apply symm_apply]
def equivSubtype : Fin n ≃ { i // i < n } 
goal: Fin.equivSubtype.symm a = ⟨↑a, ⋯⟩

full_name: Fin.equivSubtype
code: /-- Equivalence between `Fin n` and `{ i // i < n }`. -/
@[simps apply symm_apply]
def equivSubtype : Fin n ≃ { i // i < n } 
goal: Fin n ≃ { i // i < n }

full_name: Fin.equivSubtype_apply
code: /-- Equivalence between `Fin n` and `{ i // i < n }`. -/
@[simps apply symm_apply]
def equivSubtype : Fin n ≃ { i // i < n } 
goal: Fin.equivSubtype a = ⟨↑a, ⋯⟩

full_name: Fin.val_eq_val
code: theorem val_eq_val (a b : Fin n) : (a : ℕ) = b ↔ a = b 
goal: ↑a = ↑b ↔ a = b

full_name: Fin.eq_iff_veq
code: @[deprecated Fin.ext_iff (since := "2024-02-20")]
theorem eq_iff_veq (a b : Fin n) : a = b ↔ a.1 = b.1 
goal: a = b ↔ ↑a = ↑b

full_name: Fin.ne_iff_vne
code: theorem ne_iff_vne (a b : Fin n) : a ≠ b ↔ a.1 ≠ b.1 
goal: a ≠ b ↔ ↑a ≠ ↑b

full_name: Fin.mk_eq_mk
code: @[simp, nolint simpNF]
theorem mk_eq_mk {a h a' h'} : @mk n a h = @mk n a' h' ↔ a = a' 
goal: ⟨a, h⟩ = ⟨a', h'⟩ ↔ a = a'

full_name: Fin.heq_fun_iff
code: /-- Assume `k = l`. If two functions defined on `Fin k` and `Fin l` are equal on each element,
then they coincide (in the heq sense). -/
protected theorem heq_fun_iff {α : Sort*} {k l : ℕ} (h : k = l) {f : Fin k → α} {g : Fin l → α} :
    HEq f g ↔ ∀ i : Fin k, f i = g ⟨(i : ℕ), h ▸ i.2⟩ 
goal: HEq f g ↔ ∀ (i : Fin k), f i = g ⟨↑i, ⋯⟩

full_name: Fin.heq_fun₂_iff
code: /-- Assume `k = l` and `k' = l'`.
If two functions `Fin k → Fin k' → α` and `Fin l → Fin l' → α` are equal on each pair,
then they coincide (in the heq sense). -/
protected theorem heq_fun₂_iff {α : Sort*} {k l k' l' : ℕ} (h : k = l) (h' : k' = l')
    {f : Fin k → Fin k' → α} {g : Fin l → Fin l' → α} :
    HEq f g ↔ ∀ (i : Fin k) (j : Fin k'), f i j = g ⟨(i : ℕ), h ▸ i.2⟩ ⟨(j : ℕ), h' ▸ j.2⟩ 
goal: HEq f g ↔ ∀ (i : Fin k) (j : Fin k'), f i j = g ⟨↑i, ⋯⟩ ⟨↑j, ⋯⟩

full_name: Fin.heq_ext_iff
code: protected theorem heq_ext_iff {k l : ℕ} (h : k = l) {i : Fin k} {j : Fin l} :
    HEq i j ↔ (i : ℕ) = (j : ℕ) 
goal: HEq i j ↔ ↑i = ↑j

full_name: Fin.le_iff_val_le_val
code: theorem le_iff_val_le_val {a b : Fin n} : a ≤ b ↔ (a : ℕ) ≤ b 
goal: a ≤ b ↔ ↑a ≤ ↑b

full_name: Fin.val_fin_lt
code: /-- `a < b` as natural numbers if and only if `a < b` in `Fin n`. -/
@[norm_cast, simp]
theorem val_fin_lt {n : ℕ} {a b : Fin n} : (a : ℕ) < (b : ℕ) ↔ a < b 
goal: ↑a < ↑b ↔ a < b

full_name: Fin.val_fin_le
code: /-- `a ≤ b` as natural numbers if and only if `a ≤ b` in `Fin n`. -/
@[norm_cast, simp]
theorem val_fin_le {n : ℕ} {a b : Fin n} : (a : ℕ) ≤ (b : ℕ) ↔ a ≤ b 
goal: ↑a ≤ ↑b ↔ a ≤ b

full_name: Fin.min_val
code: theorem min_val {a : Fin n} : min (a : ℕ) n = a 
goal: min (↑a) n = ↑a

full_name: Fin.max_val
code: theorem max_val {a : Fin n} : max (a : ℕ) n = n 
goal: max (↑a) n = n

full_name: Fin.valEmbedding_apply
code: /-- The inclusion map `Fin n → ℕ` is an embedding. -/
@[simps apply]
def valEmbedding : Fin n ↪ ℕ 
goal: Fin.valEmbedding self = ↑self

full_name: Fin.valEmbedding
code: /-- The inclusion map `Fin n → ℕ` is an embedding. -/
@[simps apply]
def valEmbedding : Fin n ↪ ℕ 
goal: Fin n ↪ ℕ

full_name: Fin.equivSubtype_symm_trans_valEmbedding
code: @[simp]
theorem equivSubtype_symm_trans_valEmbedding :
    equivSubtype.symm.toEmbedding.trans valEmbedding = Embedding.subtype (· < n) 
goal: Fin.equivSubtype.symm.toEmbedding.trans Fin.valEmbedding = Function.Embedding.subtype fun x => x < n

full_name: Fin.instWellFoundedRelation_mathlib
code: /-- Use the ordering on `Fin n` for checking recursive definitions.

For example, the following definition is not accepted by the termination checker,
unless we declare the `WellFoundedRelation` instance:
```lean
def factorial {n : ℕ} : Fin n → ℕ
  | ⟨0, _⟩ := 1
  | ⟨i + 1, hi⟩ := (i + 1) * factorial ⟨i, i.lt_succ_self.trans hi⟩
```
-/
instance {n : ℕ} : WellFoundedRelation (Fin n) 
goal: WellFoundedRelation (Fin n)

full_name: Fin.ofNat''
code: /-- Given a positive `n`, `Fin.ofNat' i` is `i % n` as an element of `Fin n`. -/
def ofNat'' [NeZero n] (i : ℕ) : Fin n 
goal: Fin n

full_name: Fin.instZeroOfNeZeroNat
code: instance {n : ℕ} [NeZero n] : Zero (Fin n) 
goal: Zero (Fin n)

full_name: Fin.instOneOfNeZeroNat
code: instance {n : ℕ} [NeZero n] : One (Fin n) 
goal: One (Fin n)

full_name: Fin.val_zero'
code: /--
The `Fin.val_zero` in `Lean` only applies in `Fin (n+1)`.
This one instead uses a `NeZero n` typeclass hypothesis.
-/
@[simp]
theorem val_zero' (n : ℕ) [NeZero n] : ((0 : Fin n) : ℕ) = 0 
goal: ↑0 = 0

full_name: Fin.zero_le'
code: /--
The `Fin.zero_le` in `Lean` only applies in `Fin (n+1)`.
This one instead uses a `NeZero n` typeclass hypothesis.
-/
@[simp]
protected theorem zero_le' [NeZero n] (a : Fin n) : 0 ≤ a 
goal: 0 ≤ a

full_name: Fin.pos_iff_ne_zero'
code: /--
The `Fin.pos_iff_ne_zero` in `Lean` only applies in `Fin (n+1)`.
This one instead uses a `NeZero n` typeclass hypothesis.
-/
theorem pos_iff_ne_zero' [NeZero n] (a : Fin n) : 0 < a ↔ a ≠ 0 
goal: 0 < a ↔ a ≠ 0

full_name: Fin.cast_eq_self
code: @[simp] lemma cast_eq_self (a : Fin n) : cast rfl a = a 
goal: Fin.cast ⋯ a = a

full_name: Fin.rev_involutive
code: theorem rev_involutive : Involutive (rev : Fin n → Fin n) 
goal: Function.Involutive Fin.rev

full_name: Fin.revPerm
code: /-- `Fin.rev` as an `Equiv.Perm`, the antitone involution `Fin n → Fin n` given by
`i ↦ n-(i+1)`. -/
@[simps! apply symm_apply]
def revPerm : Equiv.Perm (Fin n) 
goal: Equiv.Perm (Fin n)

full_name: Fin.revPerm_apply
code: /-- `Fin.rev` as an `Equiv.Perm`, the antitone involution `Fin n → Fin n` given by
`i ↦ n-(i+1)`. -/
@[simps! apply symm_apply]
def revPerm : Equiv.Perm (Fin n) 
goal: Fin.revPerm i = i.rev

full_name: Fin.revPerm_symm_apply
code: /-- `Fin.rev` as an `Equiv.Perm`, the antitone involution `Fin n → Fin n` given by
`i ↦ n-(i+1)`. -/
@[simps! apply symm_apply]
def revPerm : Equiv.Perm (Fin n) 
goal: (Equiv.symm Fin.revPerm) i = i.rev

full_name: Fin.rev_injective
code: theorem rev_injective : Injective (@rev n) 
goal: Function.Injective Fin.rev

full_name: Fin.rev_surjective
code: theorem rev_surjective : Surjective (@rev n) 
goal: Function.Surjective Fin.rev

full_name: Fin.rev_bijective
code: theorem rev_bijective : Bijective (@rev n) 
goal: Function.Bijective Fin.rev

full_name: Fin.revPerm_symm
code: @[simp]
theorem revPerm_symm : (@revPerm n).symm = revPerm 
goal: Equiv.symm Fin.revPerm = Fin.revPerm

full_name: Fin.cast_rev
code: theorem cast_rev (i : Fin n) (h : n = m) :
    cast h i.rev = (i.cast h).rev 
goal: Fin.cast h i.rev = (Fin.cast h i).rev

full_name: Fin.rev_eq_iff
code: theorem rev_eq_iff {i j : Fin n} : rev i = j ↔ i = rev j 
goal: i.rev = j ↔ i = j.rev

full_name: Fin.rev_ne_iff
code: theorem rev_ne_iff {i j : Fin n} : rev i ≠ j ↔ i ≠ rev j 
goal: i.rev ≠ j ↔ i ≠ j.rev

full_name: Fin.rev_lt_iff
code: theorem rev_lt_iff {i j : Fin n} : rev i < j ↔ rev j < i 
goal: i.rev < j ↔ j.rev < i

full_name: Fin.rev_le_iff
code: theorem rev_le_iff {i j : Fin n} : rev i ≤ j ↔ rev j ≤ i 
goal: i.rev ≤ j ↔ j.rev ≤ i

full_name: Fin.lt_rev_iff
code: theorem lt_rev_iff {i j : Fin n} : i < rev j ↔ j < rev i 
goal: i < j.rev ↔ j < i.rev

full_name: Fin.le_rev_iff
code: theorem le_rev_iff {i j : Fin n} : i ≤ rev j ↔ j ≤ rev i 
goal: i ≤ j.rev ↔ j ≤ i.rev

full_name: Fin.val_rev_zero
code: @[simp] theorem val_rev_zero [NeZero n] : ((rev 0 : Fin n) : ℕ) = n.pred 
goal: ↑(Fin.rev 0) = n.pred

full_name: Fin.last_pos'
code: theorem last_pos' [NeZero n] : 0 < last n 
goal: 0 < Fin.last n

full_name: Fin.one_lt_last
code: theorem one_lt_last [NeZero n] : 1 < last (n + 1) 
goal: 1 < Fin.last (n + 1)

full_name: Fin.val_one'
code: @[simp]
theorem val_one' (n : ℕ) [NeZero n] : ((1 : Fin n) : ℕ) = 1 % n 
goal: ↑1 = 1 % n

full_name: Fin.val_one''
code: theorem val_one'' {n : ℕ} : ((1 : Fin (n + 1)) : ℕ) = 1 % (n + 1) 
goal: ↑1 = 1 % (n + 1)

full_name: Fin.nontrivial
code: instance nontrivial {n : ℕ} : Nontrivial (Fin (n + 2)) 
goal: Nontrivial (Fin (n + 2))

full_name: Fin.nontrivial_iff_two_le
code: theorem nontrivial_iff_two_le : Nontrivial (Fin n) ↔ 2 ≤ n 
goal: Nontrivial (Fin n) ↔ 2 ≤ n

full_name: Fin.add_zero
code: protected theorem add_zero [NeZero n] (k : Fin n) : k + 0 = k 
goal: k + 0 = k

full_name: Fin.zero_add
code: protected theorem zero_add [NeZero n] (k : Fin n) : 0 + k = k 
goal: 0 + k = k

full_name: Fin.instOfNatOfNeZeroNat
code: instance {a : ℕ} [NeZero n] : OfNat (Fin n) a 
goal: OfNat (Fin n) a

full_name: Fin.inhabited
code: instance inhabited (n : ℕ) [NeZero n] : Inhabited (Fin n) 
goal: Inhabited (Fin n)

full_name: Fin.inhabitedFinOneAdd
code: instance inhabitedFinOneAdd (n : ℕ) : Inhabited (Fin (1 + n)) 
goal: Inhabited (Fin (1 + n))

full_name: Fin.default_eq_zero
code: @[simp]
theorem default_eq_zero (n : ℕ) [NeZero n] : (default : Fin n) = 0 
goal: default = 0

full_name: Fin.ofNat'_zero
code: @[simp] lemma ofNat'_zero {h : 0 < n} [NeZero n] : (Fin.ofNat' 0 h : Fin n) = 0 
goal: Fin.ofNat' 0 h = 0

full_name: Fin.ofNat'_one
code: @[simp] lemma ofNat'_one {h : 0 < n} [NeZero n] : (Fin.ofNat' 1 h : Fin n) = 1 
goal: Fin.ofNat' 1 h = 1

full_name: Fin.instNatCast
code: instance instNatCast [NeZero n] : NatCast (Fin n) 
goal: NatCast (Fin n)

full_name: Fin.natCast_def
code: lemma natCast_def [NeZero n] (a : ℕ) : (a : Fin n) = ⟨a % n, mod_lt _ n.pos_of_neZero⟩ 
goal: ↑a = ⟨a % n, ⋯⟩

full_name: Fin.val_add_eq_ite
code: theorem val_add_eq_ite {n : ℕ} (a b : Fin n) :
    (↑(a + b) : ℕ) = if n ≤ a + b then a + b - n else a + b 
goal: ↑(a + b) = if n ≤ ↑a + ↑b then ↑a + ↑b - n else ↑a + ↑b

full_name: Fin.ofNat''_eq_cast
code: @[simp]
theorem ofNat''_eq_cast (n : ℕ) [NeZero n] (a : ℕ) : (Fin.ofNat'' a : Fin n) = a 
goal: Fin.ofNat'' a = ↑a

full_name: Fin.val_natCast
code: @[simp] lemma val_natCast (a n : ℕ) [NeZero n] : (a : Fin n).val = a % n 
goal: ↑↑a = a % n

full_name: Fin.val_cast_of_lt
code: /-- Converting an in-range number to `Fin (n + 1)` produces a result
whose value is the original number.  -/
theorem val_cast_of_lt {n : ℕ} [NeZero n] {a : ℕ} (h : a < n) : (a : Fin n).val = a 
goal: ↑↑a = a

full_name: Fin.cast_val_eq_self
code: /-- If `n` is non-zero, converting the value of a `Fin n` to `Fin n` results
in the same value.  -/
@[simp] theorem cast_val_eq_self {n : ℕ} [NeZero n] (a : Fin n) : (a.val : Fin n) = a 
goal: ↑↑a = a

full_name: Fin.natCast_self
code: @[simp] lemma natCast_self (n : ℕ) [NeZero n] : (n : Fin n) = 0 
goal: ↑n = 0

full_name: Fin.natCast_eq_zero
code: @[simp] lemma natCast_eq_zero {a n : ℕ} [NeZero n] : (a : Fin n) = 0 ↔ n ∣ a 
goal: ↑a = 0 ↔ n ∣ a

full_name: Fin.natCast_eq_last
code: @[simp]
theorem natCast_eq_last (n) : (n : Fin (n + 1)) = Fin.last n 
goal: ↑n = Fin.last n

full_name: Fin.le_val_last
code: theorem le_val_last (i : Fin (n + 1)) : i ≤ n 
goal: i ≤ ↑n

full_name: Fin.natCast_le_natCast
code: lemma natCast_le_natCast (han : a ≤ n) (hbn : b ≤ n) : (a : Fin (n + 1)) ≤ b ↔ a ≤ b 
goal: ↑a ≤ ↑b ↔ a ≤ b

full_name: Fin.natCast_lt_natCast
code: lemma natCast_lt_natCast (han : a ≤ n) (hbn : b ≤ n) : (a : Fin (n + 1)) < b ↔ a < b 
goal: ↑a < ↑b ↔ a < b

full_name: Fin.natCast_mono
code: lemma natCast_mono (hbn : b ≤ n) (hab : a ≤ b) : (a : Fin (n + 1)) ≤ b 
goal: ↑a ≤ ↑b

full_name: Fin.natCast_strictMono
code: lemma natCast_strictMono (hbn : b ≤ n) (hab : a < b) : (a : Fin (n + 1)) < b 
goal: ↑a < ↑b

full_name: Fin.one_eq_zero_iff
code: @[simp]
theorem one_eq_zero_iff [NeZero n] : (1 : Fin n) = 0 ↔ n = 1 
goal: 1 = 0 ↔ n = 1

full_name: Fin.zero_eq_one_iff
code: @[simp]
theorem zero_eq_one_iff [NeZero n] : (0 : Fin n) = 1 ↔ n = 1 
goal: 0 = 1 ↔ n = 1

full_name: Fin.succ_injective
code: lemma succ_injective (n : ℕ) : Injective (@Fin.succ n) 
goal: Function.Injective Fin.succ

full_name: Fin.succEmb
code: /-- `Fin.succ` as an `Embedding` -/
def succEmb (n : ℕ) : Fin n ↪ Fin (n + 1) 
goal: Fin n ↪ Fin (n + 1)

full_name: Fin.val_succEmb
code: @[simp]
theorem val_succEmb : ⇑(succEmb n) = Fin.succ 
goal: ⇑(Fin.succEmb n) = Fin.succ

full_name: Fin.exists_succ_eq
code: @[simp]
theorem exists_succ_eq {x : Fin (n + 1)} : (∃ y, Fin.succ y = x) ↔ x ≠ 0 
goal: (∃ y, y.succ = x) ↔ x ≠ 0

full_name: Fin.exists_succ_eq_of_ne_zero
code: theorem exists_succ_eq_of_ne_zero {x : Fin (n + 1)} (h : x ≠ 0) :
    ∃ y, Fin.succ y = x 
goal: ∃ y, y.succ = x

full_name: Fin.succ_zero_eq_one'
code: @[simp]
theorem succ_zero_eq_one' [NeZero n] : Fin.succ (0 : Fin n) = 1 
goal: Fin.succ 0 = 1

full_name: Fin.one_pos'
code: theorem one_pos' [NeZero n] : (0 : Fin (n + 1)) < 1 
goal: 0 < 1

full_name: Fin.zero_ne_one'
code: theorem zero_ne_one' [NeZero n] : (0 : Fin (n + 1)) ≠ 1 
goal: 0 ≠ 1

full_name: Fin.succ_one_eq_two'
code: /--
The `Fin.succ_one_eq_two` in `Lean` only applies in `Fin (n+2)`.
This one instead uses a `NeZero n` typeclass hypothesis.
-/
@[simp]
theorem succ_one_eq_two' [NeZero n] : Fin.succ (1 : Fin (n + 1)) = 2 
goal: Fin.succ 1 = 2

full_name: Fin.le_zero_iff'
code: /--
The `Fin.le_zero_iff` in `Lean` only applies in `Fin (n+1)`.
This one instead uses a `NeZero n` typeclass hypothesis.
-/
@[simp]
theorem le_zero_iff' {n : ℕ} [NeZero n] {k : Fin n} : k ≤ 0 ↔ k = 0 
goal: k ≤ 0 ↔ k = 0

full_name: Fin.cast_refl
code: @[simp] theorem cast_refl {n : Nat} (h : n = n) :
    Fin.cast h = id 
goal: Fin.cast h = id

full_name: Fin.castLE_inj
code: @[simp] lemma castLE_inj {hmn : m ≤ n} {a b : Fin m} : castLE hmn a = castLE hmn b ↔ a = b 
goal: Fin.castLE hmn a = Fin.castLE hmn b ↔ a = b

full_name: Fin.castAdd_inj
code: @[simp] lemma castAdd_inj {a b : Fin m} : castAdd n a = castAdd n b ↔ a = b 
goal: Fin.castAdd n a = Fin.castAdd n b ↔ a = b

full_name: Fin.castLE_injective
code: lemma castLE_injective (hmn : m ≤ n) : Injective (castLE hmn) 
goal: Function.Injective (Fin.castLE hmn)

full_name: Fin.castAdd_injective
code: lemma castAdd_injective (m n : ℕ) : Injective (@Fin.castAdd m n) 
goal: Function.Injective (Fin.castAdd n)

full_name: Fin.castSucc_injective
code: lemma castSucc_injective (n : ℕ) : Injective (@Fin.castSucc n) 
goal: Function.Injective Fin.castSucc

full_name: Fin.castLEEmb
code: /-- `Fin.castLE` as an `Embedding`, `castLEEmb h i` embeds `i` into a larger `Fin` type.  -/
@[simps! apply]
def castLEEmb (h : n ≤ m) : Fin n ↪ Fin m 
goal: Fin n ↪ Fin m

full_name: Fin.castLEEmb_apply
code: /-- `Fin.castLE` as an `Embedding`, `castLEEmb h i` embeds `i` into a larger `Fin` type.  -/
@[simps! apply]
def castLEEmb (h : n ≤ m) : Fin n ↪ Fin m 
goal: (Fin.castLEEmb h) i = Fin.castLE h i

full_name: Fin.coe_castLEEmb
code: @[simp, norm_cast] lemma coe_castLEEmb {m n} (hmn : m ≤ n) : castLEEmb hmn = castLE hmn 
goal: ⇑(Fin.castLEEmb hmn) = Fin.castLE hmn

full_name: Fin.nonempty_embedding_iff
code: lemma nonempty_embedding_iff : Nonempty (Fin n ↪ Fin m) ↔ n ≤ m 
goal: Nonempty (Fin n ↪ Fin m) ↔ n ≤ m

full_name: Fin.equiv_iff_eq
code: lemma equiv_iff_eq : Nonempty (Fin m ≃ Fin n) ↔ m = n 
goal: Nonempty (Fin m ≃ Fin n) ↔ m = n

full_name: Fin.castLE_castSucc
code: @[simp] lemma castLE_castSucc {n m} (i : Fin n) (h : n + 1 ≤ m) :
    i.castSucc.castLE h = i.castLE (Nat.le_of_succ_le h) 
goal: Fin.castLE h i.castSucc = Fin.castLE ⋯ i

full_name: Fin.castLE_comp_castSucc
code: @[simp] lemma castLE_comp_castSucc {n m} (h : n + 1 ≤ m) :
    Fin.castLE h ∘ Fin.castSucc = Fin.castLE (Nat.le_of_succ_le h) 
goal: Fin.castLE h ∘ Fin.castSucc = Fin.castLE ⋯

full_name: Fin.castLE_rfl
code: @[simp] lemma castLE_rfl (n : ℕ) : Fin.castLE (le_refl n) = id 
goal: Fin.castLE ⋯ = id

full_name: Fin.range_castLE
code: @[simp]
theorem range_castLE {n k : ℕ} (h : n ≤ k) : Set.range (castLE h) = { i : Fin k | (i : ℕ) < n } 
goal: Set.range (Fin.castLE h) = {i | ↑i < n}

full_name: Fin.coe_of_injective_castLE_symm
code: @[simp]
theorem coe_of_injective_castLE_symm {n k : ℕ} (h : n ≤ k) (i : Fin k) (hi) :
    ((Equiv.ofInjective _ (castLE_injective h)).symm ⟨i, hi⟩ : ℕ) = i 
goal: ↑((Equiv.ofInjective (Fin.castLE h) ⋯).symm ⟨i, hi⟩) = ↑i

full_name: Fin.leftInverse_cast
code: theorem leftInverse_cast (eq : n = m) : LeftInverse (cast eq.symm) (cast eq) 
goal: Function.LeftInverse (Fin.cast ⋯) (Fin.cast eq)

full_name: Fin.rightInverse_cast
code: theorem rightInverse_cast (eq : n = m) : RightInverse (cast eq.symm) (cast eq) 
goal: Function.RightInverse (Fin.cast ⋯) (Fin.cast eq)

full_name: Fin.cast_le_cast
code: theorem cast_le_cast (eq : n = m) {a b : Fin n} : cast eq a ≤ cast eq b ↔ a ≤ b 
goal: Fin.cast eq a ≤ Fin.cast eq b ↔ a ≤ b

full_name: finCongr_symm_apply
code: /-- The 'identity' equivalence between `Fin m` and `Fin n` when `m = n`. -/
@[simps]
def _root_.finCongr (eq : n = m) : Fin n ≃ Fin m 
goal: (finCongr eq).symm i = Fin.cast ⋯ i

full_name: finCongr
code: /-- The 'identity' equivalence between `Fin m` and `Fin n` when `m = n`. -/
@[simps]
def _root_.finCongr (eq : n = m) : Fin n ≃ Fin m 
goal: Fin n ≃ Fin m

full_name: finCongr_apply
code: /-- The 'identity' equivalence between `Fin m` and `Fin n` when `m = n`. -/
@[simps]
def _root_.finCongr (eq : n = m) : Fin n ≃ Fin m 
goal: (finCongr eq) i = Fin.cast eq i

full_name: finCongr_apply_mk
code: @[simp] lemma _root_.finCongr_apply_mk (h : m = n) (k : ℕ) (hk : k < m) :
    finCongr h ⟨k, hk⟩ = ⟨k, h ▸ hk⟩ 
goal: (finCongr h) ⟨k, hk⟩ = ⟨k, ⋯⟩

full_name: finCongr_refl
code: @[simp]
lemma _root_.finCongr_refl (h : n = n := rfl) : finCongr h = Equiv.refl (Fin n) 
goal: finCongr h = Equiv.refl (Fin n)

full_name: finCongr_symm
code: @[simp] lemma _root_.finCongr_symm (h : m = n) : (finCongr h).symm = finCongr h.symm 
goal: (finCongr h).symm = finCongr ⋯

full_name: finCongr_apply_coe
code: @[simp] lemma _root_.finCongr_apply_coe (h : m = n) (k : Fin m) : (finCongr h k : ℕ) = k 
goal: ↑((finCongr h) k) = ↑k

full_name: finCongr_symm_apply_coe
code: lemma _root_.finCongr_symm_apply_coe (h : m = n) (k : Fin n) : ((finCongr h).symm k : ℕ) = k 
goal: ↑((finCongr h).symm k) = ↑k

full_name: finCongr_eq_equivCast
code: /-- While in many cases `finCongr` is better than `Equiv.cast`/`cast`, sometimes we want to apply
a generic theorem about `cast`. -/
lemma _root_.finCongr_eq_equivCast (h : n = m) : finCongr h = .cast (h ▸ rfl) 
goal: finCongr h = Equiv.cast ⋯

full_name: Fin.cast_zero
code: @[simp]
theorem cast_zero {n' : ℕ} [NeZero n] {h : n = n'} : cast h (0 : Fin n) =
    by { haveI : NeZero n' := by {rw [← h]; infer_instance}; exact 0} 
goal: Fin.cast h 0 = 0

full_name: Fin.cast_eq_cast
code: /-- While in many cases `Fin.cast` is better than `Equiv.cast`/`cast`, sometimes we want to apply
a generic theorem about `cast`. -/
theorem cast_eq_cast (h : n = m) : (cast h : Fin n → Fin m) = _root_.cast (h ▸ rfl) 
goal: Fin.cast h = cast ⋯

full_name: Fin.castAddEmb
code: /-- `Fin.castAdd` as an `Embedding`, `castAddEmb m i` embeds `i : Fin n` in `Fin (n+m)`.
See also `Fin.natAddEmb` and `Fin.addNatEmb`. -/
@[simps! apply]
def castAddEmb (m) : Fin n ↪ Fin (n + m) 
goal: Fin n ↪ Fin (n + m)

full_name: Fin.castAddEmb_apply
code: /-- `Fin.castAdd` as an `Embedding`, `castAddEmb m i` embeds `i : Fin n` in `Fin (n+m)`.
See also `Fin.natAddEmb` and `Fin.addNatEmb`. -/
@[simps! apply]
def castAddEmb (m) : Fin n ↪ Fin (n + m) 
goal: (Fin.castAddEmb m) i = Fin.castLE ⋯ i

full_name: Fin.castSuccEmb
code: /-- `Fin.castSucc` as an `Embedding`, `castSuccEmb i` embeds `i : Fin n` in `Fin (n+1)`. -/
@[simps! apply]
def castSuccEmb : Fin n ↪ Fin (n + 1) 
goal: Fin n ↪ Fin (n + 1)

full_name: Fin.castSuccEmb_apply
code: /-- `Fin.castSucc` as an `Embedding`, `castSuccEmb i` embeds `i : Fin n` in `Fin (n+1)`. -/
@[simps! apply]
def castSuccEmb : Fin n ↪ Fin (n + 1) 
goal: Fin.castSuccEmb i = Fin.castLE ⋯ i

full_name: Fin.coe_castSuccEmb
code: @[simp, norm_cast] lemma coe_castSuccEmb : (castSuccEmb : Fin n → Fin (n + 1)) = Fin.castSucc 
goal: ⇑Fin.castSuccEmb = Fin.castSucc

full_name: Fin.castSucc_le_castSucc_iff
code: @[simp]
theorem castSucc_le_castSucc_iff {a b : Fin n} : castSucc a ≤ castSucc b ↔ a ≤ b 
goal: a.castSucc ≤ b.castSucc ↔ a ≤ b

full_name: Fin.succ_le_castSucc_iff
code: @[simp]
theorem succ_le_castSucc_iff {a b : Fin n} : succ a ≤ castSucc b ↔ a < b 
goal: a.succ ≤ b.castSucc ↔ a < b

full_name: Fin.castSucc_lt_succ_iff
code: @[simp]
theorem castSucc_lt_succ_iff {a b : Fin n} : castSucc a < succ b ↔ a ≤ b 
goal: a.castSucc < b.succ ↔ a ≤ b

full_name: Fin.le_of_castSucc_lt_of_succ_lt
code: theorem le_of_castSucc_lt_of_succ_lt {a b : Fin (n + 1)} {i : Fin n}
    (hl : castSucc i < a) (hu : b < succ i) : b < a 
goal: b < a

full_name: Fin.castSucc_lt_or_lt_succ
code: theorem castSucc_lt_or_lt_succ (p : Fin (n + 1)) (i : Fin n) : castSucc i < p ∨ p < i.succ 
goal: i.castSucc < p ∨ p < i.succ

full_name: Fin.succ_le_or_le_castSucc
code: theorem succ_le_or_le_castSucc (p : Fin (n + 1)) (i : Fin n) : succ i ≤ p ∨ p ≤ i.castSucc 
goal: i.succ ≤ p ∨ p ≤ i.castSucc

full_name: Fin.exists_castSucc_eq_of_ne_last
code: theorem exists_castSucc_eq_of_ne_last {x : Fin (n + 1)} (h : x ≠ (last _)) :
    ∃ y, Fin.castSucc y = x 
goal: ∃ y, y.castSucc = x

full_name: Fin.forall_fin_succ'
code: theorem forall_fin_succ' {P : Fin (n + 1) → Prop} :
    (∀ i, P i) ↔ (∀ i : Fin n, P i.castSucc) ∧ P (.last _) 
goal: (∀ (i : Fin (n + 1)), P i) ↔ (∀ (i : Fin n), P i.castSucc) ∧ P (Fin.last n)

full_name: Fin.eq_castSucc_or_eq_last
code: theorem eq_castSucc_or_eq_last {n : Nat} (i : Fin (n + 1)) :
    (∃ j : Fin n, i = j.castSucc) ∨ i = last n 
goal: (∃ j, i = j.castSucc) ∨ i = Fin.last n

full_name: Fin.exists_fin_succ'
code: theorem exists_fin_succ' {P : Fin (n + 1) → Prop} :
    (∃ i, P i) ↔ (∃ i : Fin n, P i.castSucc) ∨ P (.last _) 
goal: (∃ i, P i) ↔ (∃ i, P i.castSucc) ∨ P (Fin.last n)

full_name: Fin.castSucc_zero'
code: /--
The `Fin.castSucc_zero` in `Lean` only applies in `Fin (n+1)`.
This one instead uses a `NeZero n` typeclass hypothesis.
-/
@[simp]
theorem castSucc_zero' [NeZero n] : castSucc (0 : Fin n) = 0 
goal: Fin.castSucc 0 = 0

full_name: Fin.castSucc_pos'
code: /-- `castSucc i` is positive when `i` is positive.

The `Fin.castSucc_pos` in `Lean` only applies in `Fin (n+1)`.
This one instead uses a `NeZero n` typeclass hypothesis. -/
theorem castSucc_pos' [NeZero n] {i : Fin n} (h : 0 < i) : 0 < castSucc i 
goal: 0 < i.castSucc

full_name: Fin.castSucc_eq_zero_iff'
code: /--
The `Fin.castSucc_eq_zero_iff` in `Lean` only applies in `Fin (n+1)`.
This one instead uses a `NeZero n` typeclass hypothesis.
-/
@[simp]
theorem castSucc_eq_zero_iff' [NeZero n] (a : Fin n) : castSucc a = 0 ↔ a = 0 
goal: a.castSucc = 0 ↔ a = 0

full_name: Fin.castSucc_ne_zero_iff'
code: /--
The `Fin.castSucc_ne_zero_iff` in `Lean` only applies in `Fin (n+1)`.
This one instead uses a `NeZero n` typeclass hypothesis.
-/
theorem castSucc_ne_zero_iff' [NeZero n] (a : Fin n) : castSucc a ≠ 0 ↔ a ≠ 0 
goal: a.castSucc ≠ 0 ↔ a ≠ 0

full_name: Fin.castSucc_ne_zero_of_lt
code: theorem castSucc_ne_zero_of_lt {p i : Fin n} (h : p < i) : castSucc i ≠ 0 
goal: i.castSucc ≠ 0

full_name: Fin.succ_ne_last_iff
code: theorem succ_ne_last_iff (a : Fin (n + 1)) : succ a ≠ last (n + 1) ↔ a ≠ last n 
goal: a.succ ≠ Fin.last (n + 1) ↔ a ≠ Fin.last n

full_name: Fin.succ_ne_last_of_lt
code: theorem succ_ne_last_of_lt {p i : Fin n} (h : i < p) : succ i ≠ last n 
goal: i.succ ≠ Fin.last n

full_name: Fin.coe_eq_castSucc
code: @[norm_cast, simp]
theorem coe_eq_castSucc {a : Fin n} : (a : Fin (n + 1)) = castSucc a 
goal: ↑↑a = a.castSucc

full_name: Fin.coe_succ_lt_iff_lt
code: theorem coe_succ_lt_iff_lt {n : ℕ} {j k : Fin n} : (j : Fin <| n + 1) < k ↔ j < k 
goal: ↑↑j < ↑↑k ↔ j < k

full_name: Fin.range_castSucc
code: @[simp]
theorem range_castSucc {n : ℕ} : Set.range (castSucc : Fin n → Fin n.succ) =
    ({ i | (i : ℕ) < n } : Set (Fin n.succ)) 
goal: Set.range Fin.castSucc = {i | ↑i < n}

full_name: Fin.coe_of_injective_castSucc_symm
code: @[simp]
theorem coe_of_injective_castSucc_symm {n : ℕ} (i : Fin n.succ) (hi) :
    ((Equiv.ofInjective castSucc (castSucc_injective _)).symm ⟨i, hi⟩ : ℕ) = i 
goal: ↑((Equiv.ofInjective Fin.castSucc ⋯).symm ⟨i, hi⟩) = ↑i

full_name: Fin.addNatEmb
code: /-- `Fin.addNat` as an `Embedding`, `addNatEmb m i` adds `m` to `i`, generalizes `Fin.succ`. -/
@[simps! apply]
def addNatEmb (m) : Fin n ↪ Fin (n + m) 
goal: Fin n ↪ Fin (n + m)

full_name: Fin.addNatEmb_apply
code: /-- `Fin.addNat` as an `Embedding`, `addNatEmb m i` adds `m` to `i`, generalizes `Fin.succ`. -/
@[simps! apply]
def addNatEmb (m) : Fin n ↪ Fin (n + m) 
goal: ∀ (x : Fin n), (Fin.addNatEmb m) x = x.addNat m

full_name: Fin.natAddEmb_apply
code: /-- `Fin.natAdd` as an `Embedding`, `natAddEmb n i` adds `n` to `i` "on the left". -/
@[simps! apply]
def natAddEmb (n) {m} : Fin m ↪ Fin (n + m) 
goal: (Fin.natAddEmb n) i = Fin.natAdd n i

full_name: Fin.natAddEmb
code: /-- `Fin.natAdd` as an `Embedding`, `natAddEmb n i` adds `n` to `i` "on the left". -/
@[simps! apply]
def natAddEmb (n) {m} : Fin m ↪ Fin (n + m) 
goal: Fin m ↪ Fin (n + m)

full_name: Fin.pred_one'
code: theorem pred_one' [NeZero n] (h := (zero_ne_one' (n := n)).symm) :
    Fin.pred (1 : Fin (n + 1)) h = 0 
goal: Fin.pred 1 h = 0

full_name: Fin.pred_last
code: theorem pred_last (h := Fin.ext_iff.not.2 last_pos'.ne') :
    pred (last (n + 1)) h = last n 
goal: (Fin.last (n + 1)).pred h = Fin.last n

full_name: Fin.pred_lt_iff
code: theorem pred_lt_iff {j : Fin n} {i : Fin (n + 1)} (hi : i ≠ 0) : pred i hi < j ↔ i < succ j 
goal: i.pred hi < j ↔ i < j.succ

full_name: Fin.lt_pred_iff
code: theorem lt_pred_iff {j : Fin n} {i : Fin (n + 1)} (hi : i ≠ 0) : j < pred i hi ↔ succ j < i 
goal: j < i.pred hi ↔ j.succ < i

full_name: Fin.pred_le_iff
code: theorem pred_le_iff {j : Fin n} {i : Fin (n + 1)} (hi : i ≠ 0) : pred i hi ≤ j ↔ i ≤ succ j 
goal: i.pred hi ≤ j ↔ i ≤ j.succ

full_name: Fin.le_pred_iff
code: theorem le_pred_iff {j : Fin n} {i : Fin (n + 1)} (hi : i ≠ 0) : j ≤ pred i hi ↔ succ j ≤ i 
goal: j ≤ i.pred hi ↔ j.succ ≤ i

full_name: Fin.castSucc_pred_eq_pred_castSucc
code: theorem castSucc_pred_eq_pred_castSucc {a : Fin (n + 1)} (ha : a ≠ 0)
    (ha' := a.castSucc_ne_zero_iff.mpr ha) :
    (a.pred ha).castSucc = (castSucc a).pred ha' 
goal: (a.pred ha).castSucc = a.castSucc.pred ha'

full_name: Fin.castSucc_pred_add_one_eq
code: theorem castSucc_pred_add_one_eq {a : Fin (n + 1)} (ha : a ≠ 0) :
    (a.pred ha).castSucc + 1 = a 
goal: (a.pred ha).castSucc + 1 = a

full_name: Fin.le_pred_castSucc_iff
code: theorem le_pred_castSucc_iff {a b : Fin (n + 1)} (ha : castSucc a ≠ 0) :
    b ≤ (castSucc a).pred ha ↔ b < a 
goal: b ≤ a.castSucc.pred ha ↔ b < a

full_name: Fin.pred_castSucc_lt_iff
code: theorem pred_castSucc_lt_iff {a b : Fin (n + 1)} (ha : castSucc a ≠ 0) :
    (castSucc a).pred ha < b ↔ a ≤ b 
goal: a.castSucc.pred ha < b ↔ a ≤ b

full_name: Fin.pred_castSucc_lt
code: theorem pred_castSucc_lt {a : Fin (n + 1)} (ha : castSucc a ≠ 0) :
    (castSucc a).pred ha < a 
goal: a.castSucc.pred ha < a

full_name: Fin.le_castSucc_pred_iff
code: theorem le_castSucc_pred_iff {a b : Fin (n + 1)} (ha : a ≠ 0) :
    b ≤ castSucc (a.pred ha) ↔ b < a 
goal: b ≤ (a.pred ha).castSucc ↔ b < a

full_name: Fin.castSucc_pred_lt_iff
code: theorem castSucc_pred_lt_iff {a b : Fin (n + 1)} (ha : a ≠ 0) :
    castSucc (a.pred ha) < b ↔ a ≤ b 
goal: (a.pred ha).castSucc < b ↔ a ≤ b

full_name: Fin.castSucc_pred_lt
code: theorem castSucc_pred_lt {a : Fin (n + 1)} (ha : a ≠ 0) :
    castSucc (a.pred ha) < a 
goal: (a.pred ha).castSucc < a

full_name: Fin.castPred
code: /-- `castPred i` sends `i : Fin (n + 1)` to `Fin n` as long as i ≠ last n. -/
@[inline] def castPred (i : Fin (n + 1)) (h : i ≠ last n) : Fin n 
goal: Fin n

full_name: Fin.castLT_eq_castPred
code: @[simp]
lemma castLT_eq_castPred (i : Fin (n + 1)) (h : i < last _) (h' := Fin.ext_iff.not.2 h.ne) :
    castLT i h = castPred i h' 
goal: i.castLT h = i.castPred h'

full_name: Fin.coe_castPred
code: @[simp]
lemma coe_castPred (i : Fin (n + 1)) (h : i ≠ last _) : (castPred i h : ℕ) = i 
goal: ↑(i.castPred h) = ↑i

full_name: Fin.castPred_castSucc
code: @[simp]
theorem castPred_castSucc {i : Fin n} (h' := Fin.ext_iff.not.2 (castSucc_lt_last i).ne) :
    castPred (castSucc i) h' = i 
goal: i.castSucc.castPred h' = i

full_name: Fin.castSucc_castPred
code: @[simp]
theorem castSucc_castPred (i : Fin (n + 1)) (h : i ≠ last n) :
    castSucc (i.castPred h) = i 
goal: (i.castPred h).castSucc = i

full_name: Fin.castPred_eq_iff_eq_castSucc
code: theorem castPred_eq_iff_eq_castSucc (i : Fin (n + 1)) (hi : i ≠ last _) (j : Fin n) :
    castPred i hi = j ↔ i = castSucc j 
goal: i.castPred hi = j ↔ i = j.castSucc

full_name: Fin.castPred_mk
code: @[simp]
theorem castPred_mk (i : ℕ) (h₁ : i < n) (h₂ := h₁.trans (Nat.lt_succ_self _))
    (h₃ : ⟨i, h₂⟩ ≠ last _ := (ne_iff_vne _ _).mpr (val_last _ ▸ h₁.ne)) :
  castPred ⟨i, h₂⟩ h₃ = ⟨i, h₁⟩ 
goal: ⟨i, h₂⟩.castPred h₃ = ⟨i, h₁⟩

full_name: Fin.castPred_le_castPred_iff
code: theorem castPred_le_castPred_iff {i j : Fin (n + 1)} {hi : i ≠ last n} {hj : j ≠ last n} :
    castPred i hi ≤ castPred j hj ↔ i ≤ j 
goal: i.castPred hi ≤ j.castPred hj ↔ i ≤ j

full_name: Fin.castPred_lt_castPred_iff
code: theorem castPred_lt_castPred_iff {i j : Fin (n + 1)} {hi : i ≠ last n} {hj : j ≠ last n} :
    castPred i hi < castPred j hj ↔ i < j 
goal: i.castPred hi < j.castPred hj ↔ i < j

full_name: Fin.castPred_lt_iff
code: theorem castPred_lt_iff {j : Fin n} {i : Fin (n + 1)} (hi : i ≠ last n) :
    castPred i hi < j ↔ i < castSucc j 
goal: i.castPred hi < j ↔ i < j.castSucc

full_name: Fin.lt_castPred_iff
code: theorem lt_castPred_iff {j : Fin n} {i : Fin (n + 1)} (hi : i ≠ last n) :
    j < castPred i hi ↔ castSucc j < i 
goal: j < i.castPred hi ↔ j.castSucc < i

full_name: Fin.castPred_le_iff
code: theorem castPred_le_iff {j : Fin n} {i : Fin (n + 1)} (hi : i ≠ last n) :
    castPred i hi ≤ j ↔ i ≤ castSucc j 
goal: i.castPred hi ≤ j ↔ i ≤ j.castSucc

full_name: Fin.le_castPred_iff
code: theorem le_castPred_iff {j : Fin n} {i : Fin (n + 1)} (hi : i ≠ last n) :
    j ≤ castPred i hi ↔ castSucc j ≤ i 
goal: j ≤ i.castPred hi ↔ j.castSucc ≤ i

full_name: Fin.castPred_inj
code: theorem castPred_inj {i j : Fin (n + 1)} {hi : i ≠ last n} {hj : j ≠ last n} :
    castPred i hi = castPred j hj ↔ i = j 
goal: i.castPred hi = j.castPred hj ↔ i = j

full_name: Fin.castPred_zero'
code: theorem castPred_zero' [NeZero n] (h := Fin.ext_iff.not.2 last_pos'.ne) :
    castPred (0 : Fin (n + 1)) h = 0 
goal: Fin.castPred 0 h = 0

full_name: Fin.castPred_zero
code: theorem castPred_zero (h := Fin.ext_iff.not.2 last_pos.ne)  :
    castPred (0 : Fin (n + 2)) h = 0 
goal: Fin.castPred 0 h = 0

full_name: Fin.castPred_one
code: @[simp]
theorem castPred_one [NeZero n] (h := Fin.ext_iff.not.2 one_lt_last.ne) :
    castPred (1 : Fin (n + 2)) h = 1 
goal: Fin.castPred 1 h = 1

full_name: Fin.rev_pred
code: theorem rev_pred {i : Fin (n + 1)} (h : i ≠ 0) (h' := rev_ne_iff.mpr ((rev_last _).symm ▸ h)) :
    rev (pred i h) = castPred (rev i) h' 
goal: (i.pred h).rev = i.rev.castPred h'

full_name: Fin.rev_castPred
code: theorem rev_castPred {i : Fin (n + 1)}
    (h : i ≠ last n) (h' := rev_ne_iff.mpr ((rev_zero _).symm ▸ h)) :
    rev (castPred i h) = pred (rev i) h' 
goal: (i.castPred h).rev = i.rev.pred h'

full_name: Fin.succ_castPred_eq_castPred_succ
code: theorem succ_castPred_eq_castPred_succ {a : Fin (n + 1)} (ha : a ≠ last n)
    (ha' := a.succ_ne_last_iff.mpr ha) :
    (a.castPred ha).succ = (succ a).castPred ha' 
goal: (a.castPred ha).succ = a.succ.castPred ha'

full_name: Fin.succ_castPred_eq_add_one
code: theorem succ_castPred_eq_add_one {a : Fin (n + 1)} (ha : a ≠ last n) :
    (a.castPred ha).succ = a + 1 
goal: (a.castPred ha).succ = a + 1

full_name: Fin.castpred_succ_le_iff
code: theorem castpred_succ_le_iff {a b : Fin (n + 1)} (ha : succ a ≠ last (n + 1)) :
    (succ a).castPred ha ≤ b ↔ a < b 
goal: a.succ.castPred ha ≤ b ↔ a < b

full_name: Fin.lt_castPred_succ_iff
code: theorem lt_castPred_succ_iff {a b : Fin (n + 1)} (ha : succ a ≠ last (n + 1)) :
    b < (succ a).castPred ha ↔ b ≤ a 
goal: b < a.succ.castPred ha ↔ b ≤ a

full_name: Fin.lt_castPred_succ
code: theorem lt_castPred_succ {a : Fin (n + 1)} (ha : succ a ≠ last (n + 1)) :
    a < (succ a).castPred ha 
goal: a < a.succ.castPred ha

full_name: Fin.succ_castPred_le_iff
code: theorem succ_castPred_le_iff {a b : Fin (n + 1)} (ha : a ≠ last n) :
    succ (a.castPred ha) ≤ b ↔ a < b 
goal: (a.castPred ha).succ ≤ b ↔ a < b

full_name: Fin.lt_succ_castPred_iff
code: theorem lt_succ_castPred_iff {a b : Fin (n + 1)} (ha : a ≠ last n) :
    b < succ (a.castPred ha) ↔ b ≤ a 
goal: b < (a.castPred ha).succ ↔ b ≤ a

full_name: Fin.lt_succ_castPred
code: theorem lt_succ_castPred {a : Fin (n + 1)} (ha : a ≠ last n) :
    a < succ (a.castPred ha) 
goal: a < (a.castPred ha).succ

full_name: Fin.castPred_le_pred_iff
code: theorem castPred_le_pred_iff {a b : Fin (n + 1)} (ha : a ≠ last n) (hb : b ≠ 0) :
    castPred a ha ≤ pred b hb ↔ a < b 
goal: a.castPred ha ≤ b.pred hb ↔ a < b

full_name: Fin.pred_lt_castPred_iff
code: theorem pred_lt_castPred_iff {a b : Fin (n + 1)} (ha : a ≠ 0) (hb : b ≠ last n) :
    pred a ha < castPred b hb ↔ a ≤ b 
goal: a.pred ha < b.castPred hb ↔ a ≤ b

full_name: Fin.pred_lt_castPred
code: theorem pred_lt_castPred {a : Fin (n + 1)} (h₁ : a ≠ 0) (h₂ : a ≠ last n) :
    pred a h₁ < castPred a h₂ 
goal: a.pred h₁ < a.castPred h₂

full_name: Fin.succAbove
code: /-- `succAbove p i` embeds `Fin n` into `Fin (n + 1)` with a hole around `p`. -/
def succAbove (p : Fin (n + 1)) (i : Fin n) : Fin (n + 1) 
goal: Fin (n + 1)

full_name: Fin.succAbove_of_castSucc_lt
code: /-- Embedding `i : Fin n` into `Fin (n + 1)` with a hole around `p : Fin (n + 1)`
embeds `i` by `castSucc` when the resulting `i.castSucc < p`. -/
lemma succAbove_of_castSucc_lt (p : Fin (n + 1)) (i : Fin n) (h : castSucc i < p) :
    p.succAbove i = castSucc i 
goal: p.succAbove i = i.castSucc

full_name: Fin.succAbove_of_succ_le
code: lemma succAbove_of_succ_le (p : Fin (n + 1)) (i : Fin n) (h : succ i ≤ p) :
    p.succAbove i = castSucc i 
goal: p.succAbove i = i.castSucc

full_name: Fin.succAbove_of_le_castSucc
code: /-- Embedding `i : Fin n` into `Fin (n + 1)` with a hole around `p : Fin (n + 1)`
embeds `i` by `succ` when the resulting `p < i.succ`. -/
lemma succAbove_of_le_castSucc (p : Fin (n + 1)) (i : Fin n) (h : p ≤ castSucc i) :
    p.succAbove i = i.succ 
goal: p.succAbove i = i.succ

full_name: Fin.succAbove_of_lt_succ
code: lemma succAbove_of_lt_succ (p : Fin (n + 1)) (i : Fin n) (h : p < succ i) :
    p.succAbove i = succ i 
goal: p.succAbove i = i.succ

full_name: Fin.succAbove_succ_of_lt
code: lemma succAbove_succ_of_lt (p i : Fin n) (h : p < i) : succAbove p.succ i = i.succ 
goal: p.succ.succAbove i = i.succ

full_name: Fin.succAbove_succ_of_le
code: lemma succAbove_succ_of_le (p i : Fin n) (h : i ≤ p) : succAbove p.succ i = i.castSucc 
goal: p.succ.succAbove i = i.castSucc

full_name: Fin.succAbove_succ_self
code: @[simp] lemma succAbove_succ_self (j : Fin n) : j.succ.succAbove j = j.castSucc 
goal: j.succ.succAbove j = j.castSucc

full_name: Fin.succAbove_castSucc_of_lt
code: lemma succAbove_castSucc_of_lt (p i : Fin n) (h : i < p) : succAbove p.castSucc i = i.castSucc 
goal: p.castSucc.succAbove i = i.castSucc

full_name: Fin.succAbove_castSucc_of_le
code: lemma succAbove_castSucc_of_le (p i : Fin n) (h : p ≤ i) : succAbove p.castSucc i = i.succ 
goal: p.castSucc.succAbove i = i.succ

full_name: Fin.succAbove_castSucc_self
code: @[simp] lemma succAbove_castSucc_self (j : Fin n) : succAbove j.castSucc j = j.succ 
goal: j.castSucc.succAbove j = j.succ

full_name: Fin.succAbove_pred_of_lt
code: lemma succAbove_pred_of_lt (p i : Fin (n + 1)) (h : p < i)
    (hi := Fin.ne_of_gt $ Fin.lt_of_le_of_lt p.zero_le h) : succAbove p (i.pred hi) = i 
goal: p.succAbove (i.pred hi) = i

full_name: Fin.succAbove_pred_of_le
code: lemma succAbove_pred_of_le (p i : Fin (n + 1)) (h : i ≤ p) (hi : i ≠ 0) :
    succAbove p (i.pred hi) = (i.pred hi).castSucc 
goal: p.succAbove (i.pred hi) = (i.pred hi).castSucc

full_name: Fin.succAbove_pred_self
code: @[simp] lemma succAbove_pred_self (p : Fin (n + 1)) (h : p ≠ 0) :
    succAbove p (p.pred h) = (p.pred h).castSucc 
goal: p.succAbove (p.pred h) = (p.pred h).castSucc

full_name: Fin.succAbove_castPred_of_lt
code: lemma succAbove_castPred_of_lt (p i : Fin (n + 1)) (h : i < p)
    (hi := Fin.ne_of_lt $ Nat.lt_of_lt_of_le h p.le_last) : succAbove p (i.castPred hi) = i 
goal: p.succAbove (i.castPred hi) = i

full_name: Fin.succAbove_castPred_of_le
code: lemma succAbove_castPred_of_le (p i : Fin (n + 1)) (h : p ≤ i) (hi : i ≠ last n) :
    succAbove p (i.castPred hi) = (i.castPred hi).succ 
goal: p.succAbove (i.castPred hi) = (i.castPred hi).succ

full_name: Fin.succAbove_castPred_self
code: lemma succAbove_castPred_self (p : Fin (n + 1)) (h : p ≠ last n) :
    succAbove p (p.castPred h) = (p.castPred h).succ 
goal: p.succAbove (p.castPred h) = (p.castPred h).succ

full_name: Fin.succAbove_rev_left
code: lemma succAbove_rev_left (p : Fin (n + 1)) (i : Fin n) :
    p.rev.succAbove i = (p.succAbove i.rev).rev 
goal: p.rev.succAbove i = (p.succAbove i.rev).rev

full_name: Fin.succAbove_rev_right
code: lemma succAbove_rev_right (p : Fin (n + 1)) (i : Fin n) :
    p.succAbove i.rev = (p.rev.succAbove i).rev 
goal: p.succAbove i.rev = (p.rev.succAbove i).rev

full_name: Fin.succAbove_ne
code: /-- Embedding `i : Fin n` into `Fin (n + 1)` with a hole around `p : Fin (n + 1)`
never results in `p` itself -/
lemma succAbove_ne (p : Fin (n + 1)) (i : Fin n) : p.succAbove i ≠ p 
goal: p.succAbove i ≠ p

full_name: Fin.ne_succAbove
code: lemma ne_succAbove (p : Fin (n + 1)) (i : Fin n) : p ≠ p.succAbove i 
goal: p ≠ p.succAbove i

full_name: Fin.succAbove_right_injective
code: /-- Given a fixed pivot `p : Fin (n + 1)`, `p.succAbove` is injective. -/
lemma succAbove_right_injective : Injective p.succAbove 
goal: Function.Injective p.succAbove

full_name: Fin.succAbove_right_inj
code: /-- Given a fixed pivot `p : Fin (n + 1)`, `p.succAbove` is injective. -/
lemma succAbove_right_inj : p.succAbove i = p.succAbove j ↔ i = j 
goal: p.succAbove i = p.succAbove j ↔ i = j

full_name: Fin.succAboveEmb_apply
code: /--  `Fin.succAbove p` as an `Embedding`. -/
@[simps!]
def succAboveEmb (p : Fin (n + 1)) : Fin n ↪ Fin (n + 1) 
goal: p.succAboveEmb i = p.succAbove i

full_name: Fin.succAboveEmb
code: /--  `Fin.succAbove p` as an `Embedding`. -/
@[simps!]
def succAboveEmb (p : Fin (n + 1)) : Fin n ↪ Fin (n + 1) 
goal: Fin n ↪ Fin (n + 1)

full_name: Fin.coe_succAboveEmb
code: @[simp, norm_cast] lemma coe_succAboveEmb (p : Fin (n + 1)) : p.succAboveEmb = p.succAbove 
goal: ⇑p.succAboveEmb = p.succAbove

full_name: Fin.succAbove_ne_zero_zero
code: @[simp]
lemma succAbove_ne_zero_zero [NeZero n] {a : Fin (n + 1)} (ha : a ≠ 0) : a.succAbove 0 = 0 
goal: a.succAbove 0 = 0

full_name: Fin.succAbove_eq_zero_iff
code: lemma succAbove_eq_zero_iff [NeZero n] {a : Fin (n + 1)} {b : Fin n} (ha : a ≠ 0) :
    a.succAbove b = 0 ↔ b = 0 
goal: a.succAbove b = 0 ↔ b = 0

full_name: Fin.succAbove_ne_zero
code: lemma succAbove_ne_zero [NeZero n] {a : Fin (n + 1)} {b : Fin n} (ha : a ≠ 0) (hb : b ≠ 0) :
    a.succAbove b ≠ 0 
goal: a.succAbove b ≠ 0

full_name: Fin.succAbove_zero
code: /-- Embedding `Fin n` into `Fin (n + 1)` with a hole around zero embeds by `succ`. -/
@[simp] lemma succAbove_zero : succAbove (0 : Fin (n + 1)) = Fin.succ 
goal: Fin.succAbove 0 = Fin.succ

full_name: Fin.succAbove_zero_apply
code: lemma succAbove_zero_apply (i : Fin n) : succAbove 0 i = succ i 
goal: Fin.succAbove 0 i = i.succ

full_name: Fin.succAbove_ne_last_last
code: @[simp] lemma succAbove_ne_last_last {a : Fin (n + 2)} (h : a ≠ last (n + 1)) :
    a.succAbove (last n) = last (n + 1) 
goal: a.succAbove (Fin.last n) = Fin.last (n + 1)

full_name: Fin.succAbove_eq_last_iff
code: lemma succAbove_eq_last_iff {a : Fin (n + 2)} {b : Fin (n + 1)} (ha : a ≠ last _) :
    a.succAbove b = last _ ↔ b = last _ 
goal: a.succAbove b = Fin.last (n + 1) ↔ b = Fin.last n

full_name: Fin.succAbove_ne_last
code: lemma succAbove_ne_last {a : Fin (n + 2)} {b : Fin (n + 1)} (ha : a ≠ last _) (hb : b ≠ last _) :
    a.succAbove b ≠ last _ 
goal: a.succAbove b ≠ Fin.last (n + 1)

full_name: Fin.succAbove_last
code: /-- Embedding `Fin n` into `Fin (n + 1)` with a hole around `last n` embeds by `castSucc`. -/
@[simp] lemma succAbove_last : succAbove (last n) = castSucc 
goal: (Fin.last n).succAbove = Fin.castSucc

full_name: Fin.succAbove_last_apply
code: lemma succAbove_last_apply (i : Fin n) : succAbove (last n) i = castSucc i 
goal: (Fin.last n).succAbove i = i.castSucc

full_name: Fin.succAbove_lt_ge
code: @[deprecated (since := "2024-05-30")]
lemma succAbove_lt_ge (p : Fin (n + 1)) (i : Fin n) :
    castSucc i < p ∨ p ≤ castSucc i 
goal: i.castSucc < p ∨ p ≤ i.castSucc

full_name: Fin.succAbove_lt_iff_castSucc_lt
code: /-- Embedding `i : Fin n` into `Fin (n + 1)` using a pivot `p` that is greater
results in a value that is less than `p`. -/
lemma succAbove_lt_iff_castSucc_lt (p : Fin (n + 1)) (i : Fin n) :
    p.succAbove i < p ↔ castSucc i < p 
goal: p.succAbove i < p ↔ i.castSucc < p

full_name: Fin.succAbove_lt_iff_succ_le
code: lemma succAbove_lt_iff_succ_le (p : Fin (n + 1)) (i : Fin n) :
    p.succAbove i < p ↔ succ i ≤ p 
goal: p.succAbove i < p ↔ i.succ ≤ p

full_name: Fin.lt_succAbove_iff_le_castSucc
code: /-- Embedding `i : Fin n` into `Fin (n + 1)` using a pivot `p` that is lesser
results in a value that is greater than `p`. -/
lemma lt_succAbove_iff_le_castSucc (p : Fin (n + 1)) (i : Fin n) :
    p < p.succAbove i ↔ p ≤ castSucc i 
goal: p < p.succAbove i ↔ p ≤ i.castSucc

full_name: Fin.lt_succAbove_iff_lt_castSucc
code: lemma lt_succAbove_iff_lt_castSucc (p : Fin (n + 1)) (i : Fin n) :
    p < p.succAbove i ↔ p < succ i 
goal: p < p.succAbove i ↔ p < i.succ

full_name: Fin.succAbove_pos
code: /-- Embedding a positive `Fin n` results in a positive `Fin (n + 1)` -/
lemma succAbove_pos [NeZero n] (p : Fin (n + 1)) (i : Fin n) (h : 0 < i) : 0 < p.succAbove i 
goal: 0 < p.succAbove i

full_name: Fin.castPred_succAbove
code: lemma castPred_succAbove (x : Fin n) (y : Fin (n + 1)) (h : castSucc x < y)
    (h' := Fin.ne_last_of_lt $ (succAbove_lt_iff_castSucc_lt ..).2 h) :
    (y.succAbove x).castPred h' = x 
goal: (y.succAbove x).castPred h' = x

full_name: Fin.pred_succAbove
code: lemma pred_succAbove (x : Fin n) (y : Fin (n + 1)) (h : y ≤ castSucc x)
    (h' := Fin.ne_zero_of_lt $ (lt_succAbove_iff_le_castSucc ..).2 h) :
    (y.succAbove x).pred h' = x 
goal: (y.succAbove x).pred h' = x

full_name: Fin.exists_succAbove_eq
code: lemma exists_succAbove_eq {x y : Fin (n + 1)} (h : x ≠ y) : ∃ z, y.succAbove z = x 
goal: ∃ z, y.succAbove z = x

full_name: Fin.exists_succAbove_eq_iff
code: @[simp] lemma exists_succAbove_eq_iff {x y : Fin (n + 1)} : (∃ z, x.succAbove z = y) ↔ y ≠ x 
goal: (∃ z, x.succAbove z = y) ↔ y ≠ x

full_name: Fin.range_succAbove
code: /-- The range of `p.succAbove` is everything except `p`. -/
@[simp] lemma range_succAbove (p : Fin (n + 1)) : Set.range p.succAbove = {p}ᶜ 
goal: Set.range p.succAbove = {p}ᶜ

full_name: Fin.range_succ
code: @[simp] lemma range_succ (n : ℕ) : Set.range (Fin.succ : Fin n → Fin (n + 1)) = {0}ᶜ 
goal: Set.range Fin.succ = {0}ᶜ

full_name: Fin.succAbove_left_injective
code: /-- `succAbove` is injective at the pivot -/
lemma succAbove_left_injective : Injective (@succAbove n) 
goal: Function.Injective Fin.succAbove

full_name: Fin.succAbove_left_inj
code: /-- `succAbove` is injective at the pivot -/
@[simp] lemma succAbove_left_inj {x y : Fin (n + 1)} : x.succAbove = y.succAbove ↔ x = y 
goal: x.succAbove = y.succAbove ↔ x = y

full_name: Fin.zero_succAbove
code: @[simp] lemma zero_succAbove {n : ℕ} (i : Fin n) : (0 : Fin (n + 1)).succAbove i = i.succ 
goal: Fin.succAbove 0 i = i.succ

full_name: Fin.succ_succAbove_zero
code: @[simp] lemma succ_succAbove_zero {n : ℕ} [NeZero n] (i : Fin n) : succAbove i.succ 0 = 0 
goal: i.succ.succAbove 0 = 0

full_name: Fin.succ_succAbove_succ
code: /-- `succ` commutes with `succAbove`. -/
@[simp] lemma succ_succAbove_succ {n : ℕ} (i : Fin (n + 1)) (j : Fin n) :
    i.succ.succAbove j.succ = (i.succAbove j).succ 
goal: i.succ.succAbove j.succ = (i.succAbove j).succ

full_name: Fin.castSucc_succAbove_castSucc
code: /-- `castSucc` commutes with `succAbove`. -/
@[simp]
lemma castSucc_succAbove_castSucc {n : ℕ} {i : Fin (n + 1)} {j : Fin n} :
    i.castSucc.succAbove j.castSucc = (i.succAbove j).castSucc 
goal: i.castSucc.succAbove j.castSucc = (i.succAbove j).castSucc

full_name: Fin.pred_succAbove_pred
code: /-- `pred` commutes with `succAbove`. -/
lemma pred_succAbove_pred {a : Fin (n + 2)} {b : Fin (n + 1)} (ha : a ≠ 0) (hb : b ≠ 0)
    (hk := succAbove_ne_zero ha hb) :
    (a.pred ha).succAbove (b.pred hb) = (a.succAbove b).pred hk 
goal: (a.pred ha).succAbove (b.pred hb) = (a.succAbove b).pred hk

full_name: Fin.castPred_succAbove_castPred
code: /-- `castPred` commutes with `succAbove`. -/
lemma castPred_succAbove_castPred {a : Fin (n + 2)} {b : Fin (n + 1)} (ha : a ≠ last (n + 1))
    (hb : b ≠ last n) (hk := succAbove_ne_last ha hb) :
    (a.castPred ha).succAbove (b.castPred hb) = (a.succAbove b).castPred hk 
goal: (a.castPred ha).succAbove (b.castPred hb) = (a.succAbove b).castPred hk

full_name: Fin.rev_succAbove
code: /-- `rev` commutes with `succAbove`. -/
lemma rev_succAbove (p : Fin (n + 1)) (i : Fin n) :
    rev (succAbove p i) = succAbove (rev p) (rev i) 
goal: (p.succAbove i).rev = p.rev.succAbove i.rev

full_name: Fin.one_succAbove_zero
code: lemma one_succAbove_zero {n : ℕ} : (1 : Fin (n + 2)).succAbove 0 = 0 
goal: Fin.succAbove 1 0 = 0

full_name: Fin.succ_succAbove_one
code: /-- By moving `succ` to the outside of this expression, we create opportunities for further
simplification using `succAbove_zero` or `succ_succAbove_zero`. -/
@[simp] lemma succ_succAbove_one {n : ℕ} [NeZero n] (i : Fin (n + 1)) :
    i.succ.succAbove 1 = (i.succAbove 0).succ 
goal: i.succ.succAbove 1 = (i.succAbove 0).succ

full_name: Fin.one_succAbove_succ
code: @[simp] lemma one_succAbove_succ {n : ℕ} (j : Fin n) :
    (1 : Fin (n + 2)).succAbove j.succ = j.succ.succ 
goal: Fin.succAbove 1 j.succ = j.succ.succ

full_name: Fin.one_succAbove_one
code: @[simp] lemma one_succAbove_one {n : ℕ} : (1 : Fin (n + 3)).succAbove 1 = 2 
goal: Fin.succAbove 1 1 = 2

full_name: Fin.predAbove
code: /-- `predAbove p i` surjects `i : Fin (n+1)` into `Fin n` by subtracting one if `p < i`. -/
def predAbove (p : Fin n) (i : Fin (n + 1)) : Fin n 
goal: Fin n

full_name: Fin.predAbove_of_le_castSucc
code: lemma predAbove_of_le_castSucc (p : Fin n) (i : Fin (n + 1)) (h : i ≤ castSucc p)
    (hi := Fin.ne_of_lt $ Fin.lt_of_le_of_lt h $ castSucc_lt_last _) :
    p.predAbove i = i.castPred hi 
goal: p.predAbove i = i.castPred hi

full_name: Fin.predAbove_of_lt_succ
code: lemma predAbove_of_lt_succ (p : Fin n) (i : Fin (n + 1)) (h : i < succ p)
    (hi := Fin.ne_last_of_lt h) : p.predAbove i = i.castPred hi 
goal: p.predAbove i = i.castPred hi

full_name: Fin.predAbove_of_castSucc_lt
code: lemma predAbove_of_castSucc_lt (p : Fin n) (i : Fin (n + 1)) (h : castSucc p < i)
    (hi := Fin.ne_zero_of_lt h) : p.predAbove i = i.pred hi 
goal: p.predAbove i = i.pred hi

full_name: Fin.predAbove_of_succ_le
code: lemma predAbove_of_succ_le (p : Fin n) (i : Fin (n + 1)) (h : succ p ≤ i)
    (hi := Fin.ne_of_gt $ Fin.lt_of_lt_of_le (succ_pos _) h) :
    p.predAbove i = i.pred hi 
goal: p.predAbove i = i.pred hi

full_name: Fin.predAbove_succ_of_lt
code: lemma predAbove_succ_of_lt (p i : Fin n) (h : i < p) (hi := succ_ne_last_of_lt h) :
    p.predAbove (succ i) = (i.succ).castPred hi 
goal: p.predAbove i.succ = i.succ.castPred hi

full_name: Fin.predAbove_succ_of_le
code: lemma predAbove_succ_of_le (p i : Fin n) (h : p ≤ i) : p.predAbove (succ i) = i 
goal: p.predAbove i.succ = i

full_name: Fin.predAbove_succ_self
code: @[simp] lemma predAbove_succ_self (p : Fin n) : p.predAbove (succ p) = p 
goal: p.predAbove p.succ = p

full_name: Fin.predAbove_castSucc_of_lt
code: lemma predAbove_castSucc_of_lt (p i : Fin n) (h : p < i) (hi := castSucc_ne_zero_of_lt h) :
    p.predAbove (castSucc i) = i.castSucc.pred hi 
goal: p.predAbove i.castSucc = i.castSucc.pred hi

full_name: Fin.predAbove_castSucc_of_le
code: lemma predAbove_castSucc_of_le (p i : Fin n) (h : i ≤ p) : p.predAbove (castSucc i) = i 
goal: p.predAbove i.castSucc = i

full_name: Fin.predAbove_castSucc_self
code: @[simp] lemma predAbove_castSucc_self (p : Fin n) : p.predAbove (castSucc p) = p 
goal: p.predAbove p.castSucc = p

full_name: Fin.predAbove_pred_of_lt
code: lemma predAbove_pred_of_lt (p i : Fin (n + 1)) (h : i < p) (hp := Fin.ne_zero_of_lt h)
    (hi := Fin.ne_last_of_lt h) : (pred p hp).predAbove i = castPred i hi 
goal: (p.pred hp).predAbove i = i.castPred hi

full_name: Fin.predAbove_pred_of_le
code: lemma predAbove_pred_of_le (p i : Fin (n + 1)) (h : p ≤ i) (hp : p ≠ 0)
    (hi := Fin.ne_of_gt $ Fin.lt_of_lt_of_le (Fin.pos_iff_ne_zero.2 hp) h) :
  (pred p hp).predAbove i = pred i hi 
goal: (p.pred hp).predAbove i = i.pred hi

full_name: Fin.predAbove_pred_self
code: lemma predAbove_pred_self (p : Fin (n + 1)) (hp : p ≠ 0) : (pred p hp).predAbove p = pred p hp 
goal: (p.pred hp).predAbove p = p.pred hp

full_name: Fin.predAbove_castPred_of_lt
code: lemma predAbove_castPred_of_lt (p i : Fin (n + 1)) (h : p < i) (hp := Fin.ne_last_of_lt h)
  (hi := Fin.ne_zero_of_lt h) : (castPred p hp).predAbove i = pred i hi 
goal: (p.castPred hp).predAbove i = i.pred hi

full_name: Fin.predAbove_castPred_of_le
code: lemma predAbove_castPred_of_le (p i : Fin (n + 1)) (h : i ≤ p) (hp : p ≠ last n)
    (hi := Fin.ne_of_lt $ Fin.lt_of_le_of_lt h $ Fin.lt_last_iff_ne_last.2 hp) :
    (castPred p hp).predAbove i = castPred i hi 
goal: (p.castPred hp).predAbove i = i.castPred hi

full_name: Fin.predAbove_castPred_self
code: lemma predAbove_castPred_self (p : Fin (n + 1)) (hp : p ≠ last n) :
    (castPred p hp).predAbove p = castPred p hp 
goal: (p.castPred hp).predAbove p = p.castPred hp

full_name: Fin.predAbove_rev_left
code: lemma predAbove_rev_left (p : Fin n) (i : Fin (n + 1)) :
    p.rev.predAbove i = (p.predAbove i.rev).rev 
goal: p.rev.predAbove i = (p.predAbove i.rev).rev

full_name: Fin.predAbove_rev_right
code: lemma predAbove_rev_right (p : Fin n) (i : Fin (n + 1)) :
    p.predAbove i.rev = (p.rev.predAbove i).rev 
goal: p.predAbove i.rev = (p.rev.predAbove i).rev

full_name: Fin.predAbove_right_zero
code: @[simp] lemma predAbove_right_zero [NeZero n] {i : Fin n} : predAbove (i : Fin n) 0 = 0 
goal: i.predAbove 0 = 0

full_name: Fin.predAbove_zero_succ
code: @[simp] lemma predAbove_zero_succ [NeZero n] {i : Fin n} : predAbove 0 i.succ = i 
goal: Fin.predAbove 0 i.succ = i

full_name: Fin.succ_predAbove_zero
code: @[simp]
lemma succ_predAbove_zero [NeZero n] {j : Fin (n + 1)} (h : j ≠ 0) : succ (predAbove 0 j) = j 
goal: (Fin.predAbove 0 j).succ = j

full_name: Fin.predAbove_zero_of_ne_zero
code: @[simp] lemma predAbove_zero_of_ne_zero [NeZero n] {i : Fin (n + 1)} (hi : i ≠ 0) :
    predAbove 0 i = i.pred hi 
goal: Fin.predAbove 0 i = i.pred hi

full_name: Fin.predAbove_zero
code: lemma predAbove_zero [NeZero n] {i : Fin (n + 1)} :
    predAbove (0 : Fin n) i = if hi : i = 0 then 0 else i.pred hi 
goal: Fin.predAbove 0 i = if hi : i = 0 then 0 else i.pred hi

full_name: Fin.predAbove_right_last
code: @[simp] lemma predAbove_right_last {i : Fin (n + 1)} : predAbove i (last (n + 1)) = last n 
goal: i.predAbove (Fin.last (n + 1)) = Fin.last n

full_name: Fin.predAbove_last_castSucc
code: @[simp] lemma predAbove_last_castSucc {i : Fin (n + 1)} : predAbove (last n) (i.castSucc) = i 
goal: (Fin.last n).predAbove i.castSucc = i

full_name: Fin.predAbove_last_of_ne_last
code: @[simp] lemma predAbove_last_of_ne_last {i : Fin (n + 2)} (hi : i ≠ last (n + 1)) :
    predAbove (last n) i = castPred i hi 
goal: (Fin.last n).predAbove i = i.castPred hi

full_name: Fin.predAbove_last_apply
code: lemma predAbove_last_apply {i : Fin (n + 2)} :
    predAbove (last n) i = if hi : i = last _ then last _ else i.castPred hi 
goal: (Fin.last n).predAbove i = if hi : i = Fin.last (n + 1) then Fin.last n else i.castPred hi

full_name: Fin.succAbove_predAbove
code: /-- Sending `Fin (n+1)` to `Fin n` by subtracting one from anything above `p`
then back to `Fin (n+1)` with a gap around `p` is the identity away from `p`. -/
@[simp]
lemma succAbove_predAbove {p : Fin n} {i : Fin (n + 1)} (h : i ≠ castSucc p) :
    p.castSucc.succAbove (p.predAbove i) = i 
goal: p.castSucc.succAbove (p.predAbove i) = i

full_name: Fin.predAbove_succAbove
code: /-- Sending `Fin n` into `Fin (n + 1)` with a gap at `p`
then back to `Fin n` by subtracting one from anything above `p` is the identity. -/
@[simp]
lemma predAbove_succAbove (p : Fin n) (i : Fin n) : p.predAbove ((castSucc p).succAbove i) = i 
goal: p.predAbove (p.castSucc.succAbove i) = i

full_name: Fin.succ_predAbove_succ
code: /-- `succ` commutes with `predAbove`. -/
@[simp] lemma succ_predAbove_succ (a : Fin n) (b : Fin (n + 1)) :
    a.succ.predAbove b.succ = (a.predAbove b).succ 
goal: a.succ.predAbove b.succ = (a.predAbove b).succ

full_name: Fin.castSucc_predAbove_castSucc
code: /-- `castSucc` commutes with `predAbove`. -/
@[simp] lemma castSucc_predAbove_castSucc {n : ℕ} (a : Fin n) (b : Fin (n + 1)) :
    a.castSucc.predAbove b.castSucc = (a.predAbove b).castSucc 
goal: a.castSucc.predAbove b.castSucc = (a.predAbove b).castSucc

full_name: Fin.rev_predAbove
code: /-- `rev` commutes with `predAbove`. -/
lemma rev_predAbove {n : ℕ} (p : Fin n) (i : Fin (n + 1)) :
    (predAbove p i).rev = predAbove p.rev i.rev 
goal: (p.predAbove i).rev = p.rev.predAbove i.rev

full_name: Fin.divNat
code: /-- Compute `i / n`, where `n` is a `Nat` and inferred the type of `i`. -/
def divNat (i : Fin (m * n)) : Fin m 
goal: Fin m

full_name: Fin.coe_divNat
code: @[simp]
theorem coe_divNat (i : Fin (m * n)) : (i.divNat : ℕ) = i / n 
goal: ↑i.divNat = ↑i / n

full_name: Fin.modNat
code: /-- Compute `i % n`, where `n` is a `Nat` and inferred the type of `i`. -/
def modNat (i : Fin (m * n)) : Fin n 
goal: Fin n

full_name: Fin.coe_modNat
code: @[simp]
theorem coe_modNat (i : Fin (m * n)) : (i.modNat : ℕ) = i % n 
goal: ↑i.modNat = ↑i % n

full_name: Fin.modNat_rev
code: theorem modNat_rev (i : Fin (m * n)) : i.rev.modNat = i.modNat.rev 
goal: i.rev.modNat = i.modNat.rev

full_name: Fin.liftFun_iff_succ
code: theorem liftFun_iff_succ {α : Type*} (r : α → α → Prop) [IsTrans α r] {f : Fin (n + 1) → α} :
    ((· < ·) ⇒ r) f f ↔ ∀ i : Fin n, r (f (castSucc i)) (f i.succ) 
goal: ((fun x x_1 => x < x_1) ⇒ r) f f ↔ ∀ (i : Fin n), r (f i.castSucc) (f i.succ)

full_name: Fin.neg
code: /-- Negation on `Fin n` -/
instance neg (n : ℕ) : Neg (Fin n) 
goal: Neg (Fin n)

full_name: Fin.neg_def
code: theorem neg_def (a : Fin n) : -a = ⟨(n - a) % n, Nat.mod_lt _ a.pos⟩ 
goal: -a = ⟨(n - ↑a) % n, ⋯⟩

full_name: Fin.coe_neg
code: protected theorem coe_neg (a : Fin n) : ((-a : Fin n) : ℕ) = (n - a) % n 
goal: ↑(-a) = (n - ↑a) % n

full_name: Fin.eq_zero
code: theorem eq_zero (n : Fin 1) : n = 0 
goal: n = 0

full_name: Fin.uniqueFinOne
code: instance uniqueFinOne : Unique (Fin 1) 
goal: Unique (Fin 1)

full_name: Fin.coe_fin_one
code: @[simp]
theorem coe_fin_one (a : Fin 1) : (a : ℕ) = 0 
goal: ↑a = 0

full_name: Fin.eq_one_of_neq_zero
code: lemma eq_one_of_neq_zero (i : Fin 2) (hi : i ≠ 0) : i = 1 
goal: i = 1

full_name: Fin.coe_neg_one
code: @[simp]
theorem coe_neg_one : ↑(-1 : Fin (n + 1)) = n 
goal: ↑(-1) = n

full_name: Fin.last_sub
code: theorem last_sub (i : Fin (n + 1)) : last n - i = Fin.rev i 
goal: Fin.last n - i = i.rev

full_name: Fin.add_one_le_of_lt
code: theorem add_one_le_of_lt {n : ℕ} {a b : Fin (n + 1)} (h : a < b) : a + 1 ≤ b 
goal: a + 1 ≤ b

full_name: Fin.exists_eq_add_of_le
code: theorem exists_eq_add_of_le {n : ℕ} {a b : Fin n} (h : a ≤ b) : ∃ k ≤ b, b = a + k 
goal: ∃ k ≤ b, b = a + k

full_name: Fin.exists_eq_add_of_lt
code: theorem exists_eq_add_of_lt {n : ℕ} {a b : Fin (n + 1)} (h : a < b) :
    ∃ k < b, k + 1 ≤ b ∧ b = a + k + 1 
goal: ∃ k < b, k + 1 ≤ b ∧ b = a + k + 1

full_name: Fin.pos_of_ne_zero
code: lemma pos_of_ne_zero {n : ℕ} {a : Fin (n + 1)} (h : a ≠ 0) :
    0 < a 
goal: 0 < a

full_name: Fin.coe_ofNat_eq_mod
code: @[simp]
theorem coe_ofNat_eq_mod (m n : ℕ) [NeZero m] :
    ((n : Fin m) : ℕ) = n % m 
goal: ↑↑n = n % m

full_name: Fin.mul_one'
code: protected theorem mul_one' [NeZero n] (k : Fin n) : k * 1 = k 
goal: k * 1 = k

full_name: Fin.one_mul'
code: protected theorem one_mul' [NeZero n] (k : Fin n) : (1 : Fin n) * k = k 
goal: 1 * k = k

full_name: Fin.mul_zero'
code: protected theorem mul_zero' [NeZero n] (k : Fin n) : k * 0 = 0 
goal: k * 0 = 0

full_name: Fin.zero_mul'
code: protected theorem zero_mul' [NeZero n] (k : Fin n) : (0 : Fin n) * k = 0 
goal: 0 * k = 0

full_name: Fin.toExpr
code: instance toExpr (n : ℕ) : Lean.ToExpr (Fin n) 
goal: Lean.ToExpr (Fin n)