Definition rotate {A} (l : list A) n m := sublist (m - n) (Zlength l) l ++
sublist 0 (m - n) l.

(* Specifications: *)
Lemma sublist_of_nil : forall {A} i j, sublist i j (@nil A) = [].
Lemma sublist_0_cons : forall {A} j x (l : list A), j > 0 ->
sublist 0 j (x :: l) = x :: sublist 0 (j - 1) l.
Lemma sublist_S_cons : forall {A} i j x (l : list A), i > 0 ->
sublist i j (x :: l) = sublist (i - 1) (j - 1) l.
Lemma upd_rotate : forall {A} i (l : list A) n m x (Hl : Zlength l = m) (Hlt : 0 <= n <= m)
(Hi : 0 <= i < Zlength l),
upd_Znth i (rotate l n m) x = rotate (upd_Znth ((i - n) mod m) l x) n m.
Lemma Znth_cons_eq : forall {A}{d : Inhabitant A} i x l,
Znth i (x :: l) = if eq_dec i 0 then x else Znth (i - 1) l.
Lemma Znth_rotate : forall {A} {d : Inhabitant A} i l n,
0 <= n <= Zlength l -> 0 <= i < Zlength l ->
Znth i (rotate l n (Zlength l)) = Znth ((i - n) mod Zlength l) l.
Lemma rotate_nil : forall {A} n m, rotate (@nil A) n m = [].
Lemma Forall_sublist_le : forall {A} {d : Inhabitant A} (P : A -> Prop) i j l
(Hrangei : 0 <= i) (Hrangej : j <= Zlength l) (Hi : ~P (Znth i l)) (Hj : Forall P (sublist 0 j l)),
j <= i.
Corollary Forall_sublist_first : forall {A} {d : Inhabitant A} (P : A -> Prop) i j l
(Hrangei : 0 <= i <= Zlength l) (Hi : Forall P (sublist 0 i l)) (Hi' : ~P (Znth i l))
(Hrangej : 0 <= j <= Zlength l) (Hj : Forall P (sublist 0 j l)) (Hj' : ~P (Znth j l)),
i = j.
Lemma NoDup_Znth_inj : forall {A} {d : Inhabitant A} l i j (HNoDup : NoDup l)
(Hi : 0 <= i < Zlength l) (Hj : 0 <= j < Zlength l) (Heq : Znth i l = Znth j l ),
i = j.
Lemma rotate_In : forall {A} (x : A) n m l, 0 <= m - n <= Zlength l -> In x (rotate l n m) <-> In x l.
Lemma rotate_map : forall {A B} (f : A -> B) n m l, rotate (map f l) n m = map f (rotate l n m).
Lemma combine_app : forall {A B} (l1 l2 : list A) (l1' l2' : list B), length l1 = length l1' ->
combine (l1 ++ l2) (l1' ++ l2') = combine l1 l1' ++ combine l2 l2'.
Lemma combine_app' : forall {A B} (l1 l2 : list A) (l1' l2' : list B), Zlength l1 = Zlength l1' ->
combine (l1 ++ l2) (l1' ++ l2') = combine l1 l1' ++ combine l2 l2'.
Lemma Forall_rotate : forall {A} P (l : list A) n m, Forall P l ->
Forall P (rotate l m n).
Lemma Forall_repeat : forall {A} (P : A -> Prop) x n, P x -> Forall P (repeat x n).
Lemma Forall_complete : forall P l m, Forall P l -> P (vptrofs 0) ->
Forall P (complete m l).
Lemma app_eq_inv : forall {A} (l1 l2 l3 l4 : list A)
(Heq : l1 ++ l2 = l3 ++ l4) (Hlen : length l1 = length l3), l1 = l3 /\ l2 = l4.
Lemma rotate_inj : forall {A} (l1 l2 : list A) n m, rotate l1 n m = rotate l2 n m ->
length l1 = length l2 -> 0 <= n <= m -> m <= Zlength l1 -> l1 = l2.
Lemma complete_inj : forall l1 l2 m, complete m l1 = complete m l2 ->
length l1 = length l2 -> l1 = l2.
Lemma length_complete : forall l m, Zlength l <= m -> length (complete m l) = Z.to_nat m.
Lemma Zlength_rotate : forall {A} (l : list A) n m, 0 <= n <= m -> m <= Zlength l ->
Zlength (rotate l n m) = Zlength l.
Lemma Zlength_repeat : forall {A} (x : A) n, Zlength (repeat x n) = Z.of_nat n.
Lemma Zlength_complete : forall l m, Zlength l <= m -> Zlength (complete m l) = m.
Lemma combine_eq : forall {A B} (l : list (A * B)), combine (map fst l) (map snd l) = l.
Lemma signed_inj : forall i1 i2, Int.signed i1 = Int.signed i2 -> i1 = i2.
Lemma mods_repr : forall a b, 0 <= a <= Int.max_signed -> 0 < b <= Int.max_signed ->
Int.mods (Int.repr a) (Int.repr b) = Int.repr (a mod b).
Lemma repeat_list_repeat : forall {A} n (x : A), repeat x n = list_repeat n x.
Lemma sublist_repeat : forall {A} i j k (v : A), 0 <= i -> i <= j <= k ->
sublist i j (repeat v (Z.to_nat k)) = repeat v (Z.to_nat (j - i)).
Lemma Znth_head : forall reqs head m, Zlength reqs <= m -> 0 <= head < m ->
Zlength reqs > 0 ->
Znth head (rotate (complete m reqs) head m) = Znth 0 reqs.
Lemma Znth_repeat : forall {A} {x : Inhabitant A} n i, Znth i (repeat default n) = default.
Lemma Znth_repeat' : forall {A} {d: Inhabitant A} (x : A) n i,
0 <= i < Z.of_nat n -> Znth i (repeat x n)  = x.
Lemma rotate_1 : forall v l n m, 0 <= n < m -> Zlength l < m ->
rotate (upd_Znth 0 (complete m (v :: l)) (vptrofs 0)) n m =
rotate (complete m l) ((n + 1) mod m) m.
Lemma upd_complete_gen : forall {A} (l : list A) x n y, Zlength l < n ->
upd_Znth (Zlength l) (l ++ repeat y (Z.to_nat (n - Zlength l))) x =
(l ++ [x]) ++ repeat y (Z.to_nat (n - Zlength (l ++ [x]))).
Lemma upd_complete' : forall l x n, (length l < n)%nat ->
upd_Znth (Zlength l) (map Vint (map Int.repr l) ++ repeat Vundef (n - length l)) (Vint (Int.repr x)) =
map Vint (map Int.repr (l ++ [x])) ++ repeat Vundef (n - length (l ++ [x])).