Ltac delete_emp_in_SEP :=
repeat
match goal with |- context [SEPx ?R] =>
match R with context [emp:: ?R'] =>
rewrite (delete_emp_in_SEP (length R - S (length R')) R) by reflexivity;
simpl length; simpl minus; unfold firstn, app, list_drop; fold app
end
end.
Ltac move_from_SEP :=
(* combines extract_exists_in_SEP, move_prop_from_SEP, (*move_local_from_SEP, *)
flatten_sepcon_in_SEP *)
match goal with |- context [PROPx _ (LOCALx _ (SEPx ?R))] =>
match R with
| context [(prop ?P1 && ?Rn) :: ?R'] =>
let n := length_of R in let n' := length_of R' in
rewrite (extract_prop_in_SEP (n-S n')%nat P1 Rn) by reflexivity;
simpl minus; unfold replace_nth (*;
try (apply semax_extract_PROP; intro)*)
| context [ exp ?z :: _] =>
let n := find_in_list (exp z) R
in rewrite (grab_nth_SEP n); unfold nth, delete_nth; rewrite extract_exists_in_SEP;
repeat_extract_exists_pre
| context [ (sepcon ?x  ?y) :: ?R'] =>
let n := length_of R in let n' := length_of R' in
rewrite (grab_nth_SEP (n-S n')); simpl minus; unfold nth, delete_nth;
rewrite flatten_sepcon_in_SEP
end
end.

Lemma nth_error_local:
forall n Delta P Q R (Qn: localdef),
nth_error Q n = Some Qn ->
ENTAIL Delta, PROPx P (LOCALx Q R) |-- local (locald_denote Qn).