Built with doc-gen4, running Lean4. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓to navigate, Ctrl+🖱️to focus. On Mac, use Cmdinstead of Ctrl.
import Mt.Utils.Fin

namespace Mt.Utils.List

theorem 
get_in: ∀ {T : Type u} (l : List T) (idx : Fin (List.length l)), List.get l idx ∈ l
get_in
{
T: Type u
T
:
Type u: Type (u + 1)
Type u
} (
l: List T
l
:
List: Type ?u.4 → Type ?u.4
List
T: Type u
T
) (
idx: Fin (List.length l)
idx
:
Fin: Nat → Type
Fin
l: List T
l
.
length: {α : Type ?u.7} → List α → Nat
length
) : (
l: List T
l
.
get: {α : Type ?u.19} → (as : List α) → Fin (List.length as) → α
get
idx: Fin (List.length l)
idx
) ∈
l: List T
l
:=match
l: List T
l
,
idx: Fin (List.length l)
idx
with |
a: T
a
::
_: List T
_
, ⟨
0: Nat
0
, _⟩ =>
List.Mem.head: ∀ {α : Type ?u.88} (a : α) (as : List α), List.Mem a (a :: as)
List.Mem.head
a: T
a
_: List ?m.89
_
|
_: T
_
::
as: List T
as
, ⟨
n: Nat
n
+ 1,
isLt: n + 1 < List.length (head✝ :: as)
isLt
⟩ =>
List.Mem.tail: ∀ {α : Type ?u.208} (a : α) {b : α} {as : List α}, List.Mem b as → List.Mem b (a :: as)
List.Mem.tail
_: ?m.209
_
<|
get_in: ∀ {T : Type u} (l : List T) (idx : Fin (List.length l)), List.get l idx ∈ l
get_in
as: List T
as
⟨
n: Nat
n
,
Nat.le_of_succ_le_succ: ∀ {n m : Nat}, Nat.succ n ≤ Nat.succ m → n ≤ m
Nat.le_of_succ_le_succ
isLt: n + 1 < List.length (head✝ :: as)
isLt
⟩ theorem
get_of_set: ∀ {T : Type u} (l : List T) (idx : Nat) (a : T) (isLt : idx < List.length (List.set l idx a)), List.get (List.set l idx a) { val := idx, isLt := isLt } = a
get_of_set
{
T: Type u
T
:
Type u: Type (u + 1)
Type u
} (
l: List T
l
:
List: Type ?u.672 → Type ?u.672
List
T: Type u
T
) (
idx: Nat
idx
:
Nat: Type
Nat
) (
a: T
a
:
T: Type u
T
) (
isLt: idx < List.length (List.set l idx a)
isLt
:
idx: Nat
idx
< (
l: List T
l
.
set: {α : Type ?u.680} → List α → Nat → α → List α
set
idx: Nat
idx
a: T
a
).
length: {α : Type ?u.687} → List α → Nat
length
) : (
l: List T
l
.
set: {α : Type ?u.698} → List α → Nat → α → List α
set
idx: Nat
idx
a: T
a
).
get: {α : Type ?u.704} → (as : List α) → Fin (List.length as) → α
get
⟨
idx: Nat
idx
,
isLt: idx < List.length (List.set l idx a)
isLt
⟩ =
a: T
a
:=match
l: List T
l
,
idx: Nat
idx
with | _::_,
0: Nat
0
=>
rfl: ∀ {α : Sort ?u.784} {a : α}, a = a
rfl
| _::
xs: List T
xs
,
n: Nat
n
+ 1 =>
get_of_set: ∀ {T : Type u} (l : List T) (idx : Nat) (a : T) (isLt : idx < List.length (List.set l idx a)), List.get (List.set l idx a) { val := idx, isLt := isLt } = a
get_of_set
xs: List T
xs
n: Nat
n
a: T
a
<|
Nat.lt_of_succ_lt_succ: ∀ {n m : Nat}, Nat.succ n < Nat.succ m → n < m
Nat.lt_of_succ_lt_succ
isLt: n + 1 < List.length (List.set (head✝ :: xs) (n + 1) a)
isLt
theorem
erase_subset: ∀ {T : Type u} {a : T} (l : List T) (idx : Nat), a ∈ List.eraseIdx l idx → a ∈ l
erase_subset
{
T: Type u
T
:
Type u: Type (u + 1)
Type u
} {
a: T
a
:
T: Type u
T
} (
l: List T
l
:
List: Type ?u.1483 → Type ?u.1483
List
T: Type u
T
) (
idx: Nat
idx
:
Nat: Type
Nat
) :
a: T
a
∈ (
l: List T
l
.
eraseIdx: {α : Type ?u.1494} → List α → Nat → List α
eraseIdx
idx: Nat
idx
) →
a: T
a
∈
l: List T
l
:=match
l: List T
l
,
idx: Nat
idx
with | [], _ =>
id: ∀ {α : Sort ?u.1545}, α → α
id
|
x: T
x
::
xs: List T
xs
,
0: Nat
0
=> fun
h: ?m.1603
h
=>
List.Mem.tail: ∀ {α : Type ?u.1605} (a : α) {b : α} {as : List α}, List.Mem b as → List.Mem b (a :: as)
List.Mem.tail
_: ?m.1606
_
h: ?m.1603
h
|
x: T
x
::
xs: List T
xs
,
n: Nat
n
+1 =>
T: Type u

a: T

l: List T

idx: Nat

x: T

xs: List T

n: Nat


a ∈ List.eraseIdx (x :: xs) (n + 1) → a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

x: T

xs: List T

n: Nat

h: a ∈ List.eraseIdx (x :: xs) (n + 1)


a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

x: T

xs: List T

n: Nat


a ∈ List.eraseIdx (x :: xs) (n + 1) → a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

x: T

xs: List T

n: Nat

h: a ∈ List.eraseIdx (x :: xs) (n + 1)


a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

x: T

xs: List T

n: Nat


a ∈ List.eraseIdx (x :: xs) (n + 1) → a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

xs: List T

n: Nat


head
a ∈ a :: xs
T: Type u

a: T

l: List T

idx: Nat

x: T

xs: List T

n: Nat


tail
a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

x: T

xs: List T

n: Nat


a ∈ List.eraseIdx (x :: xs) (n + 1) → a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

xs: List T

n: Nat


head
a ∈ a :: xs
T: Type u

a: T

l: List T

idx: Nat

xs: List T

n: Nat


head
a ∈ a :: xs
T: Type u

a: T

l: List T

idx: Nat

x: T

xs: List T

n: Nat


tail
a ∈ x :: xs

Goals accomplished! 🐙
T: Type u

a: T

l: List T

idx: Nat

x: T

xs: List T

n: Nat


