Ltac select_left n :=
repeat match goal with
| |- context [(_ * mark ?i _ * mark n _)] =>
rewrite (swap_mark1 i n); [ | solve [simpl; auto]]
| |- context [(mark ?i _ * mark n _)] =>
rewrite (swap_mark0 i n); [ | solve [simpl; auto]]
end.
Ltac select_all n := match n with
| O => idtac
| S ?n' => select_left n; select_all n'
end.
Ltac markem n P :=
match P with
| (?Y * ?Z) =>
(match goal with H: mark _ Z = Z |- _ => idtac end
|| assert (mark n Z = Z) by auto); markem (S n) Y
| ?Z =>  match goal with H: mark _ Z = Z |- _ => idtac end
|| assert (mark n Z = Z) by auto
end.
Ltac prove_assoc_commut :=
clear;
try (match goal with |- ?F _ -> ?G _ => replace G with F; auto end);
(repeat rewrite <- sepcon_assoc;
match goal with |- ?P = _ => markem O P end;
let LEFT := fresh "LEFT" in match goal with |- ?P = _ => set (LEFT := P) end;
match goal with H: mark ?n _ = _ |- _ =>
repeat  match goal with H: mark ?n _ = ?P |- _ => rewrite <- H; clear H end;
select_all n;
reflexivity
end).

Lemma test_prove_assoc_commut {T}{NA: NatDed T}{SA: SepLog T} : forall A B C D E : T,
D * E * A * C * B = A * B * C * D * E.