Class Inhabitant (A: Type) := default : A.
Instance Inhabitant_Z : Inhabitant Z := 0.
Instance Inhabitant_nat : Inhabitant nat := O.
Instance Inhabitant_positive : Inhabitant positive := 1%positive.
Instance Inhabitant_list {T: Type} : Inhabitant (list T) := @nil T.
Instance Inhabitant_fun {T1 T2: Type} {H: Inhabitant T2} : Inhabitant (T1->T2) := fun _ => H.
Instance Inhabitant_Prop : Inhabitant Prop := False.
Instance Inhabitant_bool : Inhabitant bool := false.
Instance Inhabitant_pair {T1 T2 : Type} {x1: Inhabitant T1} {x2: Inhabitant T2} : Inhabitant (T1*T2)%type := (x1,x2).

(* Specifications: *)
Lemma Zlength_length:
forall A (al: list A) (n: Z),
0 <= n ->
(Zlength al = n <-> length al = Z.to_nat n).
Lemma firstn_app1: forall {A} n (p l: list A),
(n <= Datatypes.length p)%nat ->
firstn n (p ++ l) = firstn n p.
Lemma firstn_app2: forall {A} (n: nat) (al bl: list A),
(n >= length al)%nat ->
firstn n (al++bl) = al ++ firstn (n - length al) bl.
Lemma firstn_list_repeat {A} (v:A): forall i k, (i<=k)%nat ->
firstn i (list_repeat k v) = list_repeat i v.
Lemma firstn_app:
forall {A} n m (al: list A), firstn n al ++ firstn m (skipn n al) =
firstn (n+m) al.
Lemma nth_skipn:
forall {A} i n data (d:A),
nth i (skipn n data) d = nth (i+n) data d.
Lemma skipn_skipn: forall {A} n m (xs: list A),
skipn n (skipn m xs) = skipn (m + n) xs.
Lemma firstn_exact_length: forall {A} (xs: list A), firstn (length xs) xs = xs.
Lemma skipn_exact_length: forall {A} (xs: list A), skipn (length xs) xs = nil.
Lemma len_le_1_rev: forall {A} (contents: list A),
(length contents <= 1)%nat ->
contents = rev contents.
Lemma firstn_firstn: forall {A} (contents: list A) n m,
(n <= m)%nat ->
firstn n (firstn m contents) = firstn n contents.
Lemma firstn_1_skipn: forall {A} n (ct: list A) d,
(n < length ct)%nat ->
nth n ct d :: nil = firstn 1 (skipn n ct).
Lemma skipn_length: forall {A} (contents: list A) n,
length (skipn n contents) = (length contents - n)%nat.
Lemma nth_firstn: forall {A} (contents: list A) n m d,
(n < m)%nat ->
nth n (firstn m contents) d = nth n contents d.
Lemma skipn_length_short:
forall {A} n (al: list A),
(length al <= n)%nat ->
(length (skipn n al) = 0)%nat.
Lemma skipn_short:
forall {A} n (al: list A), (n >= length al)%nat -> skipn n al = nil.
Lemma nth_map':
forall {A B} (f: A -> B) d d' i al,
(i < length al)%nat ->
nth i (map f al) d = f (nth i al d').
Lemma skipn_nil: forall A n, skipn n (@nil A) = nil.
Lemma skipn_drop:
forall A n m (al: list A), skipn n (skipn m al) = skipn (n+m) al.
Lemma skipn_app1:
forall A n (al bl: list A),
(n <= length al)%nat ->
skipn n (al++bl) = skipn n al ++ bl.
Lemma skipn_app2:
forall A n (al bl: list A),
(n >= length al)%nat ->
skipn n (al++bl) = skipn (n-length al) bl.
Lemma list_repeat_app: forall A a b (x:A),
list_repeat a x ++ list_repeat b x = list_repeat (a+b) x.
Lemma firstn_same:
forall A n (b: list A), (n >= length b)%nat -> firstn n b = b.
Lemma nth_firstn_low:
forall A i n al (d: A),
(i < n <= length al)%nat -> nth i (firstn n al) d = nth i al d.
Lemma nth_error_nth:
forall A (d: A) i al, (i < length al)%nat -> nth_error al i = Some (nth i al d).
Lemma skipn_rev:
forall {A} n (vl: list A),
skipn n (rev vl) = rev (firstn (length vl - n) vl).
Lemma Forall_list_repeat:
forall {A} (P: A -> Prop) (n: nat) (a: A),
P a -> Forall P (list_repeat n a).
Lemma skipn_firstn: forall {A} n m (xs: list A),
skipn n (firstn m xs) = firstn (m-n) (skipn n xs).
Lemma rev_skipn:
forall {A} n (vl: list A),
rev (skipn n vl) = firstn (length vl -n) (rev vl).
Lemma firstn_skipn_rev:
forall {A} lo n (vl: list A),
(n+lo <= length vl)%nat ->
firstn n (skipn lo (rev vl)) =
rev (firstn n (skipn (length vl - (lo+n))%nat vl)).
Lemma map_firstn:
forall A B (F: A -> B) n (al: list A),
map F (firstn n al) = firstn n (map F al).
Lemma map_skipn:
forall A B (F: A -> B) n (al: list A),
map F (skipn n al) = skipn n (map F al).
Lemma Zlength_app: forall T (al bl: list T),
Zlength (al++bl) = Zlength al + Zlength bl.
Lemma Zlength_rev: forall T (vl: list T), Zlength (rev vl) = Zlength vl.
Lemma Zlength_map: forall A B (f: A -> B) l, Zlength (map f l) = Zlength l.
Lemma ZtoNat_Zlength:
forall {A} (l: list A), Z.to_nat (Zlength l) = length l.