a ∈ List.eraseIdx (x :: xs) (n + 1) → a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

x: T

xs: List T

n: Nat


tail
a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

x: T

xs: List T

n: Nat


tail
a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

x: T

xs: List T

n: Nat


tail
a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

x: T

xs: List T

n: Nat



Goals accomplished! 🐙

Goals accomplished! 🐙
theorem
set_subset: ∀ {T : Type u} {a : T} (l : List T) (idx : Nat) (new_value : T), a ∈ List.set l idx new_value → a = new_value ∨ a ∈ l
set_subset
{
T: Type u
T
:
Type u: Type (u + 1)
Type u
} {
a: T
a
:
T: Type u
T
} (
l: List T
l
:
List: Type ?u.2325 → Type ?u.2325
List
T: Type u
T
) (
idx: Nat
idx
:
Nat: Type
Nat
) (
new_value: T
new_value
:
T: Type u
T
) :
a: T
a
∈ (
l: List T
l
.
set: {α : Type ?u.2338} → List α → Nat → α → List α
set
idx: Nat
idx
new_value: T
new_value
) →
a: T
a
=
new_value: T
new_value
∨
a: T
a
∈
l: List T
l
:=match
l: List T
l
,
idx: Nat
idx
with | [], _ =>
Or.inr: ∀ {a b : Prop}, b → a ∨ b
Or.inr
|
x: T
x
::
xs: List T
xs
,
0: Nat
0
=>
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T


a ∈ List.set (x :: xs) 0 new_value → a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

h: a ∈ List.set (x :: xs) 0 new_value


a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T


a ∈ List.set (x :: xs) 0 new_value → a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

h: a ∈ List.set (x :: xs) 0 new_value


a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T


a ∈ List.set (x :: xs) 0 new_value → a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

x: T

xs: List T


head
a = a ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T


tail
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T


a ∈ List.set (x :: xs) 0 new_value → a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

x: T

xs: List T


head
a = a ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

x: T

xs: List T


head
a = a ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T


tail
a = new_value ∨ a ∈ x :: xs

Goals accomplished! 🐙
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T


a ∈ List.set (x :: xs) 0 new_value → a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T


tail
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T


tail
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T


tail
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T



Goals accomplished! 🐙

Goals accomplished! 🐙
|
x: T
x
::
xs: List T
xs
,
n: Nat
n
+1 =>
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


a ∈ List.set (x :: xs) (n + 1) new_value → a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat

h: a ∈ List.set (x :: xs) (n + 1) new_value


a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


a ∈ List.set (x :: xs) (n + 1) new_value → a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat

h: a ∈ List.set (x :: xs) (n + 1) new_value


a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


a ∈ List.set (x :: xs) (n + 1) new_value → a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value: T

xs: List T

n: Nat


head
a = new_value ∨ a ∈ a :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


tail
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


a ∈ List.set (x :: xs) (n + 1) new_value → a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value: T

xs: List T

n: Nat


head
a = new_value ∨ a ∈ a :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value: T

xs: List T

n: Nat


head
a = new_value ∨ a ∈ a :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


tail
a = new_value ∨ a ∈ x :: xs

Goals accomplished! 🐙
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


a ∈ List.set (x :: xs) (n + 1) new_value → a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


tail
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


tail
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


tail
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


?m.3164 ∈ List.set xs n new_value

Goals accomplished! 🐙
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


tail.inl
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


tail.inr
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


tail
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


tail.inl
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


tail.inl
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


tail.inr
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


tail.inl
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


a = new_value

Goals accomplished! 🐙

Goals accomplished! 🐙
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


tail
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


tail.inr
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


tail.inr
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat


tail.inr
a = new_value ∨ a ∈ x :: xs
T: Type u

a: T

l: List T

idx: Nat

new_value, x: T

xs: List T

n: Nat



Goals accomplished! 🐙

Goals accomplished! 🐙
theorem
index_exists: ∀ {T : Type u} {a : T} (l : List T), a ∈ l → ∃ i, List.get l i = a
index_exists
{
T: Type u
T
:
Type u: Type (u + 1)
Type u
} {
a: T
a
:
T: Type u
T
} (
l: List T
l
:
List: Type ?u.3681 → Type ?u.3681
List
T: Type u
T
) :
a: T
a
∈
l: List T
l
→ ∃ i :
Fin: Nat → Type
Fin
l: List T
l
.
length: {α : Type ?u.3704} → List α → Nat
length
,
l: List T
l
.
get: {α : Type ?u.3710} → (as : List α) → Fin (List.length as) → α
get
i =
a: T
a
:=fun
a_in_l: ?m.3724
a_in_l
=> match
l: List T
l
,
a_in_l: ?m.3724
a_in_l
with |
x: T
x
::
xs: List T
xs
,
a_in_l: a ∈ x :: xs
a_in_l
=>
T: Type u

a: T

l: List T

x: T

xs: List T

a_in_l: a ∈ x :: xs


∃ i, List.get (x :: xs) i = a
T: Type u

a: T

l: List T

a_in_l: a ∈ l

xs: List T


head
∃ i, List.get (a :: xs) i = a
T: Type u

a: T

l: List T

a_in_l: a ∈ l

x: T

xs: List T


tail
∃ i, List.get (x :: xs) i = a
T: Type u

a: T

l: List T

x: T

xs: List T

a_in_l: a ∈ x :: xs


∃ i, List.get (x :: xs) i = a
T: Type u

a: T

l: List T

a_in_l: a ∈ l

xs: List T


head
∃ i, List.get (a :: xs) i = a
T: Type u

a: T

l: List T

a_in_l: a ∈ l

xs: List T


head
∃ i, List.get (a :: xs) i = a
T: Type u

a: T

l: List T

a_in_l: a ∈ l

x: T

xs: List T


tail
∃ i, List.get (x :: xs) i = a
T: Type u

a: T

l: List T

a_in_l: a ∈ l

xs: List T


head
∃ i, List.get (a :: xs) i = a
T: Type u

a: T

l: List T

a_in_l: a ∈ l

xs: List T


0 < List.length (a :: xs)

Goals accomplished! 🐙

Goals accomplished! 🐙
T: Type u

a: T

l: List T

x: T

xs: List T

a_in_l: a ∈ x :: xs


∃ i, List.get (x :: xs) i = a
T: Type u

a: T

l: List T

a_in_l: a ∈ l

x: T

xs: List T


tail
∃ i, List.get (x :: xs) i = a
T: Type u

a: T

l: List T

a_in_l: a ∈ l

x: T

xs: List T


tail
∃ i, List.get (x :: xs) i = a
T: Type u

a: T

l: List T

a_in_l: a ∈ l

x: T

xs: List T


tail
∃ i, List.get (x :: xs) i = a
T: Type u

a: T

l: List T

