File: Mathlib/Logic/Equiv/Fin.lean

full_name: finZeroEquiv
code: /-- Equivalence between `Fin 0` and `Empty`. -/
def finZeroEquiv : Fin 0 ≃ Empty 
goal: Fin 0 ≃ Empty

full_name: finZeroEquiv'
code: /-- Equivalence between `Fin 0` and `PEmpty`. -/
def finZeroEquiv' : Fin 0 ≃ PEmpty.{u} 
goal: Fin 0 ≃ PEmpty.{u}

full_name: finOneEquiv
code: /-- Equivalence between `Fin 1` and `Unit`. -/
def finOneEquiv : Fin 1 ≃ Unit 
goal: Fin 1 ≃ Unit

full_name: finTwoEquiv
code: /-- Equivalence between `Fin 2` and `Bool`. -/
def finTwoEquiv : Fin 2 ≃ Bool 
goal: Fin 2 ≃ Bool

full_name: piFinTwoEquiv
code: /-- `Π i : Fin 2, α i` is equivalent to `α 0 × α 1`. See also `finTwoArrowEquiv` for a
non-dependent version and `prodEquivPiFinTwo` for a version with inputs `α β : Type u`. -/
@[simps (config := .asFn)]
def piFinTwoEquiv (α : Fin 2 → Type u) : (∀ i, α i) ≃ α 0 × α 1 
goal: ((i : Fin 2) → α i) ≃ α 0 × α 1

full_name: piFinTwoEquiv_apply
code: /-- `Π i : Fin 2, α i` is equivalent to `α 0 × α 1`. See also `finTwoArrowEquiv` for a
non-dependent version and `prodEquivPiFinTwo` for a version with inputs `α β : Type u`. -/
@[simps (config := .asFn)]
def piFinTwoEquiv (α : Fin 2 → Type u) : (∀ i, α i) ≃ α 0 × α 1 
goal: ⇑(piFinTwoEquiv α) = fun f => (f 0, f 1)

full_name: piFinTwoEquiv_symm_apply
code: /-- `Π i : Fin 2, α i` is equivalent to `α 0 × α 1`. See also `finTwoArrowEquiv` for a
non-dependent version and `prodEquivPiFinTwo` for a version with inputs `α β : Type u`. -/
@[simps (config := .asFn)]
def piFinTwoEquiv (α : Fin 2 → Type u) : (∀ i, α i) ≃ α 0 × α 1 
goal: ⇑(piFinTwoEquiv α).symm = fun p => Fin.cons p.1 (Fin.cons p.2 finZeroElim)

full_name: Fin.preimage_apply_01_prod
code: theorem Fin.preimage_apply_01_prod {α : Fin 2 → Type u} (s : Set (α 0)) (t : Set (α 1)) :
    (fun f : ∀ i, α i => (f 0, f 1)) ⁻¹' s ×ˢ t =
      Set.pi Set.univ (Fin.cons s <| Fin.cons t finZeroElim) 
goal: (fun f => (f 0, f 1)) ⁻¹' s ×ˢ t = Set.univ.pi (Fin.cons s (Fin.cons t finZeroElim))

full_name: Fin.preimage_apply_01_prod'
code: theorem Fin.preimage_apply_01_prod' {α : Type u} (s t : Set α) :
    (fun f : Fin 2 → α => (f 0, f 1)) ⁻¹' s ×ˢ t = Set.pi Set.univ ![s, t] 
goal: (fun f => (f 0, f 1)) ⁻¹' s ×ˢ t = Set.univ.pi ![s, t]

full_name: prodEquivPiFinTwo
code: /-- A product space `α × β` is equivalent to the space `Π i : Fin 2, γ i`, where
`γ = Fin.cons α (Fin.cons β finZeroElim)`. See also `piFinTwoEquiv` and
`finTwoArrowEquiv`. -/
@[simps! (config := .asFn)]
def prodEquivPiFinTwo (α β : Type u) : α × β ≃ ∀ i : Fin 2, ![α, β] i 
goal: α × β ≃ ((i : Fin 2) → ![α, β] i)

