(* written with list monad notation, this would be: Permutation (insert_everywhere a >>= merges y x) (merges y >>= insert_everywhere a x). *)
Proof with auto.
revert x y.
apply two_lists_rect; intros.
simpl.
rewrite merges_nil_r.
simpl.
repeat rewrite app_nil_r.
apply merges_insert_everywhere'.
simpl.
rewrite app_nil_r.
rewrite (map_ext (merges []) (fun x0 => [x0])).
rewrite concat_map_singleton...
intros.
apply merges_real_eq.
rewrite (merges_real_eq (y :: y') (x :: x')).
rewrite map_app.
rewrite concat_app.
repeat rewrite map_map.
simpl insert_everywhere.
rewrite (Permutation_concat_map_app (fun x0 => [a :: y :: x0]) (fun x0 => map (cons y) (insert_everywhere a x0))).
rewrite (Permutation_concat_map_app (fun x0 => [a :: x :: x0]) (fun x0 => map (cons x) (insert_everywhere a x0))).
repeat rewrite concat_app.
repeat rewrite concat_map_singleton_f.
rewrite app_ass.
rewrite <- (map_map (insert_everywhere a) (map (cons x))).
rewrite <- (map_map (insert_everywhere a) (map (cons y))).
rewrite <- map_concat.
rewrite <- map_concat.
rewrite H. rewrite H0.
clear H H0.
simpl @map at 7.
simpl @concat at 3.
rewrite map_map.
rewrite (merges_real_eq (y :: y') (a :: x :: x')).
rewrite (merges_real_eq (y :: y') (x :: x')).
rewrite map_app.
repeat rewrite map_map.
rewrite app_ass.
apply Permutation_sym.
rewrite (Permutation_app_swap (map (cons y) (merges y' (a :: x :: x')))).
repeat rewrite app_ass.
apply Permutation_app...
apply Permutation_sym.
rewrite (Permutation_app_swap (map (cons y) (concat (map (merges y') (insert_everywhere a (x :: x')))))).
repeat rewrite app_ass.
apply Permutation_app...
simpl.
rewrite map_map.
rewrite map_app.
rewrite (map_ext (fun x0 : list T => merges (y :: y') (x :: x0)) (fun x0 : list T => map (cons y) (merges y' (x :: x0)) ++ map (cons x) (merges (y :: y') x0))).
Focus 2.
intros.
rewrite merges_real_eq...
apply Permutation_sym.
rewrite Permutation_concat_map_app.
rewrite concat_app.
rewrite app_ass.
rewrite <- (map_map (fun x0 => merges y' (x :: x0)) (map (cons y))).
rewrite <- map_concat.
rewrite Permutation_app_swap.
rewrite <- app_ass.
apply Permutation_app...
rewrite <- (map_map (fun x0 => merges (y :: y') x0) (map (cons x))).
rewrite <- map_concat.
apply Permutation_app...
Qed. (* wow, can hardly believe it's true after this ordeal *)

(* Specifications: *)
Lemma merges_sym x y: Permutation (merges x y) (merges y x).
Proof with auto.