(** * Addendum to the standard library of Coq *)
Require Export Omega.
Global Obligation Tactic := idtac.
Notation "[ x ; .. ; y ]" := (cons x .. (cons y nil) .. ).

(* Specifications: *)
Lemma length_nil : forall A (l : list A),
length l = 0 -> l = nil.
Lemma length_tail A l : length (@tail A l) = length l - 1.
Lemma hd_nth_0 A (l : list A) d :
hd d l = nth 0 l d.
Lemma In_hd (A : Type)(d:A)(l : list A)(n : nat)(H : length l = S n) :
In (hd d l) l.
Lemma map_hd : forall A B (f:A->B) d l, f (hd d l) = hd (f d) (map f l).
Lemma map_tl : forall A B (f:A->B) l, map f (tl l) = tl (map f l).
Lemma map_eq_hd :
forall A B (f:A->B) d l1 l2,
map f l1 = map f l2 -> f (hd d l1) = f (hd d l2).
Lemma firstn_nil {A} n : firstn n (@nil A) = nil.
Lemma nth_firstn : forall A i j (l:list A) d,
i < j -> nth i (firstn j l) d = nth i l d.
Lemma nth_skipn A i j (l:list A) d :
nth i (skipn j l) d = nth (j+i) l d.
Lemma length_skipn : forall A n (y : list A),
length (skipn n y) = length y - n.
Lemma skipn_length : forall {A} n (l:list A),
length (skipn n l) = length l - n.
Lemma cons_skipn :
forall A d i (l:list A),
i < length l ->
nth i l d :: skipn (S i) l = skipn i l.
Lemma skipn_plus :
forall A j i (l:list A), skipn (i+j) l = skipn i (skipn j l).
Lemma skipn_hd : forall {A} n y (d:A),
n < length y ->
skipn n y = nth n y d :: skipn (S n) y.
Lemma firstn_app {A} (l l' : list A) :
firstn (length l) (l ++ l') = l.
Lemma skipn_app {A} (l l' : list A) :
skipn (length l) (l ++ l') = l'.
Lemma map_skipn : forall A B (f:A->B) n l,
map f (skipn n l) = skipn n (map f l).
Lemma map_nth_seq : forall A (l:list A) len n d,
length l = len + n ->
map (fun x : nat => nth x l d) (seq n len) = (skipn n l).
Lemma skipn_nil_length : forall A n (l : list A),
skipn n l = nil -> length l <= n.
Lemma firstn_map_nth :
forall A d n m (l:list A),
m+n <= length l ->
firstn n (skipn m l) = map (fun i => nth i l d) (seq m n).
Lemma firstn_seq n start len :
firstn n (seq start len) = seq start (min n len).
Lemma skipn_seq n start len :
skipn n (seq start len) = seq (start+n) (len-n).
Lemma in_seq_iff : forall x len start,
In x (seq start len) <-> start <= x < start+len.
Lemma nth_map_cst :
forall {A B} (l:list A) n (d:B), nth n (map (fun _ => d) l) d = d.
Lemma nth_S_tl A (l : list A) d n :
nth n (tl l) d = nth (S n) l d.
Lemma map_ext2 : forall {A B} (f g : A -> B) l,
(forall a : A, In a l -> f a = g a) -> map f l = map g l.
Lemma map_nth2
(A B : Type) (f : A -> B) (l : list A) b d n :
(f d) = b ->
nth n (map f l) b = f (nth n l d).
Lemma tl_app : forall A (l1 l2 : list A),
l1 <> nil ->
tl (l1 ++ l2) = tl l1 ++ l2.
Lemma map_seq_nth : forall A B (l : list A) (g : A -> B) d,
map (fun n => g (nth n l d)) (seq 0 (length l)) = map g l.
Lemma map_seq_shift : forall A m (f : nat -> A) n,
n <> 0 ->
map f (seq 0 m) = map (fun x => f (x - n)%nat) (seq n m).
Lemma map_seq_nth_safe : forall A B (l : list A) (g : A -> B) d m,
map (fun n => g (nth (n - m) l d)) (seq m (length l)) = map g l.
Lemma seq_app : forall x y z,
seq x y ++ seq (x + y) z = seq x (y + z).