lean4-htt/library/data/list.lean
Leonardo de Moura 1726d37d4e fix(library/algebra/order): decidable_linear_order
Add fields for decidable_eq and decidable_le.
We need this because a concrete instance may have its own
implementation that is not definitionally equal to
the old ones defined at library/algebra/order.lean.
Without this change, types such as nat and int would
have multiple definitions for decidable_eq and decidable_le
which are not definitionally equal.
2016-12-17 14:01:43 -08:00

139 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.data.list.basic
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