a_in_l: a ∈ l

x: T

xs: List T


?m.4575 ∈ xs

Goals accomplished! 🐙
T: Type u

a: T

l: List T

a_in_l: a ∈ l

x: T

xs: List T


tail
∀ (a_1 : Fin (List.length xs)), List.get xs a_1 = a → ∃ i, List.get (x :: xs) i = a
T: Type u

a: T

l: List T

a_in_l: a ∈ l

x: T

xs: List T


tail
∃ i, List.get (x :: xs) i = a
T: Type u

a: T

l: List T

a_in_l: a ∈ l

x: T

xs: List T

i: Fin (List.length xs)

xs_get_i: List.get xs i = a


tail
∃ i, List.get (x :: xs) i = a
T: Type u

a: T

l: List T

a_in_l: a ∈ l

x: T

xs: List T


tail
∃ i, List.get (x :: xs) i = a
T: Type u

a: T

l: List T

a_in_l: a ∈ l

x: T

xs: List T

i: Fin (List.length xs)

xs_get_i: List.get xs i = a


tail
∃ i, List.get (x :: xs) i = a
T: Type u

a: T

l: List T

a_in_l: a ∈ l

x: T

xs: List T

i: Fin (List.length xs)

xs_get_i: List.get xs i = a


i.val + 1 < List.length (x :: xs)
T: Type u

a: T

l: List T

a_in_l: a ∈ l

x: T

xs: List T

i: Fin (List.length xs)

xs_get_i: List.get xs i = a


i.val + 1 ≤ List.length xs
T: Type u

a: T

l: List T

a_in_l: a ∈ l

x: T

xs: List T

i: Fin (List.length xs)

xs_get_i: List.get xs i = a


i.val + 1 < List.length (x :: xs)
T: Type u

a: T

l: List T

a_in_l: a ∈ l

x: T

xs: List T

i: Fin (List.length xs)

xs_get_i: List.get xs i = a


i.val + 1 ≤ List.length xs
T: Type u

a: T

l: List T

a_in_l: a ∈ l

x: T

xs: List T

i: Fin (List.length xs)

xs_get_i: List.get xs i = a


i.val + 1 < List.length (x :: xs)

Goals accomplished! 🐙

Goals accomplished! 🐙
theorem
erase_set: ∀ {T : Type u} (l : List T) (idx : Nat) (new_value : T), List.eraseIdx (List.set l idx new_value) idx = List.eraseIdx l idx
erase_set
{
T: Type u
T
:
Type u: Type (u + 1)
Type u
} (
l: List T
l
:
List: Type ?u.5691 → Type ?u.5691
List
T: Type u
T
) (
idx: Nat
idx
:
Nat: Type
Nat
) (
new_value: T
new_value
:
T: Type u
T
) : (
l: List T
l
.
set: {α : Type ?u.5699} → List α → Nat → α → List α
set
idx: Nat
idx
new_value: T
new_value
).
eraseIdx: {α : Type ?u.5706} → List α → Nat → List α
eraseIdx
idx: Nat
idx
=
l: List T
l
.
eraseIdx: {α : Type ?u.5711} → List α → Nat → List α
eraseIdx
idx: Nat
idx
:=match
l: List T
l
,
idx: Nat
idx
with | [], _ =>
rfl: ∀ {α : Sort ?u.5739} {a : α}, a = a
rfl
| _::_,
0: Nat
0
=>
rfl: ∀ {α : Sort ?u.5796} {a : α}, a = a
rfl
|
x: T
x
::
xs: List T
xs
,
n: Nat
n
+1 =>
congrArg: ∀ {α : Sort ?u.5926} {β : Sort ?u.5925} {a₁ a₂ : α} (f : α → β), a₁ = a₂ → f a₁ = f a₂
congrArg
(
x: T
x
:: .) <|
erase_set: ∀ {T : Type u} (l : List T) (idx : Nat) (new_value : T), List.eraseIdx (List.set l idx new_value) idx = List.eraseIdx l idx
erase_set
xs: List T
xs
n: Nat
n
new_value: T
new_value
theorem
eq_of_in_map: ∀ {U V : Type u} {f : U → V} {l : List U} {v : V}, v ∈ List.map f l → ∃ u, u ∈ l ∧ v = f u
eq_of_in_map
{
U: Type u
U
V: Type u
V
:
Type u: Type (u + 1)
Type u
} {
f: U → V
f
:
U: Type u
U
->
V: Type u
V
} {
l: List U
l
:
List: Type ?u.6207 → Type ?u.6207
List
U: Type u
U
} {
v: V
v
:
V: Type u
V
} :
v: V
v
∈ (
l: List U
l
.
map: {α : Type ?u.6219} → {β : Type ?u.6218} → (α → β) → List α → List β
map
f: U → V
f
) → ∃
u: ?m.6243
u
,
u: ?m.6243
u
∈
l: List U
l
∧
v: V
v
=
f: U → V
f
u: ?m.6243
u
:=
U, V: Type u

f: U → V

l: List U

v: V


v ∈ List.map f l → ∃ u, u ∈ l ∧ v = f u
U, V: Type u

f: U → V

l: List U

v: V

v_in_map: v ∈ List.map f l


∃ u, u ∈ l ∧ v = f u
U, V: Type u

f: U → V

l: List U

v: V


v ∈ List.map f l → ∃ u, u ∈ l ∧ v = f u
U, V: Type u

f: U → V

v: V

v_in_map: v ∈ List.map f []


nil
∃ u, u ∈ [] ∧ v = f u
U, V: Type u

f: U → V

v: V

head✝: U

tail✝: List U

v_in_map: v ∈ List.map f (head✝ :: tail✝)


cons
∃ u, u ∈ head✝ :: tail✝ ∧ v = f u
U, V: Type u

f: U → V

l: List U

v: V


v ∈ List.map f l → ∃ u, u ∈ l ∧ v = f u
U, V: Type u

f: U → V

v: V

v_in_map: v ∈ List.map f []


nil
∃ u, u ∈ [] ∧ v = f u
U, V: Type u

f: U → V

v: V

v_in_map: v ∈ List.map f []


nil
∃ u, u ∈ [] ∧ v = f u
U, V: Type u

f: U → V

v: V

head✝: U

tail✝: List U

v_in_map: v ∈ List.map f (head✝ :: tail✝)


cons
∃ u, u ∈ head✝ :: tail✝ ∧ v = f u

Goals accomplished! 🐙
U, V: Type u

f: U → V

l: List U

v: V


v ∈ List.map f l → ∃ u, u ∈ l ∧ v = f u
U, V: Type u

f: U → V

v: V

head✝: U

tail✝: List U

v_in_map: v ∈ List.map f (head✝ :: tail✝)


