Fixpoint filterMap {A B} (f : A -> option B) (l : list A) : list B :=
  match l with
    | [] => []
    | x :: xs => match f x with
                   | None => filterMap f xs
                   | Some y => y :: filterMap f xs
                 end
  end.

(* Specifications: *)
Lemma map_of_filterMap : forall (f : A -> option B) (g : B -> C) l, map g (filterMap f l) = filterMap (fun x => match f x with | Some y => Some (g y) | None => None end) l.
Lemma filterMap_ext : forall (f g : A -> option B) l, (forall x, f x = g x) -> filterMap f l = filterMap g l.
Lemma filterMap_defn : forall (f : A -> option B) x xs, filterMap f (x :: xs) = match f x with | Some y => y :: filterMap f xs | None => filterMap f xs end.
Lemma In_filterMap : forall (f : A -> option B) b xs, In b (filterMap f xs) -> exists a, In a xs /\ f a = Some b.
Lemma filterMap_app : forall (f : A -> option B) xs ys, filterMap f (xs ++ ys) = filterMap f xs ++ filterMap f ys.
Lemma filterMap_In : forall A B (f : A -> option B) a b xs, f a = Some b -> In a xs -> In b (filterMap f xs).
Lemma filterMap_of_filterMap : forall (f : B -> option C) (g : A -> option B) xs, filterMap f (filterMap g xs) = filterMap (fun a => match g a with | Some b => f b | None => None end) xs.
Lemma filterMap_all_None : forall (f : A -> option B) xs, (forall x, In x xs -> f x = None) -> filterMap f xs = [].
Lemma filterMap_NoDup_inj : forall (f : A -> option B) l, (forall x1 x2 y, f x1 = Some y -> f x2 = Some y -> x1 = x2) -> NoDup l -> NoDup (filterMap f l).