(** *** Filter *)
Variable X : Type.
Implicit Types (x y: X) (A B C: list X) (p q: X -> bool).
Fixpoint filter p A : list X :=
match A with
| nil => nil
| x::A' => if p x then x :: filter p A' else filter p A'
end.

(* Specifications: *)
Lemma in_filter_iff x p A :
x el filter p A <-> x el A /\ p x.
Lemma filter_incl p A :
filter p A <<= A.
Lemma filter_mono p A B :
A <<= B -> filter p A <<= filter p B.
Lemma filter_id p A :
(forall x, x el A -> p x) -> filter p A = A.
Lemma filter_app p A B :
filter p (A ++ B) = filter p A ++ filter p B.
Lemma filter_fst p x A :
p x -> filter p (x::A) = x::filter p A.
Lemma filter_fst' p x A :
~ p x -> filter p (x::A) = filter p A.
Lemma filter_pq_mono p q A :
(forall x, x el A -> p x -> q x) -> filter p A <<= filter q A.
Lemma filter_pq_eq p q A :
(forall x, x el A -> p x = q x) -> filter p A = filter q A.
Lemma filter_and p q A :
filter p (filter q A) = filter (fun x => p x && q x) A.
Lemma filter_comm p q A :
filter p (filter q A) = filter q (filter p A).