cons
∃ u, u ∈ head✝ :: tail✝ ∧ v = f u
U, V: Type u

f: U → V

v: V

head✝: U

tail✝: List U

v_in_map: v ∈ List.map f (head✝ :: tail✝)


cons
∃ u, u ∈ head✝ :: tail✝ ∧ v = f u
U, V: Type u

f: U → V

v: V

head: U

tail: List U

IH: v ∈ List.map f tail → ∃ u, u ∈ tail ∧ v = f u

v_in_map: v ∈ List.map f (head :: tail)


cons
∃ u, u ∈ head :: tail ∧ v = f u
U, V: Type u

f: U → V

v: V

head✝: U

tail✝: List U

v_in_map: v ∈ List.map f (head✝ :: tail✝)


cons
∃ u, u ∈ head✝ :: tail✝ ∧ v = f u
U, V: Type u

f: U → V

head: U

tail: List U

IH: f head ∈ List.map f tail → ∃ u, u ∈ tail ∧ f head = f u


cons.head
∃ u, u ∈ head :: tail ∧ f head = f u
U, V: Type u

f: U → V

v: V

head: U

tail: List U

IH: v ∈ List.map f tail → ∃ u, u ∈ tail ∧ v = f u


cons.tail
∃ u, u ∈ head :: tail ∧ v = f u
U, V: Type u

f: U → V

v: V

head✝: U

tail✝: List U

v_in_map: v ∈ List.map f (head✝ :: tail✝)


cons
∃ u, u ∈ head✝ :: tail✝ ∧ v = f u
U, V: Type u

f: U → V

head: U

tail: List U

IH: f head ∈ List.map f tail → ∃ u, u ∈ tail ∧ f head = f u


cons.head
∃ u, u ∈ head :: tail ∧ f head = f u
U, V: Type u

f: U → V

head: U

tail: List U

IH: f head ∈ List.map f tail → ∃ u, u ∈ tail ∧ f head = f u


cons.head
∃ u, u ∈ head :: tail ∧ f head = f u
U, V: Type u

f: U → V

v: V

head: U

tail: List U

IH: v ∈ List.map f tail → ∃ u, u ∈ tail ∧ v = f u


cons.tail
∃ u, u ∈ head :: tail ∧ v = f u

Goals accomplished! 🐙
U, V: Type u

f: U → V

v: V

head✝: U

tail✝: List U

v_in_map: v ∈ List.map f (head✝ :: tail✝)


cons
∃ u, u ∈ head✝ :: tail✝ ∧ v = f u
U, V: Type u

f: U → V

v: V

head: U

tail: List U

IH: v ∈ List.map f tail → ∃ u, u ∈ tail ∧ v = f u


cons.tail
∃ u, u ∈ head :: tail ∧ v = f u
U, V: Type u

f: U → V

v: V

head: U

tail: List U

IH: v ∈ List.map f tail → ∃ u, u ∈ tail ∧ v = f u


cons.tail
∃ u, u ∈ head :: tail ∧ v = f u
U, V: Type u

f: U → V

v: V

head: U

tail: List U

IH: v ∈ List.map f tail → ∃ u, u ∈ tail ∧ v = f u

v_in_map_of_tail: List.Mem v (List.map f tail)


cons.tail
∃ u, u ∈ head :: tail ∧ v = f u
U, V: Type u

f: U → V

v: V

head: U

tail: List U

IH: v ∈ List.map f tail → ∃ u, u ∈ tail ∧ v = f u


cons.tail
∃ u, u ∈ head :: tail ∧ v = f u
U, V: Type u

f: U → V

v: V

head: U

tail: List U

IH: v ∈ List.map f tail → ∃ u, u ∈ tail ∧ v = f u

v_in_map_of_tail: List.Mem v (List.map f tail)

w✝: U


cons.tail.intro
∃ u, u ∈ head :: tail ∧ v = f u
U, V: Type u

f: U → V

v: V

head: U

tail: List U

IH: v ∈ List.map f tail → ∃ u, u ∈ tail ∧ v = f u


cons.tail
∃ u, u ∈ head :: tail ∧ v = f u
U, V: Type u

f: U → V

v: V

head: U

tail: List U

IH: v ∈ List.map f tail → ∃ u, u ∈ tail ∧ v = f u

v_in_map_of_tail: List.Mem v (List.map f tail)

u: U

u_hyp: u ∈ tail ∧ v = f u


cons.tail.intro
∃ u, u ∈ head :: tail ∧ v = f u
U, V: Type u

f: U → V

v: V

head: U

tail: List U

IH: v ∈ List.map f tail → ∃ u, u ∈ tail ∧ v = f u


cons.tail
∃ u, u ∈ head :: tail ∧ v = f u

