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 hd_nth_1 A (l : list A) d : hd d (tl l) = nth 1 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 skipn_nil : forall {A} n (x : list A), length x <= n -> skipn n x = 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_cons : forall A B (f:A->B) a l, map f (a::l) = f a :: map f l.
Lemma map_firstn : forall A B (f:A->B) n l, map f (firstn n l) = firstn n (map f 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 length_plus_ex {A} n1 n2 (l : list A): length l = n1 + n2 -> exists l1, exists l2, length l1 = n1 /\ length l2 = n2 /\ l = l1 ++ l2.
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).