Hint Rewrite @app_nil_l @app_nil_r : sublist.

(* Specifications: *)
Lemma app_Znth1:
forall A (a: Inhabitant A) (l l': list A) (i:Z),
i < Zlength l -> Znth i (l++l') = Znth i l.
Lemma app_Znth2:
forall A (a: Inhabitant A) (l l': list A) (i:Z),
i >= Zlength l -> Znth i (l++l') = Znth (i-Zlength l) l'.
Lemma Znth_firstn:
forall {A}{a: Inhabitant A} (al: list A) (n m : Z),
n<m -> Znth n (firstn (Z.to_nat m) al) = Znth n al.
Lemma Znth_skipn: forall {A}{a: Inhabitant A}  i n xs,
0 <= i ->
0 <= n ->
Znth i (skipn (nat_of_Z n) xs) = Znth (i+n) xs.
Lemma Z2Nat_neg: forall i, i < 0 -> Z.to_nat i = 0%nat.
Lemma Zlength_firstn:
forall {A} n (v: list A), Zlength (firstn (Z.to_nat n) v) = Z.min (Z.max 0 n) (Zlength v).
Lemma Zlength_skipn:
forall {A} n (v: list A),
Zlength (skipn (Z.to_nat n) v) = Z.max 0 (Zlength v - (Z.max 0n)).
Lemma Znth_cons:
forall {A}(a: Inhabitant A)  i (al: list A) bl,
0 <= i < Zlength al  ->
Znth i al :: bl = firstn (Z.to_nat 1) (skipn (Z.to_nat i) al) ++ bl.
Lemma Zfirstn_app1:
forall A n (al bl: list A),
n <= Zlength al -> firstn (Z.to_nat n) (al++bl) = firstn (Z.to_nat n) al.
Lemma Zfirstn_same:
forall A n (b: list A), n >= Zlength b -> firstn (Z.to_nat n) b = b.
Lemma Zfirstn_app2: forall {A} n (al bl: list A),
n >= Zlength al ->
firstn (Z.to_nat n) (al++bl) = al ++ firstn (Z.to_nat (n - Zlength al)) bl.
Lemma Zfirstn_firstn: forall {A} (contents: list A) n m,
n <= m ->
firstn (Z.to_nat n) (firstn (Z.to_nat m) contents) = firstn (Z.to_nat n) contents.
Lemma Zskipn_app1:
forall A n (al bl: list A),
n <= Zlength al ->
skipn (Z.to_nat n) (al++bl) = skipn (Z.to_nat n) al ++ bl.
Lemma Zskipn_app2:
forall A n (al bl: list A),
n >= Zlength al ->
skipn (Z.to_nat n) (al++bl) = skipn (Z.to_nat (n-Zlength al)) bl.
Lemma Znth_rev:
forall {A}{d: Inhabitant A} i (al:list A),
0 <= i < Zlength al ->
Znth i (rev al) = Znth (Zlength al - i - 1) al.
Lemma Zskipn_firstn: forall {A} n m (xs: list A),
0 <= n ->
skipn (Z.to_nat n) (firstn (Z.to_nat m) xs) =
firstn (Z.to_nat (m-n)) (skipn (Z.to_nat n) xs).
Lemma Zskipn_skipn: forall {A} n m (xs: list A),
0 <= n -> 0 <= m ->
skipn (Z.to_nat n) (skipn (Z.to_nat m) xs) = skipn (Z.to_nat (m + n)) xs.
Lemma Zfirstn_app:
forall {A} n m (al: list A),
0 <= n -> 0 <= m ->
firstn (Z.to_nat n) al ++ firstn (Z.to_nat m) (skipn (Z.to_nat n) al) =
firstn (Z.to_nat (n+m)) al.
Lemma Zfirstn_exact_length:
forall {A} n (al: list A),
n = Zlength al ->
firstn (Z.to_nat n) al = al.