End RAMIF_PLAIN.
End RAMIF_PLAIN.
Module RAMIF_Q.
Section RAMIF_Q.
Context {A : Type}.
Context {ND : NatDed A}.
Context {SL : SepLog A}.

(* Specifications: *)
Lemma reduce: forall {B} g l (g' l': B -> A),
g |-- l * (allp (l' -* g')) ->
g |-- l * (exp l' -* exp g').
Lemma solve: forall {B} g l g' l' F,
g |-- l * F ->
(forall x: B, F * l' x |-- g' x) ->
g |-- l * (allp (l' -* g')).
Lemma weak_ramif_spec: forall {B} g l (g' l': B -> A),
g |-- l * allp (l' -* g') -> g |-- l * TT.
Lemma plain_spec: forall {B} g l g' l' (x: B),
g |-- l * (allp (l' -* g')) ->
g |-- l *  (l' x -* g' x).
Lemma trans: forall {B BG BL} g m l g' mG' mL' l' (fG: B -> BG) (fL: B -> BL),
(forall b, mL' (fL b) |-- mG' (fG b)) ->
g |-- m * allp (mG' -* g') ->
m |-- l * allp (l' -* mL') ->
g |-- l * allp (Basics.compose l' fL -* Basics.compose g' fG).
Lemma simple_trans: forall {B} g m l (g' m' l': B -> A),
g |-- m * allp (m' -* g') ->
m |-- l * allp (l' -* m') ->
g |-- l * allp (l' -* g').
Lemma trans'':
forall {CS: ClassicalSep A}
{B C: Type} (f: B->C) p l m g1 g2,
g2 = g1 oo f ->
p |-- allp (l -* m oo f) ->
p * allp (m -* g1) |-- allp (l -* g2).
Lemma split: forall {B} g1 g2 l1 l2 (g1' g2' l1' l2': B -> A),
g1 |-- l1 * allp (l1' -* g1') ->
g2 |-- l2 * allp (l2' -* g2') ->
g1 * g2 |-- (l1 * l2) * allp (l1' * l2' -* g1' * g2').
(* Using split to prove frame will lead to a simpler proof. *)
(* But it requires a unitary separation logic.              *)
Lemma frame: forall {B} g l (g' l': B -> A) F,
g |-- l * allp (l' -* g') ->
g * F |-- l * allp (l' -* g' * Basics.const F).
Lemma frame_post: forall {B} g l (g' l' F: B -> A),
g |-- l * allp (l' -* g') ->
g |-- l * allp (l' * F -* g' * F).
Lemma frame_pre: forall {B} g l (g' l': B -> A) F,
g |-- l * allp (l' -* g') ->
g * F |-- (l * F) * allp (l' -* g').
Lemma exp_right: forall {T B} (a: B -> T) g l (g': T -> B -> A) (l': B -> A),
g |-- l * allp (l' -* (fun b => g' (a b) b)) ->
g |-- l * allp (l' -* exp g').