Tactic Notation "freeze1_SEP" constr(n) constr(m) :=
(gather_SEP n m); eapply (freeze1_SEP' (nat_of_Z 0)); simpl.
Tactic Notation "freeze1_SEP" constr(n) constr(m) constr(k)  :=
(gather_SEP n m k); eapply (freeze1_SEP' (nat_of_Z 0)); simpl.
Tactic Notation "freeze1_SEP" constr(n) constr(m) constr(k)  constr(p) :=
(gather_SEP n m k p); eapply (freeze1_SEP' (nat_of_Z 0)); simpl.
Tactic Notation "freeze1_SEP" constr(n) constr(m) constr(k) constr(p) constr(q) :=
(gather_SEP n m k p q); eapply (freeze1_SEP' (nat_of_Z 0)); simpl.
(*******************freezing a list of mpreds ******************************)
Fixpoint freezelist_nth (l: list nat) (al: list mpred): (list mpred) * (list mpred) :=
match l with
| nil => (nil,al)
| (n::l') => let (xs, ys) := freezelist_nth l' al
in (nth n ys emp::xs, delete_nth n ys)
end.

(* Specifications: *)
Lemma FRZL_ax ps: FRZL ps = fold_right_sepcon ps.
Lemma fold_right_sepcon_deletenth': forall n (l:list (LiftEnviron mpred)),
@fold_right (environ -> mpred) (environ -> mpred) sepcon emp l =
nth n l emp * fold_right sepcon emp (delete_nth n l).
Lemma freeze_SEP':
forall l Espec {cs: compspecs} Delta P Q  R c Post xs ys,
(xs, ys) = freezelist_nth l R ->
@semax cs Espec Delta (PROPx P (LOCALx Q (SEPx (FRZL xs:: ys)))) c Post ->
@semax cs Espec Delta (PROPx P (LOCALx Q (SEPx R))) c Post.
Lemma map_delete_nth {A B} (f:A->B): forall n l, delete_nth n (map f l) = map f (delete_nth n l).
Fixpoint my_nth {A} (n : nat) (l : list A) (default : A) {struct l} : A :=
match n with
| 0%nat => match l with
| [] => default
| x :: _ => x
end
| S m => match l with
| [] => default
| _ :: t => my_nth m t default
end
end.
Lemma my_nth_nth {A}: forall n l (d:A), my_nth n l d = nth n l d.
(*Variant if l is monotonically decreasing Fixpoint new_freezelist_nth (l: list nat) (al: list mpred): (list mpred) * (list mpred) := match l with | nil => (nil,al) | (n::l') => let (xs, ys) := new_freezelist_nth l' (my_delete_nth n al) in (my_nth n al emp::xs, ys) end.*)
Lemma freeze_SEP'':
forall l Espec {cs: compspecs} Delta P Q  R c Post xs ys,
(xs, ys) = my_freezelist_nth l R ->
@semax cs Espec Delta (PROPx P (LOCALx Q (SEPx (FRZL xs:: ys)))) c Post ->
@semax cs Espec Delta (PROPx P (LOCALx Q (SEPx R))) c Post.
Lemma flatten_emp_in_SEP':
forall n P Q (R: list mpred) R',
nth_error R n = Some emp ->
R' = firstn n R ++ skipn (S n) R ->
PROPx P (LOCALx Q (SEPx R)) = PROPx P (LOCALx Q (SEPx R')).