Module Freezer : FREEZER.
Definition FRZ (p: mpred) := p.
Definition FRZL (ps:list mpred): mpred := fold_right sepcon emp ps.
Inductive FRZRw' (L1 G1: list mpred): Type :=
| FRZRw'_constr: forall F: mpred,
(fold_right sepcon emp G1) |-- fold_right sepcon emp L1 * F -> FRZRw' L1 G1.
Definition FRZRw := FRZRw'.
Definition FRZRw_constr:= FRZRw'_constr.
Definition FRZR (L1 G1: list mpred) {w: FRZRw L1 G1}: mpred :=
match w with
| FRZRw'_constr F _ => F
end.
Tactic Notation "freeze1_SEP" constr(n) :=
eapply (freeze1_SEP' (Z.to_nat n)); simpl.
Tactic Notation "freeze1_SEP" constr(n) constr(m) :=
(gather_SEP' (n::m::nil)); eapply (freeze1_SEP' (Z.to_nat 0)); simpl.
Tactic Notation "freeze1_SEP" constr(n) constr(m) constr(k)  :=
(gather_SEP' (n::m::k::nil)); eapply (freeze1_SEP' (Z.to_nat 0)); simpl.
Tactic Notation "freeze1_SEP" constr(n) constr(m) constr(k)  constr(p) :=
(gather_SEP' (n::m::k::p::nil)); eapply (freeze1_SEP' (Z.to_nat 0)); simpl.
Tactic Notation "freeze1_SEP" constr(n) constr(m) constr(k) constr(p) constr(q) :=
(gather_SEP' (n::m::k::p::q::nil)); eapply (freeze1_SEP' (Z.to_nat 0)); simpl.
(*******************freezing a list of mpreds ******************************)
Fixpoint delete_list {A: Type} (ns: list nat) (xs: list A) : list A :=
(* ns must already be sorted *)
match ns with
| nil => xs
| n::ns' => delete_nth n (delete_list ns' xs)
end.
Definition freezelist_nth (ns: list nat) (al: list mpred) : list mpred * list mpred :=
(map (fun i => my_nth i al emp) ns,
delete_list (SortNat.sort ns) al).

Lemma my_nth_delete_nth_permutation:
forall al a,
(a < length al)%nat -> Permutation al (my_nth a al emp :: delete_nth a al).