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.

(* Specifications: *)
Lemma replace_nth_replace_nth: forall {A: Type} R n {Rn Rn': A},
replace_nth n (replace_nth n R Rn) Rn' = replace_nth n R Rn'.
Lemma replace_nth_nth_error: forall {A:Type} R n (Rn:A),
nth_error R n = Some Rn ->
R = replace_nth n R Rn.
Lemma nth_error_replace_nth: forall {A:Type} R n (Rn Rn':A),
nth_error R n = Some Rn ->
nth_error (replace_nth n R Rn') n = Some Rn'.
Lemma map_replace_nth:
forall {A B} (f: A -> B) n R X, map f (replace_nth n R X) =
replace_nth n (map f R) (f X).
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.
Lemma nth_error_replace_nth':
forall {A} i j R (a:A),
(i <> j)%nat -> nth_error (replace_nth i R a) j = nth_error R j.
Lemma replace_SEP':
forall n R' Espec {cs: compspecs} Delta P Q Rs c Post,
ENTAIL Delta, PROPx P (LOCALx Q (SEPx (my_nth n Rs TT ::  nil))) |-- `R' ->
@semax cs Espec Delta (PROPx P (LOCALx Q (SEPx (replace_nth n Rs R')))) c Post ->
@semax cs Espec Delta (PROPx P (LOCALx Q (SEPx Rs))) c Post.
Lemma replace_SEP'':
forall n R' Delta P Q Rs Post,
ENTAIL Delta, PROPx P (LOCALx Q (SEPx (my_nth n Rs TT ::  nil))) |-- `R' ->
ENTAIL Delta, PROPx P (LOCALx Q (SEPx (replace_nth n Rs R'))) |-- Post ->
ENTAIL Delta, PROPx P (LOCALx Q (SEPx Rs)) |-- Post.