full_name: prodEquivPiFinTwo_symm_apply
code: /-- A product space `α × β` is equivalent to the space `Π i : Fin 2, γ i`, where
`γ = Fin.cons α (Fin.cons β finZeroElim)`. See also `piFinTwoEquiv` and
`finTwoArrowEquiv`. -/
@[simps! (config := .asFn)]
def prodEquivPiFinTwo (α β : Type u) : α × β ≃ ∀ i : Fin 2, ![α, β] i 
goal: ⇑(prodEquivPiFinTwo α β).symm = fun f => (f 0, f 1)

full_name: prodEquivPiFinTwo_apply
code: /-- A product space `α × β` is equivalent to the space `Π i : Fin 2, γ i`, where
`γ = Fin.cons α (Fin.cons β finZeroElim)`. See also `piFinTwoEquiv` and
`finTwoArrowEquiv`. -/
@[simps! (config := .asFn)]
def prodEquivPiFinTwo (α β : Type u) : α × β ≃ ∀ i : Fin 2, ![α, β] i 
goal: ⇑(prodEquivPiFinTwo α β) = fun p => Fin.cons p.1 (Fin.cons p.2 finZeroElim)

full_name: finTwoArrowEquiv_apply
code: /-- The space of functions `Fin 2 → α` is equivalent to `α × α`. See also `piFinTwoEquiv` and
`prodEquivPiFinTwo`. -/
@[simps (config := .asFn)]
def finTwoArrowEquiv (α : Type*) : (Fin 2 → α) ≃ α × α 
goal: ⇑(finTwoArrowEquiv α) = (piFinTwoEquiv fun x => α).toFun

full_name: finTwoArrowEquiv
code: /-- The space of functions `Fin 2 → α` is equivalent to `α × α`. See also `piFinTwoEquiv` and
`prodEquivPiFinTwo`. -/
@[simps (config := .asFn)]
def finTwoArrowEquiv (α : Type*) : (Fin 2 → α) ≃ α × α 
goal: (Fin 2 → α) ≃ α × α

full_name: finTwoArrowEquiv_symm_apply
code: /-- The space of functions `Fin 2 → α` is equivalent to `α × α`. See also `piFinTwoEquiv` and
`prodEquivPiFinTwo`. -/
@[simps (config := .asFn)]
def finTwoArrowEquiv (α : Type*) : (Fin 2 → α) ≃ α × α 
goal: ⇑(finTwoArrowEquiv α).symm = fun x => ![x.1, x.2]

full_name: finSuccEquiv'
code: /-- An equivalence that removes `i` and maps it to `none`.
This is a version of `Fin.predAbove` that produces `Option (Fin n)` instead of
mapping both `i.cast_succ` and `i.succ` to `i`. -/
def finSuccEquiv' (i : Fin (n + 1)) : Fin (n + 1) ≃ Option (Fin n) 
goal: Fin (n + 1) ≃ Option (Fin n)

