(* find, count, has, all. *)
Section SeqFind.
Variable a : pred T.
Fixpoint find s := if s is x :: s' then if a x then 0 else (find s').+1 else 0.
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 filter_all s : all (filter s).
Lemma filter_id s : filter (filter s) = filter s.
Lemma has_nil : has [::] = false. Proof. by []. Qed.
Lemma has_seq1 x : has [:: x] = a x.
Lemma filter_cat s1 s2 : filter (s1 ++ s2) = filter s1 ++ filter s2.
Lemma sub_all s : all a1 s -> all a2 s.
End SubPred.
Lemma filter_pred0 s : filter pred0 s = [::]. Proof. by elim: s. Qed.
Lemma filter_predT s : filter predT s = s.
Lemma count_pred0 s : count pred0 s = 0.
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.
Fixpoint drop n s {struct s} :=
match s, n with
| _ :: s', n'.+1 => drop n' s'
| _, _ => s
end.