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.4Type ?u.4
List
T: Type u
T
) (
idx: Fin (List.length l)
idx
:
Fin: NatType
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 asList.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 mn 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.672Type ?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 mn < 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 idxa 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.1483Type ?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 αNatList α
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 asList.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_valuea = 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.2325Type ?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}, ba 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_valuea = 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_valuea = 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_valuea = 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_valuea = 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_valuea = 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_valuea = 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_valuea = 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_valuea = 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_valuea = 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_valuea = 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 li, 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.3681Type ?u.3681
List
T: Type u
T
) :
a: T
a
l: List T
l
→ ∃ i :
Fin: NatType
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 = ai, 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.5691Type ?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 αNatList α
eraseIdx
idx: Nat
idx
=
l: List T
l
.
eraseIdx: {α : Type ?u.5711} → List αNatList α
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 : UV} {l : List U} {v : V}, v List.map f lu, 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: UV
f
:
U: Type u
U
->
V: Type u
V
} {
l: List U
l
:
List: Type ?u.6207Type ?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: UV
f
) → ∃
u: ?m.6243
u
,
u: ?m.6243
u
l: List U
l
v: V
v
=
f: UV
f
u: ?m.6243
u
:=
U, V: Type u

f: UV

l: List U

v: V


v List.map f lu, u l v = f u
U, V: Type u

f: UV

l: List U

v: V

v_in_map: v List.map f l


u, u l v = f u
U, V: Type u

f: UV

l: List U

v: V


v List.map f lu, u l v = f u
U, V: Type u

f: UV

v: V

v_in_map: v List.map f []


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

f: UV

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: UV

l: List U

v: V


v List.map f lu, u l v = f u
U, V: Type u

f: UV

v: V

v_in_map: v List.map f []


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

f: UV

v: V

v_in_map: v List.map f []


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

f: UV

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: UV

l: List U

v: V


v List.map f lu, u l v = f u
U, V: Type u

f: UV

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: UV

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: UV

v: V

head: U

tail: List U

IH: v List.map f tailu, 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: UV

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: UV

head: U

tail: List U

IH: f head List.map f tailu, u tail f head = f u


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

f: UV

v: V

head: U

tail: List U

IH: v List.map f tailu, u tail v = f u


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

f: UV

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: UV

head: U

tail: List U

IH: f head List.map f tailu, u tail f head = f u


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

f: UV

head: U

tail: List U

IH: f head List.map f tailu, u tail f head = f u


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

f: UV

v: V

head: U

tail: List U

IH: v List.map f tailu, u tail v = f u


cons.tail
u, u head :: tail v = f u

Goals accomplished! 🐙
U, V: Type u

f: UV

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: UV

v: V

head: U

tail: List U

IH: v List.map f tailu, u tail v = f u


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

f: UV

v: V

head: U

tail: List U

IH: v List.map f tailu, u tail v = f u


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

f: UV

v: V

head: U

tail: List U

IH: v List.map f tailu, 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: UV

v: V

head: U

tail: List U

IH: v List.map f tailu, u tail v = f u


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

f: UV

v: V

head: U

tail: List U

IH: v List.map f tailu, 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: UV

v: V

head: U

tail: List U

IH: v List.map f tailu, u tail v = f u


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

f: UV

v: V

head: U

tail: List U

IH: v List.map f tailu, 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: UV

v: V

head: U

tail: List U

IH: v List.map f tailu, 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.6901Type ?u.6901
List
T: Type u
T
} (
idx: Fin (List.length l)
idx
:
Fin: NatType
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 nn = mFin 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_1Sort ?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 nn = mFin 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.valList.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.7065Type ?u.7065
List
T: Type u
T
} {i :
Fin: NatType
Fin
l: List T
l
.
length: {α : Type ?u.7068} → List αNat
length
} {j :
Fin: NatType
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 nNat
val
= j.
val: {n : Nat} → Fin nNat
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 : UV} {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: UV
f
:
U: Type u
U
->
V: Type u
V
} {
l: List U
l
:
List: Type ?u.7199Type ?u.7199
List
U: Type u
U
} {
idx: Fin (List.length (List.map f l))
idx
:
Fin: NatType
Fin
(
l: List U
l
.
map: {α : Type ?u.7203} → {β : Type ?u.7202} → (αβ) → List αList β
map
f: UV
f
).
length: {α : Type ?u.7214} → List αNat
length
} : (
l: List U
l
.
map: {α : Type ?u.7222} → {β : Type ?u.7221} → (αβ) → List αList β
map
f: UV
f
).
get: {α : Type ?u.7232} → (as : List α) → Fin (List.length as)α
get
idx: Fin (List.length (List.map f l))
idx
=
f: UV
f
(
l: List U
l
.
get: {α : Type ?u.7238} → (as : List α) → Fin (List.length as)α
get
(
Fin.cast: {n m : Nat} → Fin nn = mFin 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: UV
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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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 : UV) (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: UV
f
:
U: Type u
U
->
V: Type u
V
) (
l: List U
l
:
List: Type ?u.9080Type ?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: UV
f
= (
l: List U
l
.
map: {α : Type ?u.9107} → {β : Type ?u.9106} → (αβ) → List αList β
map
f: UV
f
).
set: {α : Type ?u.9117} → List αNatαList α
set
idx: Nat
idx
(
f: UV
f
new_val: U
new_val
) :=
U, V: Type u

f: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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 : UV) (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: UV
f
:
U: Type u
U
->
V: Type u
V
) (
l: List U
l
:
List: Type ?u.10157Type ?u.10157
List
U: Type u
U
) (
idx: Nat
idx
:
Nat: Type
Nat
) : (
l: List U
l
.
eraseIdx: {α : Type ?u.10163} → List αNatList α
eraseIdx
idx: Nat
idx
).
map: {α : Type ?u.10170} → {β : Type ?u.10169} → (αβ) → List αList β
map
f: UV
f
= (
l: List U
l
.
map: {α : Type ?u.10181} → {β : Type ?u.10180} → (αβ) → List αList β
map
f: UV
f
).
eraseIdx: {α : Type ?u.10191} → List αNatList α
eraseIdx
idx: Nat
idx
:=
U, V: Type u

f: UV

l: List U

idx: Nat


U, V: Type u

f: UV

l: List U


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

f: UV

l: List U

idx: Nat


U, V: Type u

f: UV


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

f: UV

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: UV

l: List U

idx: Nat


U, V: Type u

f: UV


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

f: UV


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

f: UV

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: UV

idx✝: Nat


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

f: UV


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

f: UV

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: UV

idx✝: Nat


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

f: UV


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

f: UV

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: UV

l: List U

idx: Nat


U, V: Type u

f: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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: UV

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