full_name: finSuccEquiv'_at
code: @[simp]
theorem finSuccEquiv'_at (i : Fin (n + 1)) : (finSuccEquiv' i) i = none 
goal: (finSuccEquiv' i) i = none

full_name: finSuccEquiv'_succAbove
code: @[simp]
theorem finSuccEquiv'_succAbove (i : Fin (n + 1)) (j : Fin n) :
    finSuccEquiv' i (i.succAbove j) = some j 
goal: (finSuccEquiv' i) (i.succAbove j) = some j

full_name: finSuccEquiv'_below
code: theorem finSuccEquiv'_below {i : Fin (n + 1)} {m : Fin n} (h : Fin.castSucc m < i) :
    (finSuccEquiv' i) (Fin.castSucc m) = m 
goal: (finSuccEquiv' i) m.castSucc = some m

full_name: finSuccEquiv'_above
code: theorem finSuccEquiv'_above {i : Fin (n + 1)} {m : Fin n} (h : i ≤ Fin.castSucc m) :
    (finSuccEquiv' i) m.succ = some m 
goal: (finSuccEquiv' i) m.succ = some m

full_name: finSuccEquiv'_symm_none
code: @[simp]
theorem finSuccEquiv'_symm_none (i : Fin (n + 1)) : (finSuccEquiv' i).symm none = i 
goal: (finSuccEquiv' i).symm none = i

full_name: finSuccEquiv'_symm_some
code: @[simp]
theorem finSuccEquiv'_symm_some (i : Fin (n + 1)) (j : Fin n) :
    (finSuccEquiv' i).symm (some j) = i.succAbove j 
goal: (finSuccEquiv' i).symm (some j) = i.succAbove j

full_name: finSuccEquiv'_symm_some_below
code: theorem finSuccEquiv'_symm_some_below {i : Fin (n + 1)} {m : Fin n} (h : Fin.castSucc m < i) :
    (finSuccEquiv' i).symm (some m) = Fin.castSucc m 
goal: (finSuccEquiv' i).symm (some m) = m.castSucc

full_name: finSuccEquiv'_symm_some_above
code: theorem finSuccEquiv'_symm_some_above {i : Fin (n + 1)} {m : Fin n} (h : i ≤ Fin.castSucc m) :
    (finSuccEquiv' i).symm (some m) = m.succ 
goal: (finSuccEquiv' i).symm (some m) = m.succ

full_name: finSuccEquiv'_symm_coe_below
code: theorem finSuccEquiv'_symm_coe_below {i : Fin (n + 1)} {m : Fin n} (h : Fin.castSucc m < i) :
    (finSuccEquiv' i).symm m = Fin.castSucc m 
goal: (finSuccEquiv' i).symm (some m) = m.castSucc

full_name: finSuccEquiv'_symm_coe_above
code: theorem finSuccEquiv'_symm_coe_above {i : Fin (n + 1)} {m : Fin n} (h : i ≤ Fin.castSucc m) :
    (finSuccEquiv' i).symm m = m.succ 
goal: (finSuccEquiv' i).symm (some m) = m.succ

full_name: finSuccEquiv
code: /-- Equivalence between `Fin (n + 1)` and `Option (Fin n)`.
This is a version of `Fin.pred` that produces `Option (Fin n)` instead of
requiring a proof that the input is not `0`. -/
def finSuccEquiv (n : ℕ) : Fin (n + 1) ≃ Option (Fin n) 
goal: Fin (n + 1) ≃ Option (Fin n)

full_name: finSuccEquiv_zero
code: @[simp]
theorem finSuccEquiv_zero : (finSuccEquiv n) 0 = none 
goal: (finSuccEquiv n) 0 = none

full_name: finSuccEquiv_succ
code: @[simp]
theorem finSuccEquiv_succ (m : Fin n) : (finSuccEquiv n) m.succ = some m 
goal: (finSuccEquiv n) m.succ = some m

full_name: finSuccEquiv_symm_none
code: @[simp]
theorem finSuccEquiv_symm_none : (finSuccEquiv n).symm none = 0 
goal: (finSuccEquiv n).symm none = 0

full_name: finSuccEquiv_symm_some
code: @[simp]
theorem finSuccEquiv_symm_some (m : Fin n) : (finSuccEquiv n).symm (some m) = m.succ 
goal: (finSuccEquiv n).symm (some m) = m.succ

full_name: finSuccEquiv'_zero
code: /-- The equiv version of `Fin.predAbove_zero`. -/
theorem finSuccEquiv'_zero : finSuccEquiv' (0 : Fin (n + 1)) = finSuccEquiv n 
goal: finSuccEquiv' 0 = finSuccEquiv n

full_name: finSuccEquiv'_last_apply_castSucc
code: theorem finSuccEquiv'_last_apply_castSucc (i : Fin n) :
    finSuccEquiv' (Fin.last n) (Fin.castSucc i) = i 
goal: (finSuccEquiv' (Fin.last n)) i.castSucc = some i

full_name: finSuccEquiv'_last_apply
code: theorem finSuccEquiv'_last_apply {i : Fin (n + 1)} (h : i ≠ Fin.last n) :
    finSuccEquiv' (Fin.last n) i = Fin.castLT i (Fin.val_lt_last h) 
goal: (finSuccEquiv' (Fin.last n)) i = some (i.castLT ⋯)

full_name: finSuccEquiv'_ne_last_apply
code: theorem finSuccEquiv'_ne_last_apply {i j : Fin (n + 1)} (hi : i ≠ Fin.last n) (hj : j ≠ i) :
    finSuccEquiv' i j = (i.castLT (Fin.val_lt_last hi)).predAbove j 
goal: (finSuccEquiv' i) j = some ((i.castLT ⋯).predAbove j)

full_name: finSuccAboveEquiv
code: /-- `Fin.succAbove` as an order isomorphism between `Fin n` and `{x : Fin (n + 1) // x ≠ p}`. -/
def finSuccAboveEquiv (p : Fin (n + 1)) : Fin n ≃ { x : Fin (n + 1) // x ≠ p } 
goal: Fin n ≃ { x // x ≠ p }

full_name: finSuccAboveEquiv_apply
code: theorem finSuccAboveEquiv_apply (p : Fin (n + 1)) (i : Fin n) :
    finSuccAboveEquiv p i = ⟨p.succAbove i, p.succAbove_ne i⟩ 
goal: (finSuccAboveEquiv p) i = ⟨p.succAbove i, ⋯⟩

full_name: finSuccAboveEquiv_symm_apply_last
code: theorem finSuccAboveEquiv_symm_apply_last (x : { x : Fin (n + 1) // x ≠ Fin.last n }) :
    (finSuccAboveEquiv (Fin.last n)).symm x = Fin.castLT x.1 (Fin.val_lt_last x.2) 
goal: (finSuccAboveEquiv (Fin.last n)).symm x = (↑x).castLT ⋯

full_name: finSuccAboveEquiv_symm_apply_ne_last
code: theorem finSuccAboveEquiv_symm_apply_ne_last {p : Fin (n + 1)} (h : p ≠ Fin.last n)
    (x : { x : Fin (n + 1) // x ≠ p }) :
    (finSuccAboveEquiv p).symm x = (p.castLT (Fin.val_lt_last h)).predAbove x 
goal: (finSuccAboveEquiv p).symm x = (p.castLT ⋯).predAbove ↑x

full_name: finSuccEquivLast
code: /-- `Equiv` between `Fin (n + 1)` and `Option (Fin n)` sending `Fin.last n` to `none` -/
def finSuccEquivLast : Fin (n + 1) ≃ Option (Fin n) 
goal: Fin (n + 1) ≃ Option (Fin n)

full_name: finSuccEquivLast_castSucc
code: @[simp]
theorem finSuccEquivLast_castSucc (i : Fin n) : finSuccEquivLast (Fin.castSucc i) = some i 
goal: finSuccEquivLast i.castSucc = some i

full_name: finSuccEquivLast_last
code: @[simp]
theorem finSuccEquivLast_last : finSuccEquivLast (Fin.last n) = none 
goal: finSuccEquivLast (Fin.last n) = none

full_name: finSuccEquivLast_symm_some
code: @[simp]
theorem finSuccEquivLast_symm_some (i : Fin n) :
    finSuccEquivLast.symm (some i) = Fin.castSucc i 
goal: finSuccEquivLast.symm (some i) = i.castSucc

full_name: finSuccEquivLast_symm_none
code: @[simp] theorem finSuccEquivLast_symm_none : finSuccEquivLast.symm none = Fin.last n 
goal: finSuccEquivLast.symm none = Fin.last n

full_name: Equiv.piFinSuccAbove_symm_apply
code: /-- Equivalence between `Π j : Fin (n + 1), α j` and `α i × Π j : Fin n, α (Fin.succAbove i j)`. -/
@[simps (config := .asFn)]
def Equiv.piFinSuccAbove (α : Fin (n + 1) → Type u) (i : Fin (n + 1)) :
    (∀ j, α j) ≃ α i × ∀ j, α (i.succAbove j) 
goal: ⇑(Equiv.piFinSuccAbove α i).symm = fun f => i.insertNth f.1 f.2

full_name: Equiv.piFinSuccAbove_apply
code: /-- Equivalence between `Π j : Fin (n + 1), α j` and `α i × Π j : Fin n, α (Fin.succAbove i j)`. -/
@[simps (config := .asFn)]
def Equiv.piFinSuccAbove (α : Fin (n + 1) → Type u) (i : Fin (n + 1)) :
    (∀ j, α j) ≃ α i × ∀ j, α (i.succAbove j) 
goal: ⇑(Equiv.piFinSuccAbove α i) = fun f => (f i, i.removeNth f)

full_name: Equiv.piFinSuccAbove
code: /-- Equivalence between `Π j : Fin (n + 1), α j` and `α i × Π j : Fin n, α (Fin.succAbove i j)`. -/
@[simps (config := .asFn)]
def Equiv.piFinSuccAbove (α : Fin (n + 1) → Type u) (i : Fin (n + 1)) :
    (∀ j, α j) ≃ α i × ∀ j, α (i.succAbove j) 
goal: ((j : Fin (n + 1)) → α j) ≃ α i × ((j : Fin n) → α (i.succAbove j))

full_name: Equiv.piFinSucc
code: /-- Equivalence between `Fin (n + 1) → β` and `β × (Fin n → β)`. -/
@[simps! (config := .asFn)]
def Equiv.piFinSucc (n : ℕ) (β : Type u) : (Fin (n + 1) → β) ≃ β × (Fin n → β) 
goal: (Fin (n + 1) → β) ≃ β × (Fin n → β)

full_name: Equiv.piFinSucc_symm_apply
code: /-- Equivalence between `Fin (n + 1) → β` and `β × (Fin n → β)`. -/
@[simps! (config := .asFn)]
def Equiv.piFinSucc (n : ℕ) (β : Type u) : (Fin (n + 1) → β) ≃ β × (Fin n → β) 
goal: ⇑(Equiv.piFinSucc n β).symm = fun f => Fin.cons f.1 f.2

full_name: Equiv.piFinSucc_apply
code: /-- Equivalence between `Fin (n + 1) → β` and `β × (Fin n → β)`. -/
@[simps! (config := .asFn)]
def Equiv.piFinSucc (n : ℕ) (β : Type u) : (Fin (n + 1) → β) ≃ β × (Fin n → β) 
goal: ⇑(Equiv.piFinSucc n β) = fun f => (f 0, Fin.tail f)

full_name: Equiv.embeddingFinSucc
code: /-- An embedding `e : Fin (n+1) ↪ ι` corresponds to an embedding `f : Fin n ↪ ι` (corresponding
the last `n` coordinates of `e`) together with a value not taken by `f` (corresponding to `e 0`). -/
def Equiv.embeddingFinSucc (n : ℕ) (ι : Type*) :
    (Fin (n+1) ↪ ι) ≃ (Σ (e : Fin n ↪ ι), {i // i ∉ Set.range e}) 
goal: (Fin (n + 1) ↪ ι) ≃ (e : Fin n ↪ ι) × { i // i ∉ Set.range ⇑e }

full_name: Equiv.embeddingFinSucc_fst
code: @[simp] lemma Equiv.embeddingFinSucc_fst {n : ℕ} {ι : Type*} (e : Fin (n+1) ↪ ι) :
    ((Equiv.embeddingFinSucc n ι e).1 : Fin n → ι) = e ∘ Fin.succ 
goal: ⇑((Equiv.embeddingFinSucc n ι) e).fst = ⇑e ∘ Fin.succ

full_name: Equiv.embeddingFinSucc_snd
code: @[simp] lemma Equiv.embeddingFinSucc_snd {n : ℕ} {ι : Type*} (e : Fin (n+1) ↪ ι) :
    ((Equiv.embeddingFinSucc n ι e).2 : ι) = e 0 
goal: ↑((Equiv.embeddingFinSucc n ι) e).snd = e 0

full_name: Equiv.coe_embeddingFinSucc_symm
code: @[simp] lemma Equiv.coe_embeddingFinSucc_symm {n : ℕ} {ι : Type*}
    (f : Σ (e : Fin n ↪ ι), {i // i ∉ Set.range e}) :
    ((Equiv.embeddingFinSucc n ι).symm f : Fin (n + 1) → ι) = Fin.cons f.2.1 f.1 
goal: ⇑((Equiv.embeddingFinSucc n ι).symm f) = Fin.cons ↑f.snd ⇑f.fst

full_name: Equiv.piFinCastSucc_apply
code: /-- Equivalence between `Fin (n + 1) → β` and `β × (Fin n → β)` which separates out the last
element of the tuple. -/
@[simps! (config := .asFn)]
def Equiv.piFinCastSucc (n : ℕ) (β : Type u) : (Fin (n + 1) → β) ≃ β × (Fin n → β) 
goal: ⇑(Equiv.piFinCastSucc n β) = fun f => (f (Fin.last n), Fin.init f)

full_name: Equiv.piFinCastSucc_symm_apply
code: /-- Equivalence between `Fin (n + 1) → β` and `β × (Fin n → β)` which separates out the last
element of the tuple. -/
@[simps! (config := .asFn)]
def Equiv.piFinCastSucc (n : ℕ) (β : Type u) : (Fin (n + 1) → β) ≃ β × (Fin n → β) 
goal: ⇑(Equiv.piFinCastSucc n β).symm = fun f => Fin.snoc f.2 f.1

full_name: Equiv.piFinCastSucc
code: /-- Equivalence between `Fin (n + 1) → β` and `β × (Fin n → β)` which separates out the last
element of the tuple. -/
@[simps! (config := .asFn)]
def Equiv.piFinCastSucc (n : ℕ) (β : Type u) : (Fin (n + 1) → β) ≃ β × (Fin n → β) 
goal: (Fin (n + 1) → β) ≃ β × (Fin n → β)

full_name: finSumFinEquiv
code: /-- Equivalence between `Fin m ⊕ Fin n` and `Fin (m + n)` -/
def finSumFinEquiv : Fin m ⊕ Fin n ≃ Fin (m + n) 
goal: Fin m ⊕ Fin n ≃ Fin (m + n)

full_name: finSumFinEquiv_apply_left
code: @[simp]
theorem finSumFinEquiv_apply_left (i : Fin m) :
    (finSumFinEquiv (Sum.inl i) : Fin (m + n)) = Fin.castAdd n i 
goal: finSumFinEquiv (Sum.inl i) = Fin.castAdd n i

full_name: finSumFinEquiv_apply_right
code: @[simp]
theorem finSumFinEquiv_apply_right (i : Fin n) :
    (finSumFinEquiv (Sum.inr i) : Fin (m + n)) = Fin.natAdd m i 
goal: finSumFinEquiv (Sum.inr i) = Fin.natAdd m i

full_name: finSumFinEquiv_symm_apply_castAdd
code: @[simp]
theorem finSumFinEquiv_symm_apply_castAdd (x : Fin m) :
    finSumFinEquiv.symm (Fin.castAdd n x) = Sum.inl x 
goal: finSumFinEquiv.symm (Fin.castAdd n x) = Sum.inl x

full_name: finSumFinEquiv_symm_apply_natAdd
code: @[simp]
theorem finSumFinEquiv_symm_apply_natAdd (x : Fin n) :
    finSumFinEquiv.symm (Fin.natAdd m x) = Sum.inr x 
goal: finSumFinEquiv.symm (Fin.natAdd m x) = Sum.inr x

full_name: finSumFinEquiv_symm_last
code: @[simp]
theorem finSumFinEquiv_symm_last : finSumFinEquiv.symm (Fin.last n) = Sum.inr 0 
goal: finSumFinEquiv.symm (Fin.last n) = Sum.inr 0

full_name: finAddFlip
code: /-- The equivalence between `Fin (m + n)` and `Fin (n + m)` which rotates by `n`. -/
def finAddFlip : Fin (m + n) ≃ Fin (n + m) 
goal: Fin (m + n) ≃ Fin (n + m)

full_name: finAddFlip_apply_castAdd
code: @[simp]
theorem finAddFlip_apply_castAdd (k : Fin m) (n : ℕ) :
    finAddFlip (Fin.castAdd n k) = Fin.natAdd n k 
goal: finAddFlip (Fin.castAdd n k) = Fin.natAdd n k

full_name: finAddFlip_apply_natAdd
code: @[simp]
theorem finAddFlip_apply_natAdd (k : Fin n) (m : ℕ) :
    finAddFlip (Fin.natAdd m k) = Fin.castAdd m k 
goal: finAddFlip (Fin.natAdd m k) = Fin.castAdd m k

full_name: finAddFlip_apply_mk_left
code: @[simp]
theorem finAddFlip_apply_mk_left {k : ℕ} (h : k < m) (hk : k < m + n := Nat.lt_add_right n h)
    (hnk : n + k < n + m := Nat.add_lt_add_left h n) :
    finAddFlip (⟨k, hk⟩ : Fin (m + n)) = ⟨n + k, hnk⟩ 
goal: finAddFlip ⟨k, hk⟩ = ⟨n + k, hnk⟩

full_name: finAddFlip_apply_mk_right
code: @[simp]
theorem finAddFlip_apply_mk_right {k : ℕ} (h₁ : m ≤ k) (h₂ : k < m + n) :
    finAddFlip (⟨k, h₂⟩ : Fin (m + n)) = ⟨k - m, by omega⟩ 
goal: finAddFlip ⟨k, h₂⟩ = ⟨k - m, ⋯⟩

full_name: finRotate
code: /-- Rotate `Fin n` one step to the right. -/
def finRotate : ∀ n, Equiv.Perm (Fin n)
  
goal: Equiv.Perm (Fin n)

full_name: finRotate_zero
code: @[simp] lemma finRotate_zero : finRotate 0 = Equiv.refl _ 
goal: finRotate 0 = Equiv.refl (Fin 0)

full_name: finRotate_succ
code: lemma finRotate_succ (n : ℕ) :
    finRotate (n + 1) = finAddFlip.trans (finCongr (Nat.add_comm 1 n)) 
goal: finRotate (n + 1) = finAddFlip.trans (finCongr ⋯)

full_name: finRotate_of_lt
code: theorem finRotate_of_lt {k : ℕ} (h : k < n) :
    finRotate (n + 1) ⟨k, h.trans_le n.le_succ⟩ = ⟨k + 1, Nat.succ_lt_succ h⟩ 
goal: (finRotate (n + 1)) ⟨k, ⋯⟩ = ⟨k + 1, ⋯⟩

full_name: finRotate_last'
code: theorem finRotate_last' : finRotate (n + 1) ⟨n, by omega⟩ = ⟨0, Nat.zero_lt_succ _⟩ 
goal: (finRotate (n + 1)) ⟨n, ⋯⟩ = ⟨0, ⋯⟩

full_name: finRotate_last
code: theorem finRotate_last : finRotate (n + 1) (Fin.last _) = 0 
goal: (finRotate (n + 1)) (Fin.last n) = 0

full_name: Fin.snoc_eq_cons_rotate
code: theorem Fin.snoc_eq_cons_rotate {α : Type*} (v : Fin n → α) (a : α) :
    @Fin.snoc _ (fun _ => α) v a = fun i => @Fin.cons _ (fun _ => α) a v (finRotate _ i) 
goal: Fin.snoc v a = fun i => Fin.cons a v ((finRotate (n + 1)) i)

full_name: finRotate_one
code: @[simp]
theorem finRotate_one : finRotate 1 = Equiv.refl _ 
goal: finRotate 1 = Equiv.refl (Fin 1)

full_name: finRotate_succ_apply
code: @[simp] theorem finRotate_succ_apply (i : Fin (n + 1)) : finRotate (n + 1) i = i + 1 
goal: (finRotate (n + 1)) i = i + 1

full_name: finRotate_apply_zero
code: theorem finRotate_apply_zero : finRotate n.succ 0 = 1 
goal: (finRotate n.succ) 0 = 1

full_name: coe_finRotate_of_ne_last
code: theorem coe_finRotate_of_ne_last {i : Fin n.succ} (h : i ≠ Fin.last n) :
    (finRotate (n + 1) i : ℕ) = i + 1 
goal: ↑((finRotate (n + 1)) i) = ↑i + 1

full_name: coe_finRotate
code: theorem coe_finRotate (i : Fin n.succ) :
    (finRotate n.succ i : ℕ) = if i = Fin.last n then (0 : ℕ) else i + 1 
goal: ↑((finRotate n.succ) i) = if i = Fin.last n then 0 else ↑i + 1

full_name: finProdFinEquiv
code: /-- Equivalence between `Fin m × Fin n` and `Fin (m * n)` -/
@[simps]
def finProdFinEquiv : Fin m × Fin n ≃ Fin (m * n) 
goal: Fin m × Fin n ≃ Fin (m * n)

full_name: finProdFinEquiv_symm_apply
code: /-- Equivalence between `Fin m × Fin n` and `Fin (m * n)` -/
@[simps]
def finProdFinEquiv : Fin m × Fin n ≃ Fin (m * n) 
goal: finProdFinEquiv.symm x = (x.divNat, x.modNat)

full_name: finProdFinEquiv_apply_val
code: /-- Equivalence between `Fin m × Fin n` and `Fin (m * n)` -/
@[simps]
def finProdFinEquiv : Fin m × Fin n ≃ Fin (m * n) 
goal: ↑(finProdFinEquiv x) = ↑x.2 + n * ↑x.1

full_name: Nat.divModEquiv_symm_apply
code: /-- The equivalence induced by `a ↦ (a / n, a % n)` for nonzero `n`.
This is like `finProdFinEquiv.symm` but with `m` infinite.
See `Nat.div_mod_unique` for a similar propositional statement. -/
@[simps]
def Nat.divModEquiv (n : ℕ) [NeZero n] : ℕ ≃ ℕ × Fin n 
goal: n.divModEquiv.symm p = p.1 * n + ↑p.2

full_name: Nat.divModEquiv_apply
code: /-- The equivalence induced by `a ↦ (a / n, a % n)` for nonzero `n`.
This is like `finProdFinEquiv.symm` but with `m` infinite.
See `Nat.div_mod_unique` for a similar propositional statement. -/
@[simps]
def Nat.divModEquiv (n : ℕ) [NeZero n] : ℕ ≃ ℕ × Fin n 
goal: n.divModEquiv a = (a / n, ↑a)

full_name: Nat.divModEquiv
code: /-- The equivalence induced by `a ↦ (a / n, a % n)` for nonzero `n`.
This is like `finProdFinEquiv.symm` but with `m` infinite.
See `Nat.div_mod_unique` for a similar propositional statement. -/
@[simps]
def Nat.divModEquiv (n : ℕ) [NeZero n] : ℕ ≃ ℕ × Fin n 
goal: ℕ ≃ ℕ × Fin n

full_name: Int.divModEquiv_apply
code: /-- The equivalence induced by `a ↦ (a / n, a % n)` for nonzero `n`.
See `Int.ediv_emod_unique` for a similar propositional statement. -/
@[simps]
def Int.divModEquiv (n : ℕ) [NeZero n] : ℤ ≃ ℤ × Fin n 
goal: (Int.divModEquiv n) a = (a / ↑n, ↑(a.natMod ↑n))

full_name: Int.divModEquiv
code: /-- The equivalence induced by `a ↦ (a / n, a % n)` for nonzero `n`.
See `Int.ediv_emod_unique` for a similar propositional statement. -/
@[simps]
def Int.divModEquiv (n : ℕ) [NeZero n] : ℤ ≃ ℤ × Fin n 
goal: ℤ ≃ ℤ × Fin n

full_name: Int.divModEquiv_symm_apply
code: /-- The equivalence induced by `a ↦ (a / n, a % n)` for nonzero `n`.
See `Int.ediv_emod_unique` for a similar propositional statement. -/
@[simps]
def Int.divModEquiv (n : ℕ) [NeZero n] : ℤ ≃ ℤ × Fin n 
goal: (Int.divModEquiv n).symm p = p.1 * ↑n + ↑↑p.2

full_name: Fin.castLEquiv_apply
code: /-- Promote a `Fin n` into a larger `Fin m`, as a subtype where the underlying
values are retained.

This is the `Equiv` version of `Fin.castLE`. -/
@[simps apply symm_apply]
def Fin.castLEquiv {n m : ℕ} (h : n ≤ m) : Fin n ≃ { i : Fin m // (i : ℕ) < n } 
goal: (Fin.castLEquiv h) i = ⟨Fin.castLE h i, ⋯⟩

full_name: Fin.castLEquiv_symm_apply
code: /-- Promote a `Fin n` into a larger `Fin m`, as a subtype where the underlying
values are retained.

This is the `Equiv` version of `Fin.castLE`. -/
@[simps apply symm_apply]
def Fin.castLEquiv {n m : ℕ} (h : n ≤ m) : Fin n ≃ { i : Fin m // (i : ℕ) < n } 
goal: (Fin.castLEquiv h).symm i = ⟨↑↑i, ⋯⟩

full_name: Fin.castLEquiv
code: /-- Promote a `Fin n` into a larger `Fin m`, as a subtype where the underlying
values are retained.

This is the `Equiv` version of `Fin.castLE`. -/
@[simps apply symm_apply]
def Fin.castLEquiv {n m : ℕ} (h : n ≤ m) : Fin n ≃ { i : Fin m // (i : ℕ) < n } 
goal: Fin n ≃ { i // ↑i < n }

full_name: subsingleton_fin_zero
code: /-- `Fin 0` is a subsingleton. -/
instance subsingleton_fin_zero : Subsingleton (Fin 0) 
goal: Subsingleton (Fin 0)

full_name: subsingleton_fin_one
code: /-- `Fin 1` is a subsingleton. -/
instance subsingleton_fin_one : Subsingleton (Fin 1) 
goal: Subsingleton (Fin 1)