Goals accomplished! 🐙
theorem
get_congr: ∀ {T : Type u} {l l' : List T} (idx : Fin (List.length l)) (eq : l = l'), List.get l idx = List.get l' (Fin.cast idx (_ : List.length l = List.length l'))
get_congr
{
T: Type u
T
:
Type u: Type (u + 1)
Type u
} {
l: List T
l
l': List T
l'
:
List: Type ?u.6901 → Type ?u.6901
List
T: Type u
T
} (
idx: Fin (List.length l)
idx
:
Fin: Nat → Type
Fin
l: List T
l
.
length: {α : Type ?u.6904} → List α → Nat
length
) (
eq: l = l'
eq
:
l: List T
l
=
l': List T
l'
) :
l: List T
l
.
get: {α : Type ?u.6916} → (as : List α) → Fin (List.length as) → α
get
idx: Fin (List.length l)
idx
=
l': List T
l'
.
get: {α : Type ?u.6922} → (as : List α) → Fin (List.length as) → α
get
(
Fin.cast: {n m : Nat} → Fin n → n = m → Fin m
Fin.cast
idx: Fin (List.length l)
idx
(
congrArg: ∀ {α : Sort ?u.6930} {β : Sort ?u.6929} {a₁ a₂ : α} (f : α → β), a₁ = a₂ → f a₁ = f a₂
congrArg
_: ?m.6931 → ?m.6932
_
eq: l = l'
eq
)) :=
Eq.rec: ∀ {α : Sort ?u.6952} {a : α} {motive : (a_1 : α) → a = a_1 → Sort ?u.6953}, motive a (_ : a = a) → ∀ {a_1 : α} (t : a = a_1), motive a_1 t
Eq.rec
(motive :=λ
l': ?m.6971
l'
eq: ?m.6974
eq
=>
l: List T
l
.
get: {α : Type ?u.6977} → (as : List α) → Fin (List.length as) → α
get
idx: Fin (List.length l)
idx
=
l': ?m.6971
l'
.
get: {α : Type ?u.7034} → (as : List α) → Fin (List.length as) → α
get
(
Fin.cast: {n m : Nat} → Fin n → n = m → Fin m
Fin.cast
idx: Fin (List.length l)
idx
(
congrArg: ∀ {α : Sort ?u.7042} {β : Sort ?u.7041} {a₁ a₂ : α} (f : α → β), a₁ = a₂ → f a₁ = f a₂
congrArg
_: ?m.7043 → ?m.7044
_
eq: ?m.6974
eq
)))
rfl: ∀ {α : Sort ?u.6991} {a : α}, a = a
rfl
eq: l = l'
eq
theorem
get_congr': ∀ {T : Type u} {l l' : List T} {i : Fin (List.length l)} {j : Fin (List.length l')}, l = l' → i.val = j.val → List.get l i = List.get l' j
get_congr'
{
T: Type u
T
:
Type u: Type (u + 1)
Type u
} {
l: List T
l
l': List T
l'
:
List: Type ?u.7065 → Type ?u.7065
List
T: Type u
T
} {i :
Fin: Nat → Type
Fin
l: List T
l
.
length: {α : Type ?u.7068} → List α → Nat
length
} {j :
Fin: Nat → Type
Fin
l': List T
l'
.
length: {α : Type ?u.7075} → List α → Nat
length
} (
l_eq: l = l'
l_eq
:
l: List T
l
=
l': List T
l'
) (
i_eq: i.val = j.val
i_eq
: i.
val: {n : Nat} → Fin n → Nat
val
= j.
val: {n : Nat} → Fin n → Nat
val
) :
l: List T
l
.
get: {α : Type ?u.7093} → (as : List α) → Fin (List.length as) → α
get
i =
l': List T
l'
.
get: {α : Type ?u.7098} → (as : List α) → Fin (List.length as) → α
get
j :=
T: Type u

l, l': List T

i: Fin (List.length l)

j: Fin (List.length l')

l_eq: l = l'

i_eq: i.val = j.val


T: Type u

l, l': List T

i: Fin (List.length l)

j: Fin (List.length l')

l_eq: l = l'

i_eq: i.val = j.val

this: j = Fin.cast i (_ : List.length l = List.length l')


T: Type u

l, l': List T

i: Fin (List.length l)

j: Fin (List.length l')

l_eq: l = l'

i_eq: i.val = j.val


T: Type u

l, l': List T

i: Fin (List.length l)

j: Fin (List.length l')

l_eq: l = l'

i_eq: i.val = j.val

this: j = Fin.cast i (_ : List.length l = List.length l')


T: Type u

l, l': List T

i: Fin (List.length l)

j: Fin (List.length l')

l_eq: l = l'

i_eq: i.val = j.val

this: j = Fin.cast i (_ : List.length l = List.length l')


T: Type u

l, l': List T

i: Fin (List.length l)

j: Fin (List.length l')

l_eq: l = l'

i_eq: i.val = j.val

this: j = Fin.cast i (_ : List.length l = List.length l')


T: Type u

l, l': List T

i: Fin (List.length l)

j: Fin (List.length l')

l_eq: l = l'

i_eq: i.val = j.val



Goals accomplished! 🐙
theorem
get_of_map: ∀ {U V : Type u} {f : U → V} {l : List U} {idx : Fin (List.length (List.map f l))}, List.get (List.map f l) idx = f (List.get l (Fin.cast idx (_ : List.length (List.map f l) = List.length l)))
get_of_map
{
U: Type u
U
V: Type u
V
:
Type u: Type (u + 1)
Type u
} {
f: U → V
f
:
U: Type u
U
->
V: Type u
V
} {
l: List U
l
:
List: Type ?u.7199 → Type ?u.7199
List
U: Type u
U
} {
idx: Fin (List.length (List.map f l))
idx
:
Fin: Nat → Type
Fin
(
l: List U
l
.
map: {α : Type ?u.7203} → {β : Type ?u.7202} → (α → β) → List α → List β
map
f: U → V
f
).
length: {α : Type ?u.7214} → List α → Nat
length
} : (
l: List U
l
.
map: {α : Type ?u.7222} → {β : Type ?u.7221} → (α → β) → List α → List β
map
f: U → V
f
).
get: {α : Type ?u.7232} → (as : List α) → Fin (List.length as) → α
get
idx: Fin (List.length (List.map f l))
idx
=
f: U → V
f
(
l: List U
l
.
get: {α : Type ?u.7238} → (as : List α) → Fin (List.length as) → α
get
(
Fin.cast: {n m : Nat} → Fin n → n = m → Fin m
Fin.cast
idx: Fin (List.length (List.map f l))
idx
(
List.length_map: ∀ {α : Type ?u.7246} {β : Type ?u.7245} (as : List α) (f : α → β), List.length (List.map f as) = List.length as
List.length_map
l: List U
l
f: U → V
f
))) := match
l: List U
l
,
idx: Fin (List.length (List.map f l))
idx
with |
head: U
head
::
tail: List U
tail
, ⟨
0: Nat
0
,
isLt: 0 < List.length (List.map f (head :: tail))
isLt
⟩ =>
rfl: ∀ {α : Sort ?u.7308} {a : α}, a = a
rfl
|
head: U
head
::
tail: List U
tail
, ⟨
n: Nat
n
+ 1,
isLt: n + 1 < List.length (List.map f (head :: tail))
isLt
⟩ =>
U, V: Type u

f: U → V

l: List U

idx: Fin (List.length (List.map f l))

head: U

tail: List U

n: Nat

isLt: n + 1 < List.length (List.map f (head :: tail))


List.get (List.map f (head :: tail)) { val := n + 1, isLt := isLt } = f (List.get (head :: tail) (Fin.cast { val := n + 1, isLt := isLt } (_ : List.length (List.map f (head :: tail)) = List.length (head :: tail))))
U, V: Type u

f: U → V

l: List U

idx: Fin (List.length (List.map f l))

head: U

tail: List U

n: Nat

isLt: n + 1 < List.length (List.map f (head :: tail))


List.get (List.map f tail) { val := Nat.add n 0, isLt := (_ : Nat.succ (Nat.add n 0) ≤ List.length (List.map f tail)) } = f (List.get tail { val := Nat.add n 0, isLt := (_ : Nat.succ (Nat.add n 0) ≤ List.length tail) })
U, V: Type u

f: U → V

l: List U

idx: Fin (List.length (List.map f l))

head: U

tail: List U

n: Nat

isLt: n + 1 < List.length (List.map f (head :: tail))


List.get (List.map f (head :: tail)) { val := n + 1, isLt := isLt } = f (List.get (head :: tail) (Fin.cast { val := n + 1, isLt := isLt } (_ : List.length (List.map f (head :: tail)) = List.length (head :: tail))))
U, V: Type u

f: U → V

l: List U

idx: Fin (List.length (List.map f l))

head: U

tail: List U

n: Nat

isLt: n + 1 < List.length (List.map f (head :: tail))


List.get (List.map f tail) { val := Nat.add n 0, isLt := (_ : Nat.succ (Nat.add n 0) ≤ List.length (List.map f tail)) } = f (List.get tail { val := Nat.add n 0, isLt := (_ : Nat.succ (Nat.add n 0) ≤ List.length tail) })
U, V: Type u

f: U → V

l: List U

idx: Fin (List.length (List.map f l))

head: U

tail: List U

n: Nat

isLt: n + 1 < List.length (List.map f (head :: tail))


f (List.get tail (Fin.cast { val := Nat.add n 0, isLt := (_ : Nat.succ (Nat.add n 0) ≤ List.length (List.map f tail)) } (_ : List.length (List.map f tail) = List.length tail))) = f (List.get tail { val := Nat.add n 0, isLt := (_ : Nat.succ (Nat.add n 0) ≤ List.length tail) })
U, V: Type u

f: U → V

l: List U

idx: Fin (List.length (List.map f l))

head: U

tail: List U

n: Nat

isLt: n + 1 < List.length (List.map f (head :: tail))


f (List.get tail (Fin.cast { val := Nat.add n 0, isLt := (_ : Nat.succ (Nat.add n 0) ≤ List.length (List.map f tail)) } (_ : List.length (List.map f tail) = List.length tail))) = f (List.get tail { val := Nat.add n 0, isLt := (_ : Nat.succ (Nat.add n 0) ≤ List.length tail) })
U, V: Type u

f: U → V

l: List U

idx: Fin (List.length (List.map f l))

head: U

tail: List U

n: Nat

isLt: n + 1 < List.length (List.map f (head :: tail))


List.get (List.map f (head :: tail)) { val := n + 1, isLt := isLt } = f (List.get (head :: tail) (Fin.cast { val := n + 1, isLt := isLt } (_ : List.length (List.map f (head :: tail)) = List.length (head :: tail))))

Goals accomplished! 🐙
theorem
set_map_commutes: ∀ {U V : Type u} (f : U → V) (l : List U) (idx : Nat) (new_val : U), List.map f (List.set l idx new_val) = List.set (List.map f l) idx (f new_val)
set_map_commutes
{
U: Type u
U
V: Type u
V
:
Type u: Type (u + 1)
Type u
} (
f: U → V
f
:
U: Type u
U
->
V: Type u
V
) (
l: List U
l
:
List: Type ?u.9080 → Type ?u.9080
List
U: Type u
U
) (
idx: Nat
idx
:
Nat: Type
Nat
) (
new_val: U
new_val
:
U: Type u
U
) : (
l: List U
l
.
set: {α : Type ?u.9088} → List α → Nat → α → List α
set
idx: Nat
idx
new_val: U
new_val
).
map: {α : Type ?u.9096} → {β : Type ?u.9095} → (α → β) → List α → List β
map
f: U → V
f
= (
l: List U
l
.
map: {α : Type ?u.9107} → {β : Type ?u.9106} → (α → β) → List α → List β
map
f: U → V
f
).
set: {α : Type ?u.9117} → List α → Nat → α → List α
set
idx: Nat
idx
(
f: U → V
f
new_val: U
new_val
) :=
U, V: Type u

f: U → V

l: List U

idx: Nat

new_val: U


List.map f (List.set l idx new_val) = List.set (List.map f l) idx (f new_val)
U, V: Type u

f: U → V

l: List U

new_val: U


∀ (idx : Nat), List.map f (List.set l idx new_val) = List.set (List.map f l) idx (f new_val)
U, V: Type u

f: U → V

l: List U

idx: Nat

new_val: U


List.map f (List.set l idx new_val) = List.set (List.map f l) idx (f new_val)
U, V: Type u

f: U → V

new_val: U


nil
∀ (idx : Nat), List.map f (List.set [] idx new_val) = List.set (List.map f []) idx (f new_val)
U, V: Type u

f: U → V

new_val, head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.set (head✝ :: tail✝) idx new_val) = List.set (List.map f (head✝ :: tail✝)) idx (f new_val)
U, V: Type u

f: U → V

l: List U

idx: Nat

new_val: U


List.map f (List.set l idx new_val) = List.set (List.map f l) idx (f new_val)
U, V: Type u

f: U → V

new_val: U


nil
∀ (idx : Nat), List.map f (List.set [] idx new_val) = List.set (List.map f []) idx (f new_val)
U, V: Type u

f: U → V

new_val: U


nil
∀ (idx : Nat), List.map f (List.set [] idx new_val) = List.set (List.map f []) idx (f new_val)
U, V: Type u

f: U → V

new_val, head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.set (head✝ :: tail✝) idx new_val) = List.set (List.map f (head✝ :: tail✝)) idx (f new_val)
U, V: Type u

f: U → V

new_val: U

idx✝: Nat


nil
List.map f (List.set [] idx✝ new_val) = List.set (List.map f []) idx✝ (f new_val)
U, V: Type u

f: U → V

new_val: U


nil
∀ (idx : Nat), List.map f (List.set [] idx new_val) = List.set (List.map f []) idx (f new_val)
U, V: Type u

f: U → V

new_val, head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.set (head✝ :: tail✝) idx new_val) = List.set (List.map f (head✝ :: tail✝)) idx (f new_val)
U, V: Type u

f: U → V

new_val: U

idx✝: Nat


nil
List.map f (List.set [] idx✝ new_val) = List.set (List.map f []) idx✝ (f new_val)
U, V: Type u

f: U → V

new_val: U


nil
∀ (idx : Nat), List.map f (List.set [] idx new_val) = List.set (List.map f []) idx (f new_val)
U, V: Type u

f: U → V

new_val, head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.set (head✝ :: tail✝) idx new_val) = List.set (List.map f (head✝ :: tail✝)) idx (f new_val)

Goals accomplished! 🐙
U, V: Type u

f: U → V

l: List U

idx: Nat

new_val: U


List.map f (List.set l idx new_val) = List.set (List.map f l) idx (f new_val)
U, V: Type u

f: U → V

new_val, head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.set (head✝ :: tail✝) idx new_val) = List.set (List.map f (head✝ :: tail✝)) idx (f new_val)
U, V: Type u

f: U → V

new_val, head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.set (head✝ :: tail✝) idx new_val) = List.set (List.map f (head✝ :: tail✝)) idx (f new_val)
U, V: Type u

f: U → V

new_val, head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.set tail idx new_val) = List.set (List.map f tail) idx (f new_val)


cons
∀ (idx : Nat), List.map f (List.set (head :: tail) idx new_val) = List.set (List.map f (head :: tail)) idx (f new_val)
U, V: Type u

f: U → V

new_val, head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.set (head✝ :: tail✝) idx new_val) = List.set (List.map f (head✝ :: tail✝)) idx (f new_val)
U, V: Type u

f: U → V

new_val, head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.set tail idx new_val) = List.set (List.map f tail) idx (f new_val)

idx: Nat


cons
List.map f (List.set (head :: tail) idx new_val) = List.set (List.map f (head :: tail)) idx (f new_val)
U, V: Type u

f: U → V

new_val, head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.set (head✝ :: tail✝) idx new_val) = List.set (List.map f (head✝ :: tail✝)) idx (f new_val)
U, V: Type u

f: U → V

new_val, head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.set tail idx new_val) = List.set (List.map f tail) idx (f new_val)


cons.zero
List.map f (List.set (head :: tail) Nat.zero new_val) = List.set (List.map f (head :: tail)) Nat.zero (f new_val)
U, V: Type u

f: U → V

new_val, head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.set tail idx new_val) = List.set (List.map f tail) idx (f new_val)

n✝: Nat


cons.succ
List.map f (List.set (head :: tail) (Nat.succ n✝) new_val) = List.set (List.map f (head :: tail)) (Nat.succ n✝) (f new_val)
U, V: Type u

f: U → V

new_val, head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.set (head✝ :: tail✝) idx new_val) = List.set (List.map f (head✝ :: tail✝)) idx (f new_val)
U, V: Type u

