Section flat_map.
Variable (X Y : Type) (f : X -> list Y).
Fact flat_map_app l1 l2 : flat_map f (l1++l2) = flat_map f l1 ++ flat_map f l2.
Fact flat_map_app_inv l r1 y r2 : flat_map f l = r1++y::r2 -> exists l1 m1 x m2 l2, l = l1++x::l2 /\ f x = m1++y::m2
/\ r1 = flat_map f l1++m1 /\ r2 = m2++flat_map f l2.
End flat_map.
Fact in_concat_iff X (ll : list (list X)) x : In x (concat ll) <-> exists l, In x l /\ In l ll.
Fact flat_map_flat_map X Y Z (f : X -> list Y) (g : Y -> list Z) l :
flat_map g (flat_map f l) = flat_map (fun x => flat_map g (f x)) l.
Fact flat_map_single X Y (f : X -> Y) l : flat_map (fun x => f x::nil) l = map f l.

Theorem In_list_in_map_inv l f y : In y (list_in_map l f) -> exists x Hx, y = f x Hx.