File: Mathlib/Data/List/OfFn.lean

full_name: List.length_ofFn_go
code: @[simp]
theorem length_ofFn_go {n} (f : Fin n → α) (i j h) : length (ofFn.go f i j h) = i 
goal: (List.ofFn.go f i j h).length = i

full_name: List.length_ofFn
code: /-- The length of a list converted from a function is the size of the domain. -/
@[simp]
theorem length_ofFn {n} (f : Fin n → α) : length (ofFn f) = n 
goal: (List.ofFn f).length = n

full_name: List.getElem_ofFn_go
code: theorem getElem_ofFn_go {n} (f : Fin n → α) (i j h) (k) (hk : k < (ofFn.go f i j h).length) :
    (ofFn.go f i j h)[k] = f ⟨j + k, by simp at hk; omega⟩ 
goal: (List.ofFn.go f i j h)[k] = f ⟨j + k, ⋯⟩

full_name: List.get_ofFn_go
code: theorem get_ofFn_go {n} (f : Fin n → α) (i j h) (k) (hk) :
    get (ofFn.go f i j h) ⟨k, hk⟩ = f ⟨j + k, by simp at hk; omega⟩ 
goal: (List.ofFn.go f i j h).get ⟨k, hk⟩ = f ⟨j + k, ⋯⟩

full_name: List.getElem_ofFn
code: @[simp]
theorem getElem_ofFn {n} (f : Fin n → α) (i : Nat) (h : i < (ofFn f).length) :
    (ofFn f)[i] = f ⟨i, by simp_all⟩ 
goal: (List.ofFn f)[i] = f ⟨i, ⋯⟩

full_name: List.get_ofFn
code: theorem get_ofFn {n} (f : Fin n → α) (i) : get (ofFn f) i = f (Fin.cast (by simp) i) 
goal: (List.ofFn f).get i = f (Fin.cast ⋯ i)

full_name: List.getElem?_ofFn
code: /-- The `n`th element of a list -/
@[simp]
theorem getElem?_ofFn {n} (f : Fin n → α) (i) : (ofFn f)[i]? = ofFnNthVal f i 
goal: (List.ofFn f)[i]? = List.ofFnNthVal f i

full_name: List.get?_ofFn
code: /-- The `n`th element of a list -/
theorem get?_ofFn {n} (f : Fin n → α) (i) : get? (ofFn f) i = ofFnNthVal f i 
goal: (List.ofFn f).get? i = List.ofFnNthVal f i

full_name: List.nthLe_ofFn
code: @[deprecated get_ofFn (since := "2023-01-17")]
theorem nthLe_ofFn {n} (f : Fin n → α) (i : Fin n) :
    nthLe (ofFn f) i ((length_ofFn f).symm ▸ i.2) = f i 
goal: (List.ofFn f).nthLe ↑i ⋯ = f i

full_name: List.nthLe_ofFn'
code: @[simp, deprecated get_ofFn (since := "2023-01-17")]
theorem nthLe_ofFn' {n} (f : Fin n → α) {i : ℕ} (h : i < (ofFn f).length) :
    nthLe (ofFn f) i h = f ⟨i, length_ofFn f ▸ h⟩ 
goal: (List.ofFn f).nthLe i h = f ⟨i, ⋯⟩

full_name: List.map_ofFn
code: @[simp]
theorem map_ofFn {β : Type*} {n : ℕ} (f : Fin n → α) (g : α → β) :
    map g (ofFn f) = ofFn (g ∘ f) 
goal: List.map g (List.ofFn f) = List.ofFn (g ∘ f)

full_name: List.ofFn_congr
code: @[congr]
theorem ofFn_congr {m n : ℕ} (h : m = n) (f : Fin m → α) :
    ofFn f = ofFn fun i : Fin n => f (Fin.cast h.symm i) 
goal: List.ofFn f = List.ofFn fun i => f (Fin.cast ⋯ i)

full_name: List.ofFn_zero
code: /-- `ofFn` on an empty domain is the empty list. -/
@[simp]
theorem ofFn_zero (f : Fin 0 → α) : ofFn f = [] 
goal: List.ofFn f = []

full_name: List.ofFn_succ
code: @[simp]
theorem ofFn_succ {n} (f : Fin (succ n) → α) : ofFn f = f 0 :: ofFn fun i => f i.succ 
goal: List.ofFn f = f 0 :: List.ofFn fun i => f i.succ

full_name: List.ofFn_succ'
code: theorem ofFn_succ' {n} (f : Fin (succ n) → α) :
    ofFn f = (ofFn fun i => f (Fin.castSucc i)).concat (f (Fin.last _)) 
goal: List.ofFn f = (List.ofFn fun i => f i.castSucc).concat (f (Fin.last n))

full_name: List.ofFn_eq_nil_iff
code: @[simp]
theorem ofFn_eq_nil_iff {n : ℕ} {f : Fin n → α} : ofFn f = [] ↔ n = 0 
goal: List.ofFn f = [] ↔ n = 0

