This modification was suggested by @kha. TODO: - Use `simp [-f]` instead of `simp without f` - Allow users to remove hypothesis from `*`. Example: `simp [*, -h]` for simplify using all hypotheses but `h`.
100 lines
3.1 KiB
Text
100 lines
3.1 KiB
Text
/-
|
||
Copyright (c) 2015 Leonardo de Moura. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
Authors: Leonardo de Moura, Haitao Zhang, Floris van Doorn
|
||
|
||
List combinators.
|
||
-/
|
||
import init.data.list.basic
|
||
|
||
universes u v w
|
||
|
||
namespace list
|
||
|
||
open nat
|
||
|
||
variables {α : Type u} {β : Type v} {φ : Type w}
|
||
|
||
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)
|
||
|
||
@[simp]
|
||
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))
|
||
|
||
@[simp]
|
||
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₂
|
||
|
||
@[simp]
|
||
theorem foldl_nil (f : α → β → α) (a : α) : foldl f a [] = a := rfl
|
||
|
||
@[simp]
|
||
theorem foldl_cons (f : α → β → α) (a : α) (b : β) (l : list β) :
|
||
foldl f a (b::l) = foldl f (f a b) l := rfl
|
||
|
||
@[simp]
|
||
theorem foldr_nil (f : α → β → β) (b : β) : foldr f b [] = b := rfl
|
||
|
||
@[simp]
|
||
theorem foldr_cons (f : α → β → β) (b : β) (a : α) (l : list α) :
|
||
foldr f b (a::l) = f a (foldr f b l) := rfl
|
||
|
||
@[simp]
|
||
theorem foldl_append (f : β → α → β) :
|
||
∀ (b : β) (l₁ l₂ : list α), foldl f b (l₁++l₂) = foldl f (foldl f b l₁) l₂
|
||
| b [] l₂ := rfl
|
||
| b (a::l₁) l₂ := by simp [foldl_append]
|
||
|
||
@[simp]
|
||
theorem foldr_append (f : α → β → β) :
|
||
∀ (b : β) (l₁ l₂ : list α), foldr f b (l₁++l₂) = foldr f (foldr f b l₂) l₁
|
||
| b [] l₂ := rfl
|
||
| b (a::l₁) l₂ := by simp [foldr_append]
|
||
|
||
theorem foldl_reverse (f : α → β → α) (a : α) (l : list β) : foldl f a (reverse l) = foldr (λx y, f y x) a l :=
|
||
by induction l; simp [*, foldl, foldr]
|
||
|
||
theorem foldr_reverse (f : α → β → β) (a : β) (l : list α) : foldr f a (reverse l) = foldl (λx y, f y x) a l :=
|
||
let t := foldl_reverse (λx y, f y x) a (reverse l) in
|
||
by rw reverse_reverse l at t; rwa t
|
||
|
||
end list
|