Ltac gather_SEP' L :=
grab_indexes_SEP L;
match goal with |- context [SEPx ?R] =>
let r := fresh "R" in
set (r := (SEPx R));
revert r;
rewrite <- (firstn_skipn (length L) R);
unfold length at 1 2;
unfold firstn at 1; unfold skipn at 1;
rewrite gather_SEP;
unfold fold_right at 1; try  rewrite sepcon_emp;
try (intro r; unfold r; clear r)
end.
Tactic Notation "gather_SEP" constr(a) :=
gather_SEP' (a::nil).
Tactic Notation "gather_SEP" constr(a) constr(b) :=
gather_SEP' (a::b::nil).
Tactic Notation "gather_SEP" constr(a) constr(b) constr(c) :=
gather_SEP' (a::b::c::nil).
Tactic Notation "gather_SEP" constr(a) constr(b) constr(c) constr(d) :=
gather_SEP' (a::b::c::d::nil).
Tactic Notation "gather_SEP" constr(a) constr(b) constr(c) constr(d) constr(e) :=
gather_SEP' (a::b::c::d::e::nil).
Tactic Notation "gather_SEP" constr(a) constr(b) constr(c) constr(d) constr(e) constr(f) :=
gather_SEP' (a::b::c::d::e::f::nil).
Tactic Notation "gather_SEP" constr(a) constr(b) constr(c) constr(d) constr(e) constr(f) constr(g) :=
gather_SEP' (a::b::c::d::e::f::g::nil).
Tactic Notation "gather_SEP" constr(a) constr(b) constr(c) constr(d) constr(e) constr(f) constr(g) constr(h) :=
gather_SEP' (a::b::c::d::e::f::g::h::nil).
Tactic Notation "gather_SEP" constr(a) constr(b) constr(c) constr(d) constr(e) constr(f) constr(g) constr(h) constr(i) :=
gather_SEP' (a::b::c::d::e::f::g::h::i::nil).
Tactic Notation "gather_SEP" constr(a) constr(b) constr(c) constr(d) constr(e) constr(f) constr(g) constr(h) constr(i) constr(j) :=
gather_SEP' (a::b::c::d::e::f::g::h::i::j::nil).
Fixpoint replace_nth {A} (n: nat) (al: list A) (x: A) {struct n}: list A :=
match n, al with
| O , a::al => x::al
| S n', a::al' => a :: replace_nth n' al' x
| _, nil => nil
end.
Fixpoint my_nth{A} (n: nat) (al: list A) (default: A) {struct n} : A :=
(* just like nth; make a new copy, for better control of unfolding *)
match n, al with
| O, a::al' => a
| S n', a::al' => my_nth n' al' default
| _, nil => default
end.

Lemma replace_nth_commute:
forall {A} i j R (a b: A),
i <> j ->
replace_nth i (replace_nth j R b) a =
replace_nth j (replace_nth i R a) b.