File: Mathlib/Data/Fin/VecNotation.lean

full_name: Matrix.vecEmpty
code: /-- `![]` is the vector with no entries. -/
def vecEmpty : Fin 0 → α 
goal: Fin 0 → α

full_name: Matrix.vecCons
code: /-- `vecCons h t` prepends an entry `h` to a vector `t`.

The inverse functions are `vecHead` and `vecTail`.
The notation `![a, b, ...]` expands to `vecCons a (vecCons b ...)`.
-/
def vecCons {n : ℕ} (h : α) (t : Fin n → α) : Fin n.succ → α 
goal: Fin n.succ → α

full_name: Matrix.vecNotation
code: /-- `![...]` notation is used to construct a vector `Fin n → α` using `Matrix.vecEmpty` and
`Matrix.vecCons`.

For instance, `![a, b, c] : Fin 3` is syntax for `vecCons a (vecCons b (vecCons c vecEmpty))`.

Note that this should not be used as syntax for `Matrix` as it generates a term with the wrong type.
The `!![a, b; c, d]` syntax (provided by `Matrix.matrixNotation`) should be used instead.
-/
syntax (name := vecNotation) "![" term,* "]" : term
goal: Lean.ParserDescr

full_name: Matrix._aux_Mathlib_Data_Fin_VecNotation___macroRules_Matrix_vecNotation_1
code: macro_rules
  | `(![$term:term, $terms:term,*]) => `(vecCons $term ![$terms,*])
  | `(![$term:term]) => `(vecCons $term ![])
  | `(![]) => `(vecEmpty)
goal: Lean.Macro

full_name: Matrix.vecConsUnexpander
code: /-- Unexpander for the `![x, y, ...]` notation. -/
@[app_unexpander vecCons]
def vecConsUnexpander : Lean.PrettyPrinter.Unexpander
  
goal: Lean.PrettyPrinter.Unexpander

full_name: Matrix.vecEmptyUnexpander
code: /-- Unexpander for the `![]` notation. -/
@[app_unexpander vecEmpty]
def vecEmptyUnexpander : Lean.PrettyPrinter.Unexpander
  
goal: Lean.PrettyPrinter.Unexpander

full_name: Matrix.vecHead
code: /-- `vecHead v` gives the first entry of the vector `v` -/
def vecHead {n : ℕ} (v : Fin n.succ → α) : α 
goal: α

full_name: Matrix.vecTail
code: /-- `vecTail v` gives a vector consisting of all entries of `v` except the first -/
def vecTail {n : ℕ} (v : Fin n.succ → α) : Fin n → α 
goal: Fin n → α

full_name: PiFin.hasRepr
code: /-- Use `![...]` notation for displaying a vector `Fin n → α`, for example:

```
#eval ![1, 2] + ![3, 4] -- ![4, 6]
```
-/
instance _root_.PiFin.hasRepr [Repr α] : Repr (Fin n → α) 
goal: Repr (Fin n → α)

full_name: Matrix.empty_eq
code: theorem empty_eq (v : Fin 0 → α) : v = ![] 
goal: v = ![]

full_name: Matrix.head_fin_const
code: @[simp]
theorem head_fin_const (a : α) : (vecHead fun _ : Fin (n + 1) => a) = a 
goal: (Matrix.vecHead fun x => a) = a

full_name: Matrix.cons_val_zero
code: @[simp]
theorem cons_val_zero (x : α) (u : Fin m → α) : vecCons x u 0 = x 
goal: Matrix.vecCons x u 0 = x

full_name: Matrix.cons_val_zero'
code: theorem cons_val_zero' (h : 0 < m.succ) (x : α) (u : Fin m → α) : vecCons x u ⟨0, h⟩ = x 
goal: Matrix.vecCons x u ⟨0, h⟩ = x

full_name: Matrix.cons_val_succ
code: @[simp]
theorem cons_val_succ (x : α) (u : Fin m → α) (i : Fin m) : vecCons x u i.succ = u i 
goal: Matrix.vecCons x u i.succ = u i

