End RAMIF_Q.
Ltac formalize :=
match goal with
| |- @derives ?Pred _ ?g (?l * @allp ?Pred _ ?T ?Func) =>
let g' := fresh "g'" in evar (g': T -> Pred);
let l' := fresh "l'" in evar (l': T -> Pred);
let x := fresh "x" in
let H := fresh "H" in
assert (Func = l' -* g') as H;
[
extensionality x; cbv beta;
match goal with
| |- ?L' -* exp ?G' = _ =>
super_pattern L' x; super_pattern_in_func G' x
| |- ?L' -* ?G' = _ =>
super_pattern L' x; super_pattern G' x
end;
match goal with
| |- ?L' _ -* exp (fun a => ?G' a _) = _ =>
instantiate (1 := L') in (Value of l');
instantiate (1 := exp G') in (Value of g')
| |- ?L' _ -* ?G' _ = _ =>
instantiate (1 := L') in (Value of l');
instantiate (1 := G') in (Value of g')
end;
subst g' l';
reflexivity
| subst g' l'; rewrite H; clear H]
end.
End RAMIF_Q.
Module RAMIF_Q'.
Section RAMIF_Q'.
Context {A : Type}.
Context {ND : NatDed A}.
Context {SL : SepLog A}.
Context {CoSL: CorableSepLog A}.

(* Using split to prove frame will lead to a simpler proof. *)
(* But it requires a unitary separation logic.              *)
Lemma frame: forall {B} g l p g' l' F,
(forall x: B, corable (p x)) ->
g |-- l * allp (p --> (l' -* g')) ->
g * F |-- l * allp (p --> (l' -* g' * Basics.const F)).