Ltac unfold_app :=
change (@app mpred)
with (fix app (l m : list mpred) {struct l} : list mpred :=
match l with
| nil => m
| cons a l1 => cons a (app l1 m)
end);
change (@app Prop)
with (fix app (l m : list Prop) {struct l} : list Prop :=
match l with
| nil => m
| cons a l1 => cons a (app l1 m)
end);
cbv beta iota.
Ltac localize R_L :=
eapply (localize R_L); [prove_split_FRZ_in_SEP |];
let FR_L := fresh "RamL" in
let FR_G := fresh "RamG" in
intros FR_L FR_G;
eexists;
unfold_app.

(* Specifications: *)
Lemma unlocalize_aux: forall R_G2 R R_FR R_L1 R_G1 R_L2 F w,
split_FRZ_in_SEP R R_L2 (@FRZR R_L1 R_G1 w :: R_FR) ->
(exists (H: (fold_right_sepcon R_G1) |-- fold_right_sepcon R_L1 * F), w = @Freezer.FRZRw_constr _ _ _ H) ->
F |-- fold_right_sepcon R_L2 -* fold_right_sepcon R_G2 ->
fold_right_sepcon R |-- fold_right_sepcon (R_G2 ++ R_FR).
Lemma unlocalize_triple: forall R_G2 Espec {cs: compspecs} Delta P Q R R_FR R_L1 R_G1 R_L2 c Post w,
split_FRZ_in_SEP R R_L2 (@FRZR R_L1 R_G1 w :: R_FR) ->
(exists (H: fold_right_sepcon R_G1 |-- fold_right_sepcon R_L1 * (fold_right_sepcon R_L2 -* fold_right_sepcon R_G2)), w = @Freezer.FRZRw_constr _ _ _ H) ->
(@abbreviate _ (fun _ _ => True) R_L1 R_G1 -> @semax cs Espec Delta (PROPx P (LOCALx Q (SEPx (R_G2 ++ R_FR)))) c Post) ->
@semax cs Espec Delta (PROPx P (LOCALx Q (SEPx R))) c Post.
Lemma unlocalize_derives_canon: forall R_G2 Delta P Q R R_FR R_L1 R_G1 R_L2 Post w,
split_FRZ_in_SEP R R_L2 (@FRZR R_L1 R_G1 w :: R_FR) ->
(exists (H: (fold_right_sepcon R_G1) |-- fold_right_sepcon R_L1 * (fold_right_sepcon R_L2 -* fold_right_sepcon R_G2)), w = @Freezer.FRZRw_constr _ _ _ H) ->
(@abbreviate _ (fun _ _ => True) R_L1 R_G1 -> local (tc_environ Delta) && PROPx P (LOCALx Q (SEPx (R_G2 ++ R_FR))) |-- Post) ->
local (tc_environ Delta) && PROPx P (LOCALx Q (SEPx R)) |-- Post.
Lemma unlocalize_derives_unlift: forall R_G2 Pre R R_FR R_L1 R_G1 R_L2 Post w,
construct_fold_right_sepcon Pre R ->
split_FRZ_in_SEP R R_L2 (@FRZR R_L1 R_G1 w :: R_FR) ->
(exists (H: (fold_right_sepcon R_G1) |-- fold_right_sepcon R_L1 * (fold_right_sepcon R_L2 -* fold_right_sepcon R_G2)), w = @Freezer.FRZRw_constr _ _ _ H) ->
(@abbreviate _ (fun _ _ => True) R_L1 R_G1 -> fold_left_sepconx (R_G2 ++ R_FR) |-- Post) ->
Pre |-- Post.