full_name: Matrix.cons_val_succ'
code: @[simp]
theorem cons_val_succ' {i : ℕ} (h : i.succ < m.succ) (x : α) (u : Fin m → α) :
    vecCons x u ⟨i.succ, h⟩ = u ⟨i, Nat.lt_of_succ_lt_succ h⟩ 
goal: Matrix.vecCons x u ⟨i.succ, h⟩ = u ⟨i, ⋯⟩

full_name: Matrix.head_cons
code: @[simp]
theorem head_cons (x : α) (u : Fin m → α) : vecHead (vecCons x u) = x 
goal: Matrix.vecHead (Matrix.vecCons x u) = x

full_name: Matrix.tail_cons
code: @[simp]
theorem tail_cons (x : α) (u : Fin m → α) : vecTail (vecCons x u) = u 
goal: Matrix.vecTail (Matrix.vecCons x u) = u

full_name: Matrix.empty_val'
code: @[simp]
theorem empty_val' {n' : Type*} (j : n') : (fun i => (![] : Fin 0 → n' → α) i j) = ![] 
goal: (fun i => ![] i j) = ![]

full_name: Matrix.cons_head_tail
code: @[simp]
theorem cons_head_tail (u : Fin m.succ → α) : vecCons (vecHead u) (vecTail u) = u 
goal: Matrix.vecCons (Matrix.vecHead u) (Matrix.vecTail u) = u

full_name: Matrix.range_cons
code: @[simp]
theorem range_cons (x : α) (u : Fin n → α) : Set.range (vecCons x u) = {x} ∪ Set.range u 
goal: Set.range (Matrix.vecCons x u) = {x} ∪ Set.range u

full_name: Matrix.range_empty
code: @[simp]
theorem range_empty (u : Fin 0 → α) : Set.range u = ∅ 
goal: Set.range u = ∅

full_name: Matrix.range_cons_empty
code: theorem range_cons_empty (x : α) (u : Fin 0 → α) : Set.range (Matrix.vecCons x u) = {x} 
goal: Set.range (Matrix.vecCons x u) = {x}

full_name: Matrix.range_cons_cons_empty
code: theorem range_cons_cons_empty (x y : α) (u : Fin 0 → α) :
    Set.range (vecCons x <| vecCons y u) = {x, y} 
goal: Set.range (Matrix.vecCons x (Matrix.vecCons y u)) = {x, y}

full_name: Matrix.vecCons_const
code: @[simp]
theorem vecCons_const (a : α) : (vecCons a fun _ : Fin n => a) = fun _ => a 
goal: (Matrix.vecCons a fun x => a) = fun x => a

full_name: Matrix.vec_single_eq_const
code: theorem vec_single_eq_const (a : α) : ![a] = fun _ => a 
goal: ![a] = fun x => a

full_name: Matrix.cons_val_one
code: /-- `![a, b, ...] 1` is equal to `b`.

  The simplifier needs a special lemma for length `≥ 2`, in addition to
  `cons_val_succ`, because `1 : Fin 1 = 0 : Fin 1`.
-/
@[simp]
theorem cons_val_one (x : α) (u : Fin m.succ → α) : vecCons x u 1 = vecHead u 
goal: Matrix.vecCons x u 1 = Matrix.vecHead u

full_name: Matrix.cons_val_two
code: @[simp]
theorem cons_val_two (x : α) (u : Fin m.succ.succ → α) : vecCons x u 2 = vecHead (vecTail u) 
goal: Matrix.vecCons x u 2 = Matrix.vecHead (Matrix.vecTail u)

full_name: Matrix.cons_val_three
code: @[simp]
lemma cons_val_three (x : α) (u : Fin m.succ.succ.succ → α) :
    vecCons x u 3 = vecHead (vecTail (vecTail u)) 
goal: Matrix.vecCons x u 3 = Matrix.vecHead (Matrix.vecTail (Matrix.vecTail u))

full_name: Matrix.cons_val_four
code: @[simp]
lemma cons_val_four (x : α) (u : Fin m.succ.succ.succ.succ → α) :
    vecCons x u 4 = vecHead (vecTail (vecTail (vecTail u))) 
