Fixpoint count (l: list X): nat :=
    match l with
    | nil => 0
    | h :: t => if p h then S (count t) else count t
    end.

(* Specifications: *)
Lemma count_app l l': count (l ++ l') = count l + count l'.
Lemma count_0 l: (forall x, In x l -> p x = false) -> count l = 0.
Lemma count_le l: count l <= length l.
Lemma count_filter_le (f: X -> bool) x: count (filter f x) <= count x.
Lemma count_lt v l: In v l -> p v = false -> count l < length l.
Lemma NoDup_map_inv' A B (f: A -> B) (l: list A): NoDup (map f l) -> NoDup l.
Lemma length_filter X (p: X -> bool) (l: list X): length (filter p l) = count p l.
Lemma length_filter_le T (p: T -> bool) (l: list T): length (filter p l) <= length l.
Lemma filter_all X (p: X -> bool) (l: list X): (forall x, In x l -> p x = true) -> filter p l = l.
Lemma In_filter T (p: T -> bool) (t: T): p t = true -> forall l, In t l -> In t (filter p l).
Lemma incl_filter X (p: X -> bool) (l: list X): incl (filter p l) l.
Lemma incl_trans A (x y: list A): incl x y -> forall z, incl y z -> incl x z.
Lemma filter_preserves_incl X (p: X -> bool) (a b: list X): incl a b -> incl (filter p a) (filter p b).
Lemma In_inv_perm X (x: X) (l: list X): In x l -> exists l', Permutation (x :: l') l.
Lemma In_map_inv T U (f: T -> U) (l: list T) (y: U): In y (map f l) -> exists x, f x = y /\ In x l.
Lemma Permutation_incl X (a b: list X): Permutation a b -> incl a b.
Lemma pointwise_eq_refl A B (x: A -> B): pointwise_relation A eq x x.
Lemma filter_none X (p: X -> bool) (l: list X): (forall x, In x l -> p x = false) <-> filter p l = nil.
Lemma incl_map X Y (f: X -> Y) (a b: list X): incl a b -> incl (map f a) (map f b).
Lemma incl_in T (a b: list T): incl a b -> forall x, In x a -> In x b.
Lemma incl_In X (x: X) (l: list X): In x l -> forall l', incl l l' -> In x l'.
Lemma NoDup_filter T (p: T -> bool) (l: list T): NoDup l -> NoDup (filter p l).
Lemma count_filtered X (p q: X -> bool): (forall x, q x = true -> p x = false) -> forall l, count p (filter q l) = 0.
Lemma app_nil_r T (l: list T): l ++ nil = l.
Lemma map_cons T U (f: T -> U) (h: T) (l: list T): map f (h :: l) = f h :: map f l.