full_name: List.last_ofFn
code: theorem last_ofFn {n : ℕ} (f : Fin n → α) (h : ofFn f ≠ [])
    (hn : n - 1 < n := Nat.pred_lt <| ofFn_eq_nil_iff.not.mp h) :
    getLast (ofFn f) h = f ⟨n - 1, hn⟩ 
goal: (List.ofFn f).getLast h = f ⟨n - 1, hn⟩

full_name: List.last_ofFn_succ
code: theorem last_ofFn_succ {n : ℕ} (f : Fin n.succ → α)
    (h : ofFn f ≠ [] := mt ofFn_eq_nil_iff.mp (Nat.succ_ne_zero _)) :
    getLast (ofFn f) h = f (Fin.last _) 
goal: (List.ofFn f).getLast h = f (Fin.last n)

full_name: List.ofFn_add
code: /-- Note this matches the convention of `List.ofFn_succ'`, putting the `Fin m` elements first. -/
theorem ofFn_add {m n} (f : Fin (m + n) → α) :
    List.ofFn f =
      (List.ofFn fun i => f (Fin.castAdd n i)) ++ List.ofFn fun j => f (Fin.natAdd m j) 
goal: List.ofFn f = (List.ofFn fun i => f (Fin.castAdd n i)) ++ List.ofFn fun j => f (Fin.natAdd m j)

full_name: List.ofFn_fin_append
code: @[simp]
theorem ofFn_fin_append {m n} (a : Fin m → α) (b : Fin n → α) :
    List.ofFn (Fin.append a b) = List.ofFn a ++ List.ofFn b 
goal: List.ofFn (Fin.append a b) = List.ofFn a ++ List.ofFn b

full_name: List.ofFn_mul
code: /-- This breaks a list of `m*n` items into `m` groups each containing `n` elements. -/
theorem ofFn_mul {m n} (f : Fin (m * n) → α) :
    List.ofFn f = List.join (List.ofFn fun i : Fin m => List.ofFn fun j : Fin n => f ⟨i * n + j,
    calc
      ↑i * n + j < (i + 1) * n :=
        (Nat.add_lt_add_left j.prop _).trans_eq (by rw [Nat.add_mul, Nat.one_mul])
      _ ≤ _ := Nat.mul_le_mul_right _ i.prop⟩) 
goal: List.ofFn f = (List.ofFn fun i => List.ofFn fun j => f ⟨↑i * n + ↑j, ⋯⟩).join

full_name: List.ofFn_mul'
code: /-- This breaks a list of `m*n` items into `n` groups each containing `m` elements. -/
theorem ofFn_mul' {m n} (f : Fin (m * n) → α) :
    List.ofFn f = List.join (List.ofFn fun i : Fin n => List.ofFn fun j : Fin m => f ⟨m * i + j,
    calc
      m * i + j < m * (i + 1) :=
        (Nat.add_lt_add_left j.prop _).trans_eq (by rw [Nat.mul_add, Nat.mul_one])
      _ ≤ _ := Nat.mul_le_mul_left _ i.prop⟩) 
goal: List.ofFn f = (List.ofFn fun i => List.ofFn fun j => f ⟨m * ↑i + ↑j, ⋯⟩).join

full_name: List.ofFn_get
code: @[simp]
theorem ofFn_get : ∀ l : List α, (ofFn (get l)) = l
  
goal: List.ofFn l.get = l

full_name: List.ofFn_getElem
code: @[simp]
theorem ofFn_getElem : ∀ l : List α, (ofFn (fun i : Fin l.length => l[(i : Nat)])) = l
  
goal: (List.ofFn fun i => l[↑i]) = l

full_name: List.ofFn_getElem_eq_map
code: @[simp]
theorem ofFn_getElem_eq_map {β : Type*} (l : List α) (f : α → β) :
    ofFn (fun i : Fin l.length => f <| l[(i : Nat)]) = l.map f 
goal: (List.ofFn fun i => f l[↑i]) = List.map f l

full_name: List.ofFn_get_eq_map
code: @[deprecated ofFn_getElem_eq_map (since := "2024-06-12")]
theorem ofFn_get_eq_map {β : Type*} (l : List α) (f : α → β) : ofFn (f <| l.get ·) = l.map f 
goal: (List.ofFn fun x => f (l.get x)) = List.map f l

full_name: List.ofFn_nthLe
code: @[deprecated ofFn_get (since := "2023-01-17")]
theorem ofFn_nthLe : ∀ l : List α, (ofFn fun i => nthLe l i i.2) = l 
goal: (List.ofFn fun i => l.nthLe ↑i ⋯) = l

full_name: List.mem_ofFn
code: theorem mem_ofFn {n} (f : Fin n → α) (a : α) : a ∈ ofFn f ↔ a ∈ Set.range f 
goal: a ∈ List.ofFn f ↔ a ∈ Set.range f

full_name: List.forall_mem_ofFn_iff
code: @[simp]
theorem forall_mem_ofFn_iff {n : ℕ} {f : Fin n → α} {P : α → Prop} :
    (∀ i ∈ ofFn f, P i) ↔ ∀ j : Fin n, P (f j) 