goal: Matrix.vecCons x u 4 = Matrix.vecHead (Matrix.vecTail (Matrix.vecTail (Matrix.vecTail u)))

full_name: Matrix.cons_val_fin_one
code: @[simp]
theorem cons_val_fin_one (x : α) (u : Fin 0 → α) : ∀ (i : Fin 1), vecCons x u i = x 
goal: Matrix.vecCons x u i = x

full_name: Matrix.cons_fin_one
code: theorem cons_fin_one (x : α) (u : Fin 0 → α) : vecCons x u = fun _ => x 
goal: Matrix.vecCons x u = fun x_1 => x

full_name: PiFin.toExpr
code: protected instance _root_.PiFin.toExpr [ToLevel.{u}] [ToExpr α] (n : ℕ) : ToExpr (Fin n → α) 
goal: Lean.ToExpr (Fin n → α)

full_name: Matrix.vecAppend
code: /-- `vecAppend ho u v` appends two vectors of lengths `m` and `n` to produce
one of length `o = m + n`. This is a variant of `Fin.append` with an additional `ho` argument,
which provides control of definitional equality for the vector length.

This turns out to be helpful when providing simp lemmas to reduce `![a, b, c] n`, and also means
that `vecAppend ho u v 0` is valid. `Fin.append u v 0` is not valid in this case because there is
no `Zero (Fin (m + n))` instance. -/
def vecAppend {α : Type*} {o : ℕ} (ho : o = m + n) (u : Fin m → α) (v : Fin n → α) : Fin o → α 
goal: Fin o → α

full_name: Matrix.vecAppend_eq_ite
code: theorem vecAppend_eq_ite {α : Type*} {o : ℕ} (ho : o = m + n) (u : Fin m → α) (v : Fin n → α) :
    vecAppend ho u v = fun i : Fin o =>
      if h : (i : ℕ) < m then u ⟨i, h⟩ else v ⟨(i : ℕ) - m, by omega⟩ 
goal: Matrix.vecAppend ho u v = fun i => if h : ↑i < m then u ⟨↑i, h⟩ else v ⟨↑i - m, ⋯⟩

full_name: Matrix.vecAppend_apply_zero
code: @[simp]
theorem vecAppend_apply_zero {α : Type*} {o : ℕ} (ho : o + 1 = m + 1 + n) (u : Fin (m + 1) → α)
    (v : Fin n → α) : vecAppend ho u v 0 = u 0 
goal: Matrix.vecAppend ho u v 0 = u 0

full_name: Matrix.empty_vecAppend
code: @[simp]
theorem empty_vecAppend (v : Fin n → α) : vecAppend n.zero_add.symm ![] v = v 
goal: Matrix.vecAppend ⋯ ![] v = v

full_name: Matrix.cons_vecAppend
code: @[simp]
theorem cons_vecAppend (ho : o + 1 = m + 1 + n) (x : α) (u : Fin m → α) (v : Fin n → α) :
    vecAppend ho (vecCons x u) v = vecCons x (vecAppend (by omega) u v) 
goal: Matrix.vecAppend ho (Matrix.vecCons x u) v = Matrix.vecCons x (Matrix.vecAppend ⋯ u v)

full_name: Matrix.vecAlt0
code: /-- `vecAlt0 v` gives a vector with half the length of `v`, with
only alternate elements (even-numbered). -/
def vecAlt0 (hm : m = n + n) (v : Fin m → α) (k : Fin n) : α 
goal: α

full_name: Matrix.vecAlt1
code: /-- `vecAlt1 v` gives a vector with half the length of `v`, with
only alternate elements (odd-numbered). -/
def vecAlt1 (hm : m = n + n) (v : Fin m → α) (k : Fin n) : α 
goal: α

full_name: Matrix.vecAlt0_vecAppend
code: theorem vecAlt0_vecAppend (v : Fin n → α) :
    vecAlt0 rfl (vecAppend rfl v v) = v ∘ (fun n ↦ n + n) 
