Fixpoint assoc {A B : Type}(eq : A -> A -> bool)(x : A)(l : list (A * B)) : option B :=
  match l with
  | nil => None
  | (x', y) :: l' => if eq x x' then Some y else assoc eq x l'
  end.Definition assoc_default {A B : Type}
  (eqA : A -> A -> bool) (d : B) (l : list (A * B)) (x : A) : B :=
  match assoc eqA x l with
  | None => d
  | Some b => b
  end.

Lemma flat_map_comp (A B C : Type) (f : A -> B) (g : B -> list C) (h : A -> list C) (l : list A) : (forall x, In x l -> h x = g (f x)) -> flat_map h l = flat_map g (map f l).