f: U → V

new_val, head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.set tail idx new_val) = List.set (List.map f tail) idx (f new_val)


cons.zero
List.map f (List.set (head :: tail) Nat.zero new_val) = List.set (List.map f (head :: tail)) Nat.zero (f new_val)
U, V: Type u

f: U → V

new_val, head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.set tail idx new_val) = List.set (List.map f tail) idx (f new_val)


cons.zero
List.map f (List.set (head :: tail) Nat.zero new_val) = List.set (List.map f (head :: tail)) Nat.zero (f new_val)
U, V: Type u

f: U → V

new_val, head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.set tail idx new_val) = List.set (List.map f tail) idx (f new_val)

n✝: Nat


cons.succ
List.map f (List.set (head :: tail) (Nat.succ n✝) new_val) = List.set (List.map f (head :: tail)) (Nat.succ n✝) (f new_val)

Goals accomplished! 🐙
U, V: Type u

f: U → V

new_val, head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.set (head✝ :: tail✝) idx new_val) = List.set (List.map f (head✝ :: tail✝)) idx (f new_val)
U, V: Type u

f: U → V

new_val, head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.set tail idx new_val) = List.set (List.map f tail) idx (f new_val)

n✝: Nat


cons.succ
List.map f (List.set (head :: tail) (Nat.succ n✝) new_val) = List.set (List.map f (head :: tail)) (Nat.succ n✝) (f new_val)
U, V: Type u

