When updating Std, be careful that not every lemma has been upstreamed, so we need to be careful to only delete things that have already been declared.
46 lines
1.2 KiB
Text
46 lines
1.2 KiB
Text
inductive ListSplit {α : Type u} : List α → Type u
|
||
| split l₁ l₂ : ListSplit (l₁ ++ l₂)
|
||
|
||
def splitList {α : Type _} : (l : List α) → ListSplit l
|
||
| [] => ListSplit.split [] []
|
||
| h :: t => ListSplit.split [h] t
|
||
|
||
def len : List α → Nat
|
||
| [] => 0
|
||
| a :: [] => 1
|
||
| l =>
|
||
match splitList l with
|
||
| ListSplit.split fst snd => len fst + len snd
|
||
termination_by l => l.length
|
||
decreasing_by
|
||
all_goals sorry
|
||
|
||
theorem len_nil : len ([] : List α) = 0 := by
|
||
simp [len]
|
||
|
||
-- The `simp [len]` above generated the following equation theorems for len
|
||
#check @len._eq_1
|
||
#check @len._eq_2
|
||
#check @len._eq_3 -- It is conditional, and may be tricky to use.
|
||
|
||
theorem len_1 (a : α) : len [a] = 1 := by
|
||
simp [len]
|
||
|
||
theorem len_2 (a b : α) (bs : List α) : len (a::b::bs) = 1 + len (b::bs) := by
|
||
conv => lhs; unfold len
|
||
|
||
-- The `unfold` tactic above generated the following theorem
|
||
#check @len._unfold
|
||
|
||
theorem len_cons (a : α) (as : List α) : len (a::as) = 1 + len as := by
|
||
cases as with
|
||
| nil => simp [len_1, len_nil]
|
||
| cons b bs => simp [len_2]
|
||
|
||
theorem listlen : ∀ l : List α, l.length = len l := by
|
||
intro l
|
||
induction l with
|
||
| nil => rfl
|
||
| cons h t ih =>
|
||
simp [List.length, len_cons, ih]
|
||
rw [Nat.add_comm]
|