goal: Matrix.vecAlt0 ⋯ (Matrix.vecAppend ⋯ v v) = v ∘ fun n_1 => n_1 + n_1

full_name: Matrix.vecAlt1_vecAppend
code: theorem vecAlt1_vecAppend (v : Fin (n + 1) → α) :
    vecAlt1 rfl (vecAppend rfl v v) = v ∘ (fun n ↦ (n + n) + 1) 
goal: Matrix.vecAlt1 ⋯ (Matrix.vecAppend ⋯ v v) = v ∘ fun n_1 => n_1 + n_1 + 1

full_name: Matrix.vecHead_vecAlt0
code: @[simp]
theorem vecHead_vecAlt0 (hm : m + 2 = n + 1 + (n + 1)) (v : Fin (m + 2) → α) :
    vecHead (vecAlt0 hm v) = v 0 
goal: Matrix.vecHead (Matrix.vecAlt0 hm v) = v 0

full_name: Matrix.vecHead_vecAlt1
code: @[simp]
theorem vecHead_vecAlt1 (hm : m + 2 = n + 1 + (n + 1)) (v : Fin (m + 2) → α) :
    vecHead (vecAlt1 hm v) = v 1 
goal: Matrix.vecHead (Matrix.vecAlt1 hm v) = v 1

full_name: Matrix.cons_vec_bit0_eq_alt0
code: @[simp]
theorem cons_vec_bit0_eq_alt0 (x : α) (u : Fin n → α) (i : Fin (n + 1)) :
    vecCons x u (i + i) = vecAlt0 rfl (vecAppend rfl (vecCons x u) (vecCons x u)) i 
goal: Matrix.vecCons x u (i + i) = Matrix.vecAlt0 ⋯ (Matrix.vecAppend ⋯ (Matrix.vecCons x u) (Matrix.vecCons x u)) i

full_name: Matrix.cons_vec_bit1_eq_alt1
code: @[simp]
theorem cons_vec_bit1_eq_alt1 (x : α) (u : Fin n → α) (i : Fin (n + 1)) :
    vecCons x u ((i + i) + 1) = vecAlt1 rfl (vecAppend rfl (vecCons x u) (vecCons x u)) i 
goal: Matrix.vecCons x u (i + i + 1) = Matrix.vecAlt1 ⋯ (Matrix.vecAppend ⋯ (Matrix.vecCons x u) (Matrix.vecCons x u)) i

full_name: Matrix.cons_vecAlt0
code: @[simp]
theorem cons_vecAlt0 (h : m + 1 + 1 = n + 1 + (n + 1)) (x y : α) (u : Fin m → α) :
    vecAlt0 h (vecCons x (vecCons y u)) = vecCons x (vecAlt0 (by omega) u) 
goal: Matrix.vecAlt0 h (Matrix.vecCons x (Matrix.vecCons y u)) = Matrix.vecCons x (Matrix.vecAlt0 ⋯ u)

full_name: Matrix.empty_vecAlt0
code: @[simp]
theorem empty_vecAlt0 (α) {h} : vecAlt0 h (![] : Fin 0 → α) = ![] 
goal: Matrix.vecAlt0 h ![] = ![]

full_name: Matrix.cons_vecAlt1
code: @[simp]
theorem cons_vecAlt1 (h : m + 1 + 1 = n + 1 + (n + 1)) (x y : α) (u : Fin m → α) :
    vecAlt1 h (vecCons x (vecCons y u)) = vecCons y (vecAlt1 (by omega) u) 
goal: Matrix.vecAlt1 h (Matrix.vecCons x (Matrix.vecCons y u)) = Matrix.vecCons y (Matrix.vecAlt1 ⋯ u)

full_name: Matrix.empty_vecAlt1
code: @[simp]
theorem empty_vecAlt1 (α) {h} : vecAlt1 h (![] : Fin 0 → α) = ![] 
goal: Matrix.vecAlt1 h ![] = ![]

full_name: Matrix.const_fin1_eq
code: lemma const_fin1_eq (x : α) : (fun _ : Fin 1 => x) = ![x] 
goal: (fun x_1 => x) = ![x]