f: U → V

new_val, head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.set tail idx new_val) = List.set (List.map f tail) idx (f new_val)

n✝: Nat


cons.succ
List.map f (List.set (head :: tail) (Nat.succ n✝) new_val) = List.set (List.map f (head :: tail)) (Nat.succ n✝) (f new_val)
U, V: Type u

f: U → V

new_val, head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.set tail idx new_val) = List.set (List.map f tail) idx (f new_val)

n✝: Nat


cons.succ
f head :: List.map f (List.set tail n✝ new_val) = f head :: List.set (List.map f tail) n✝ (f new_val)
U, V: Type u

f: U → V

new_val, head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.set tail idx new_val) = List.set (List.map f tail) idx (f new_val)

n✝: Nat


cons.succ
List.map f (List.set (head :: tail) (Nat.succ n✝) new_val) = List.set (List.map f (head :: tail)) (Nat.succ n✝) (f new_val)
U, V: Type u

f: U → V

new_val, head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.set tail idx new_val) = List.set (List.map f tail) idx (f new_val)

n: Nat


cons.succ
f head :: List.map f (List.set tail n new_val) = f head :: List.set (List.map f tail) n (f new_val)
U, V: Type u

f: U → V

new_val, head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.set tail idx new_val) = List.set (List.map f tail) idx (f new_val)

n✝: Nat


cons.succ
List.map f (List.set (head :: tail) (Nat.succ n✝) new_val) = List.set (List.map f (head :: tail)) (Nat.succ n✝) (f new_val)
U, V: Type u

f: U → V

new_val, head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.set tail idx new_val) = List.set (List.map f tail) idx (f new_val)

n: Nat


cons.succ
f head :: List.map f (List.set tail n new_val) = f head :: List.set (List.map f tail) n (f new_val)
U, V: Type u

f: U → V

new_val, head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.set tail idx new_val) = List.set (List.map f tail) idx (f new_val)

n: Nat


cons.succ
f head :: List.set (List.map f tail) n (f new_val) = f head :: List.set (List.map f tail) n (f new_val)

Goals accomplished! 🐙
theorem
erase_map_commutes: ∀ {U V : Type u} (f : U → V) (l : List U) (idx : Nat), List.map f (List.eraseIdx l idx) = List.eraseIdx (List.map f l) idx
erase_map_commutes
{
U: Type u
U
V: Type u
V
:
Type u: Type (u + 1)
Type u
} (
f: U → V
f
:
U: Type u
U
->
V: Type u
V
) (
l: List U
l
:
List: Type ?u.10157 → Type ?u.10157
List
U: Type u
U
) (
idx: Nat
idx
:
Nat: Type
Nat
) : (
l: List U
l
.
eraseIdx: {α : Type ?u.10163} → List α → Nat → List α
eraseIdx
idx: Nat
idx
).
map: {α : Type ?u.10170} → {β : Type ?u.10169} → (α → β) → List α → List β
map
f: U → V
f
= (
l: List U
l
.
map: {α : Type ?u.10181} → {β : Type ?u.10180} → (α → β) → List α → List β
map
f: U → V
f
).
eraseIdx: {α : Type ?u.10191} → List α → Nat → List α
eraseIdx
idx: Nat
idx
:=
U, V: Type u

f: U → V

l: List U

idx: Nat


U, V: Type u

f: U → V

l: List U


∀ (idx : Nat), List.map f (List.eraseIdx l idx) = List.eraseIdx (List.map f l) idx
U, V: Type u

f: U → V

l: List U

idx: Nat


U, V: Type u

f: U → V


nil
∀ (idx : Nat), List.map f (List.eraseIdx [] idx) = List.eraseIdx (List.map f []) idx
U, V: Type u

f: U → V

head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.eraseIdx (head✝ :: tail✝) idx) = List.eraseIdx (List.map f (head✝ :: tail✝)) idx
U, V: Type u

f: U → V

l: List U

idx: Nat


U, V: Type u

