(* Surgery: drop, take, rot, rotr.                                        *)

(* Specifications: *)
Lemma drop_behead : drop n0 =1 iter n0 behead.
Fixpoint take n s {struct s} :=
match s, n with
| x :: s', n'.+1 => x :: take n' s'
| _, _ => [::]
end.
Lemma take0 s : take 0 s = [::]. Proof. by case: s. Qed.
Lemma take_oversize n s : size s <= n -> take n s = s.
Lemma size_take s : size (take n0 s) = if n0 < size s then n0 else size s.
Lemma take_cat s1 s2 :
take n0 (s1 ++ s2) =
if n0 < size s1 then take n0 s1 else s1 ++ take (n0 - size s1) s2.
Lemma take_size_cat n s1 s2 : size s1 = n -> take n (s1 ++ s2) = s1.
Lemma nth_drop s i : nth (drop n0 s) i = nth s (n0 + i).
Lemma nth_take i : i < n0 -> forall s, nth (take n0 s) i = nth s i.
(* drop_nth and take_nth below do NOT use the default n0, because the "n"  *)
(* can be inferred from the condition, whereas the nth default value x0    *)
(* will have to be given explicitly (and this will provide "d" as well).   *)
Lemma drop_nth n s : n < size s -> drop n s = nth s n :: drop n.+1 s.
Lemma rot_inj : injective (rot n0). Proof. exact (can_inj rotK). Qed.
Lemma rot1_cons x s : rot 1 (x :: s) = rcons s x.
Lemma filter_rev a s : filter a (rev s) = rev (filter a s).
Lemma drop_rev s n : drop n (rev s) = rev (take (size s - n) s).
End Rev.