goal: (∀ i ∈ List.ofFn f, P i) ↔ ∀ (j : Fin n), P (f j)

full_name: List.ofFn_const
code: @[simp]
theorem ofFn_const : ∀ (n : ℕ) (c : α), (ofFn fun _ : Fin n => c) = replicate n c
  
goal: (List.ofFn fun x => c) = List.replicate n c

full_name: List.ofFn_fin_repeat
code: @[simp]
theorem ofFn_fin_repeat {m} (a : Fin m → α) (n : ℕ) :
    List.ofFn (Fin.repeat n a) = (List.replicate n (List.ofFn a)).join 
goal: List.ofFn (Fin.repeat n a) = (List.replicate n (List.ofFn a)).join

full_name: List.pairwise_ofFn
code: @[simp]
theorem pairwise_ofFn {R : α → α → Prop} {n} {f : Fin n → α} :
    (ofFn f).Pairwise R ↔ ∀ ⦃i j⦄, i < j → R (f i) (f j) 
goal: List.Pairwise R (List.ofFn f) ↔ ∀ ⦃i j : Fin n⦄, i < j → R (f i) (f j)

full_name: List.equivSigmaTuple_symm_apply
code: /-- Lists are equivalent to the sigma type of tuples of a given length. -/
@[simps]
def equivSigmaTuple : List α ≃ Σn, Fin n → α 
goal: List.equivSigmaTuple.symm f = List.ofFn f.snd

full_name: List.equivSigmaTuple_apply_snd
code: /-- Lists are equivalent to the sigma type of tuples of a given length. -/
@[simps]
def equivSigmaTuple : List α ≃ Σn, Fin n → α 
goal: ∀ (a : Fin l.length), (List.equivSigmaTuple l).snd a = l.get a

full_name: List.equivSigmaTuple_apply_fst
code: /-- Lists are equivalent to the sigma type of tuples of a given length. -/
@[simps]
def equivSigmaTuple : List α ≃ Σn, Fin n → α 
goal: (List.equivSigmaTuple l).fst = l.length

full_name: List.equivSigmaTuple
code: /-- Lists are equivalent to the sigma type of tuples of a given length. -/
@[simps]
def equivSigmaTuple : List α ≃ Σn, Fin n → α 
goal: List α ≃ (n : ℕ) × (Fin n → α)

full_name: List.ofFnRec
code: /-- A recursor for lists that expands a list into a function mapping to its elements.

This can be used with `induction l using List.ofFnRec`. -/
@[elab_as_elim]
def ofFnRec {C : List α → Sort*} (h : ∀ (n) (f : Fin n → α), C (List.ofFn f)) (l : List α) : C l 
goal: C l

full_name: List.ofFnRec_ofFn
code: @[simp]
theorem ofFnRec_ofFn {C : List α → Sort*} (h : ∀ (n) (f : Fin n → α), C (List.ofFn f)) {n : ℕ}
    (f : Fin n → α) : @ofFnRec _ C h (List.ofFn f) = h _ f 
goal: List.ofFnRec h (List.ofFn f) = h n f

full_name: List.exists_iff_exists_tuple
code: theorem exists_iff_exists_tuple {P : List α → Prop} :
    (∃ l : List α, P l) ↔ ∃ (n : _) (f : Fin n → α), P (List.ofFn f) 
goal: (∃ l, P l) ↔ ∃ n f, P (List.ofFn f)

full_name: List.forall_iff_forall_tuple
code: theorem forall_iff_forall_tuple {P : List α → Prop} :
    (∀ l : List α, P l) ↔ ∀ (n) (f : Fin n → α), P (List.ofFn f) 
goal: (∀ (l : List α), P l) ↔ ∀ (n : ℕ) (f : Fin n → α), P (List.ofFn f)

full_name: List.ofFn_inj'
code: /-- `Fin.sigma_eq_iff_eq_comp_cast` may be useful to work with the RHS of this expression. -/
theorem ofFn_inj' {m n : ℕ} {f : Fin m → α} {g : Fin n → α} :
    ofFn f = ofFn g ↔ (⟨m, f⟩ : Σn, Fin n → α) = ⟨n, g⟩ 
goal: List.ofFn f = List.ofFn g ↔ ⟨m, f⟩ = ⟨n, g⟩

full_name: List.ofFn_injective
code: /-- Note we can only state this when the two functions are indexed by defeq `n`. -/
theorem ofFn_injective {n : ℕ} : Function.Injective (ofFn : (Fin n → α) → List α) 
goal: Function.Injective List.ofFn

full_name: List.ofFn_inj
code: /-- A special case of `List.ofFn_inj` for when the two functions are indexed by defeq `n`. -/
@[simp]
theorem ofFn_inj {n : ℕ} {f g : Fin n → α} : ofFn f = ofFn g ↔ f = g 
goal: List.ofFn f = List.ofFn g ↔ f = g