lean4-htt/library/data/list.lean

141 lines
4.7 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Jeremy Avigad
This is a minimal port of functions from the lean2 list library.
-/
import init.list
import algebra.order
import data.nat
universe variables u v w
namespace list
open nat
variables {α : Type u} {β : Type v} {φ : Type w}
/- length theorems -/
theorem length_append : ∀ (x y : list α), length (x ++ y) = length x + length y
| [] l := eq.symm (nat.zero_add (length l))
| (a::s) l :=
calc nat.succ (length (s ++ l))
= nat.succ (length s + length l) : congr_arg nat.succ (length_append s l)
... = nat.succ (length s) + length l : eq.symm (nat.succ_add (length s) (length l))
theorem length_repeat (a : α) : ∀ (n : ), length (repeat a n) = n
| 0 := eq.refl 0
| (succ i) := congr_arg succ (length_repeat i)
theorem length_map (f : α → β) : ∀ (a : list α), length (map f a) = length a
| [] := rfl
| (a :: l) := congr_arg succ (length_map l)
theorem length_dropn
: ∀ (i : ) (l : list α), length (dropn i l) = length l - i
| 0 l := rfl
| (succ i) [] := eq.symm (nat.zero_sub_eq_zero (succ i))
| (succ i) (x::l) := calc
length (dropn (succ i) (x::l))
= length l - i : length_dropn i l
... = succ (length l) - succ i : nat.sub_eq_succ_sub_succ (length l) i
/- firstn -/
def firstn : → list α → list α
| 0 l := []
| (succ n) [] := []
| (succ n) (a::l) := a :: firstn n l
theorem length_firstn
: ∀ (i : ) (l : list α), length (firstn i l) = min i (length l)
| 0 l := eq.symm (nat.min_zero_left (length l))
| (succ n) [] := eq.symm (nat.min_zero_right (succ n))
| (succ n) (a::l) :=
calc succ (length (firstn n l)) = succ (min n (length l)) : congr_arg succ (length_firstn n l)
... = min (succ n) (succ (length l))
: eq.symm (nat.min_succ_succ n (length l))
/- map₂ -/
definition map₂ {α : Type u} {β : Type v} {φ : Type w} (f : α → β → φ) : list α → list β → list φ
| [] l := []
| l [] := []
| (a::s) (b::t) := f a b :: map₂ s t
theorem map₂_nil_1 {α : Type u} {β : Type v} {φ : Type w} (f : α → β → φ)
: Π y, map₂ f nil y = nil
| [] := eq.refl nil
| (b::t) := eq.refl nil
theorem map₂_nil_2 {α β φ : Type} (f : α → β → φ)
: Π (x : list α), map₂ f x nil = nil
| [] := eq.refl nil
| (b::t) := eq.refl nil
theorem length_map₂ {α β φ : Type} (f : α → β → φ)
: Π x y, length (map₂ f x y) = min (length x) (length y)
| [] y :=
calc length (map₂ f nil y) = 0 : congr_arg length (map₂_nil_1 f y)
... = min 0 (length y) : eq.symm (nat.min_zero_left (length y))
| x [] :=
calc length (map₂ f x nil) = 0 : congr_arg length (map₂_nil_2 f x)
... = min (length x) 0 : eq.symm (nat.min_zero_right (length x))
| (a::x) (b::y) :=
calc succ (length (map₂ f x y))
= succ (min (length x) (length y))
: congr_arg succ (length_map₂ x y)
... = min (succ (length x)) (succ (length y))
: eq.symm (min_succ_succ (length x) (length y))
section map_accumr
variable {σ : Type}
-- This runs a function over a list returning the intermediate results and a
-- a final result.
definition map_accumr (f : ασσ × β) : list ασ → (σ × list β)
| [] c := (c, [])
| (y::yr) c :=
let r := map_accumr yr c in
let z := f y (prod.fst r) in
(prod.fst z, prod.snd z :: prod.snd r)
theorem length_map_accumr
: ∀ (f : ασσ × β) (x : list α) (s : σ),
length (prod.snd (map_accumr f x s)) = length x
| f (a::x) s := congr_arg succ (length_map_accumr f x s)
| f [] s := rfl
end map_accumr
section map_accumr₂
-- This runs a function over two lists returning the intermediate results and a
-- a final result.
definition map_accumr₂ {α β σ φ : Type} (f : α → β → σσ × φ)
: list α → list β → σσ × list φ
| [] _ c := (c,[])
| _ [] c := (c,[])
| (x::xr) (y::yr) c :=
let r := map_accumr₂ xr yr c in
let q := f x y (prod.fst r) in
(prod.fst q, prod.snd q :: (prod.snd r))
theorem length_map_accumr₂ {α β σ φ : Type}
: ∀ (f : α → β → σσ × φ) x y c,
length (prod.snd (map_accumr₂ f x y c)) = min (length x) (length y)
| f (a::x) (b::y) c := calc
succ (length (prod.snd (map_accumr₂ f x y c)))
= succ (min (length x) (length y))
: congr_arg succ (length_map_accumr₂ f x y c)
... = min (succ (length x)) (succ (length y))
: eq.symm (min_succ_succ (length x) (length y))
| f (a::x) [] c := rfl
| f [] (b::y) c := rfl
| f [] [] c := rfl
end map_accumr₂
end list