unfold product.
intros.
rewrite map_concat.
rewrite map_map.
induction a.
simpl.
rewrite app_nil_r.
rewrite map_map.
unfold uncurry.
simpl.
rewrite (map_ext (fun x => merges [] x) (fun x => x :: nil))...
rewrite concat_map_singleton...
simpl.
unfold Basics.compose.
rewrite IHa. clear IHa.
rewrite (map_ext (fun x : list T => map (uncurry merges) (map (pair x) (perms b)))
(fun x : list T => map (merges x) (perms b))).
rewrite (map_ext (fun x : list T => map (uncurry merges) (map (pair x) (perms b)))
(fun x : list T => map (merges x) (perms b))).
rewrite concat_concat.
rewrite concat_concat.
rewrite map_map.
rewrite map_map.
rewrite map_concat_map.
rewrite concat_concat.
rewrite map_map.
rewrite map_concat_map.
rewrite concat_concat.
rewrite map_map.
apply Permutation_concatMap.
intros.
unfold Basics.compose.
rewrite map_concat_map.
rewrite concat_concat.
rewrite map_map.
rewrite (map_ext (fun x0 => concat ((map (insert_everywhere a) ∘ merges x) x0))
(concat ∘ (map (insert_everywhere a) ∘ merges x)))...
transitivity (concat (map (concat ∘ map (merges x) ∘ insert_everywhere a) (perms b))).
apply Permutation_concatMap.
intros.
unfold Basics.compose.
apply insert_everywhere_merges_commute.
apply Permutation_sym.
rewrite <- (concat_product merges (perms b) (insert_everywhere a x)).
apply Permutation_concatMap.
intros.
unfold Basics.compose.
apply Permutation_sym.
rewrite <- insert_everywhere_merges_commute.
transitivity (concat (map (merges x0) (insert_everywhere a x))).
apply Permutation_sym.
rewrite <- insert_everywhere_merges_commute...
rewrite merges_sym...
apply Permutation_concatMap.
intros...
intros.
rewrite map_map...
intros.
rewrite map_map...
Qed.

(* Specifications: *)
Lemma filter_merges p (x y: list T):
(forall z, In z x -> p z = true) ->
(forall z, In z y -> p z = false) ->
forall r, In r (map (filter p) (merges x y)) -> r = x.