Fixpoint filter s :=
  if s is x :: s' then if a x then x :: filter s' else filter s' else [::].Fixpoint count s := if s is x :: s' then a x + count s' else 0.Fixpoint has s := if s is x :: s' then a x || has s' else false.Fixpoint all s := if s is x :: s' then a x && all s' else true.

(* Specifications: *)
Lemma size_filter s : size (filter s) = count s.
Lemma has_count s : has s = (0 < count s).
Lemma count_size s : count s <= size s.
Lemma filter_all s : all (filter s).
Lemma all_filterP s : reflect (filter s = s) (all s).
Lemma filter_id s : filter (filter s) = filter s.
Lemma has_find s : has s = (find s < size s).
Lemma find_size s : find s <= size s.
Lemma find_cat s1 s2 : find (s1 ++ s2) = if has s1 then find s1 else size s1 + find s2.
Lemma has_nil : has [::] = false.
Lemma has_seq1 x : has [:: x] = a x.
Lemma has_nseq n x : has (nseq n x) = (0 < n) && a x.
Lemma has_seqb (b : bool) x : has (nseq b x) = b && a x.
Lemma all_nil : all [::] = true.
Lemma all_seq1 x : all [:: x] = a x.
Lemma find_nseq n x : find (nseq n x) = ~~ a x * n.
Lemma nth_find s : has s -> a (nth s (find s)).
Lemma before_find s i : i < find s -> a (nth s i) = false.
Lemma filter_cat s1 s2 : filter (s1 ++ s2) = filter s1 ++ filter s2.
Lemma filter_rcons s x : filter (rcons s x) = if a x then rcons (filter s) x else filter s.
Lemma count_cat s1 s2 : count (s1 ++ s2) = count s1 + count s2.
Lemma has_cat s1 s2 : has (s1 ++ s2) = has s1 || has s2.
Lemma has_rcons s x : has (rcons s x) = a x || has s.
Lemma all_cat s1 s2 : all (s1 ++ s2) = all s1 && all s2.
Lemma all_rcons s x : all (rcons s x) = a x && all s.
Lemma eq_find a1 a2 : a1 =1 a2 -> find a1 =1 find a2.
Lemma eq_filter a1 a2 : a1 =1 a2 -> filter a1 =1 filter a2.
Lemma eq_count a1 a2 : a1 =1 a2 -> count a1 =1 count a2.
Lemma eq_has a1 a2 : a1 =1 a2 -> has a1 =1 has a2.
Lemma eq_all a1 a2 : a1 =1 a2 -> all a1 =1 all a2.
Lemma sub_find s : find a2 s <= find a1 s.
Lemma sub_has s : has a1 s -> has a2 s.
Lemma sub_count s : count a1 s <= count a2 s.
Lemma sub_all s : all a1 s -> all a2 s.
Lemma filter_pred0 s : filter pred0 s = [::].
Lemma filter_predT s : filter predT s = s.
Lemma filter_predI a1 a2 s : filter (predI a1 a2) s = filter a1 (filter a2 s).
Lemma count_pred0 s : count pred0 s = 0.
Lemma count_predT s : count predT s = size s.
Lemma count_predUI a1 a2 s : count (predU a1 a2) s + count (predI a1 a2) s = count a1 s + count a2 s.
Lemma count_predC a s : count a s + count (predC a) s = size s.
Lemma count_filter a1 a2 s : count a1 (filter a2 s) = count (predI a1 a2) s.
Lemma has_pred0 s : has pred0 s = false.
Lemma has_predT s : has predT s = (0 < size s).
Lemma has_predC a s : has (predC a) s = ~~ all a s.
Lemma has_predU a1 a2 s : has (predU a1 a2) s = has a1 s || has a2 s.
Lemma all_predT s : all predT s.
Lemma all_predC a s : all (predC a) s = ~~ has a s.
Lemma all_predI a1 a2 s : all (predI a1 a2) s = all a1 s && all a2 s.
Lemma drop_behead : drop n0 =1 iter n0 behead.
Lemma drop0 s : drop 0 s = s.
Lemma drop1 : drop 1 =1 behead.
Lemma drop_oversize n s : size s <= n -> drop n s = [::].
Lemma drop_size s : drop (size s) s = [::].
Lemma size_drop s : size (drop n0 s) = size s - n0.
Lemma drop_cat s1 s2 : drop n0 (s1 ++ s2) = if n0 < size s1 then drop n0 s1 ++ s2 else drop (n0 - size s1) s2.
Lemma drop_size_cat n s1 s2 : size s1 = n -> drop n (s1 ++ s2) = s2.
Lemma nconsK n x : cancel (ncons n x) (drop n).
Lemma drop_drop s n1 n2 : drop n1 (drop n2 s) = drop (n1 + n2) s.
Lemma take0 s : take 0 s = [::].
Lemma take_oversize n s : size s <= n -> take n s = s.
Lemma take_size s : take (size s) s = s.
Lemma drop_rcons s : n0 <= size s -> forall x, drop n0 (rcons s x) = rcons (drop n0 s) x.
Lemma cat_take_drop s : take n0 s ++ drop n0 s = s.
Lemma size_takel s : n0 <= size s -> size (take n0 s) = n0.
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 takel_cat s1 : n0 <= size s1 -> forall s2, take n0 (s1 ++ s2) = take n0 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.