f: U → V


nil
∀ (idx : Nat), List.map f (List.eraseIdx [] idx) = List.eraseIdx (List.map f []) idx
U, V: Type u

f: U → V


nil
∀ (idx : Nat), List.map f (List.eraseIdx [] idx) = List.eraseIdx (List.map f []) idx
U, V: Type u

f: U → V

head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.eraseIdx (head✝ :: tail✝) idx) = List.eraseIdx (List.map f (head✝ :: tail✝)) idx
U, V: Type u

f: U → V

idx✝: Nat


nil
List.map f (List.eraseIdx [] idx✝) = List.eraseIdx (List.map f []) idx✝
U, V: Type u

f: U → V


nil
∀ (idx : Nat), List.map f (List.eraseIdx [] idx) = List.eraseIdx (List.map f []) idx
U, V: Type u

f: U → V

head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.eraseIdx (head✝ :: tail✝) idx) = List.eraseIdx (List.map f (head✝ :: tail✝)) idx
U, V: Type u

f: U → V

idx✝: Nat


nil
List.map f (List.eraseIdx [] idx✝) = List.eraseIdx (List.map f []) idx✝
U, V: Type u

f: U → V


nil
∀ (idx : Nat), List.map f (List.eraseIdx [] idx) = List.eraseIdx (List.map f []) idx
U, V: Type u

f: U → V

head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.eraseIdx (head✝ :: tail✝) idx) = List.eraseIdx (List.map f (head✝ :: tail✝)) idx

Goals accomplished! 🐙
U, V: Type u

f: U → V

l: List U

idx: Nat


U, V: Type u

f: U → V

head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.eraseIdx (head✝ :: tail✝) idx) = List.eraseIdx (List.map f (head✝ :: tail✝)) idx
U, V: Type u

f: U → V

head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.eraseIdx (head✝ :: tail✝) idx) = List.eraseIdx (List.map f (head✝ :: tail✝)) idx
U, V: Type u

f: U → V

head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.eraseIdx tail idx) = List.eraseIdx (List.map f tail) idx


cons
∀ (idx : Nat), List.map f (List.eraseIdx (head :: tail) idx) = List.eraseIdx (List.map f (head :: tail)) idx
U, V: Type u

f: U → V

head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.eraseIdx (head✝ :: tail✝) idx) = List.eraseIdx (List.map f (head✝ :: tail✝)) idx
U, V: Type u

f: U → V

head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.eraseIdx tail idx) = List.eraseIdx (List.map f tail) idx

idx: Nat


cons
List.map f (List.eraseIdx (head :: tail) idx) = List.eraseIdx (List.map f (head :: tail)) idx
U, V: Type u

f: U → V

head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.eraseIdx (head✝ :: tail✝) idx) = List.eraseIdx (List.map f (head✝ :: tail✝)) idx
U, V: Type u

f: U → V

head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.eraseIdx tail idx) = List.eraseIdx (List.map f tail) idx


cons.zero
U, V: Type u

f: U → V

head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.eraseIdx tail idx) = List.eraseIdx (List.map f tail) idx

n✝: Nat


cons.succ
List.map f (List.eraseIdx (head :: tail) (Nat.succ n✝)) = List.eraseIdx (List.map f (head :: tail)) (Nat.succ n✝)
U, V: Type u

f: U → V

head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.eraseIdx (head✝ :: tail✝) idx) = List.eraseIdx (List.map f (head✝ :: tail✝)) idx
U, V: Type u

f: U → V

head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.eraseIdx tail idx) = List.eraseIdx (List.map f tail) idx


cons.zero
U, V: Type u

f: U → V

head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.eraseIdx tail idx) = List.eraseIdx (List.map f tail) idx


cons.zero
U, V: Type u

f: U → V

head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.eraseIdx tail idx) = List.eraseIdx (List.map f tail) idx

n✝: Nat


cons.succ
List.map f (List.eraseIdx (head :: tail) (Nat.succ n✝)) = List.eraseIdx (List.map f (head :: tail)) (Nat.succ n✝)

Goals accomplished! 🐙
U, V: Type u

f: U → V

head✝: U

tail✝: List U


cons
∀ (idx : Nat), List.map f (List.eraseIdx (head✝ :: tail✝) idx) = List.eraseIdx (List.map f (head✝ :: tail✝)) idx
U, V: Type u

f: U → V

head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.eraseIdx tail idx) = List.eraseIdx (List.map f tail) idx

n✝: Nat


cons.succ
List.map f (List.eraseIdx (head :: tail) (Nat.succ n✝)) = List.eraseIdx (List.map f (head :: tail)) (Nat.succ n✝)
U, V: Type u

f: U → V

head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.eraseIdx tail idx) = List.eraseIdx (List.map f tail) idx

n✝: Nat


cons.succ
List.map f (List.eraseIdx (head :: tail) (Nat.succ n✝)) = List.eraseIdx (List.map f (head :: tail)) (Nat.succ n✝)
U, V: Type u

f: U → V

head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.eraseIdx tail idx) = List.eraseIdx (List.map f tail) idx

n✝: Nat


cons.succ
f head :: List.map f (List.eraseIdx tail n✝) = f head :: List.eraseIdx (List.map f tail) n✝
U, V: Type u

f: U → V

head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.eraseIdx tail idx) = List.eraseIdx (List.map f tail) idx

n✝: Nat


cons.succ
List.map f (List.eraseIdx (head :: tail) (Nat.succ n✝)) = List.eraseIdx (List.map f (head :: tail)) (Nat.succ n✝)
U, V: Type u

f: U → V

head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.eraseIdx tail idx) = List.eraseIdx (List.map f tail) idx

n: Nat


cons.succ
f head :: List.map f (List.eraseIdx tail n) = f head :: List.eraseIdx (List.map f tail) n
U, V: Type u

f: U → V

head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.eraseIdx tail idx) = List.eraseIdx (List.map f tail) idx

n✝: Nat


cons.succ
List.map f (List.eraseIdx (head :: tail) (Nat.succ n✝)) = List.eraseIdx (List.map f (head :: tail)) (Nat.succ n✝)
U, V: Type u

f: U → V

head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.eraseIdx tail idx) = List.eraseIdx (List.map f tail) idx

n: Nat


cons.succ
f head :: List.map f (List.eraseIdx tail n) = f head :: List.eraseIdx (List.map f tail) n
U, V: Type u

f: U → V

head: U

tail: List U

IH: ∀ (idx : Nat), List.map f (List.eraseIdx tail idx) = List.eraseIdx (List.map f tail) idx

n: Nat


cons.succ
f head :: List.eraseIdx (List.map f tail) n = f head :: List.eraseIdx (List.map f tail) n

Goals accomplished! 🐙
end Mt.Utils.List