Definition dummy {X Y} (P : X -> Prop) (Q : Y -> Prop) : X -> Y -> Prop :=
fun x y => P x /\ Q y.

(* Specifications: *)
Lemma poram_lift2_strengthen_pre {X Y}
(Pre Pre' Post : state -> state -> Prop)
(P : X -> Y -> Prop)
(m : Poram X)
(m' : Poram Y) :
(forall s s', Pre' s s' -> Pre s s') ->
poram_lift2 Pre Post P m m' ->
poram_lift2 Pre' Post P m m'.
Lemma plift2_conj {X X' Y Y'}
(P : X -> Y -> Prop)
(Q : X' -> Y' -> Prop)
(dx : dist (X * X')) (dy : dist (Y * Y')) :
plift2 (fun p p' => P (fst p) (fst p')) dx dy ->
plift2 (fun p p' => Q (snd p) (snd p')) dx dy ->
plift2 (prod_rel P Q) dx dy.
Lemma plift2_triv {X Y} (dx : dist X) (dy : dist Y)
(P : X -> Y -> Prop) :
(forall x y, P x y) -> plift2 P dx dy.
Lemma poram_split_dummy {X Y}
(Pre Pre' Post Post' : state -> Prop)
(m : Poram X) (m' : Poram Y) :
poram_lift Pre Post triv m ->
poram_lift Pre' Post' triv m' ->
poram_lift2 (dummy Pre Pre') (dummy Post Post') triv2 m m'.
Lemma plift2_and {X Y} {P Q : X -> Y -> Prop}
(m : dist X) (m' : dist Y) :
plift2 P m m' ->
plift2 Q m m' ->
plift2 (fun x y => P x y /\ Q x y) m m'.
Lemma plift_to_plift2_l {X Y} (P : X -> Prop) (m : dist X) (m' : dist Y) :
plift P m ->
plift2 (fun x _ => P x) m m'.
Lemma plift_to_plift2_r {X Y} (Q : Y -> Prop) (m : dist X) (m' : dist Y) :
plift Q m' ->
plift2 (fun _ y => Q y) m m'.
Lemma plift2_split_eq {X Y Z} (f : X -> Z) (g : Y -> Z) (z : Z)
(m : dist X) (m' : dist Y) :
plift (fun x => f x = z) m ->
plift (fun y => g y = z) m' ->
plift2 (fun x y => f x = g y) m m'.
Lemma poram_lift2_kv_stable {X Y} (m : Poram X) (m' : Poram Y) :
kv_stable m -> kv_stable m' ->
poram_lift2 state_equiv state_equiv triv2 m m'.
Lemma get_state_val_Some_kv_rel k v s :
well_formed s ->
get_state_val k s = Some v ->
kv_rel k v s.
Lemma get_state_val_None_kv_rel k s :
well_formed s ->
get_state_val k s = None ->
kv_rel k 0 s.
Theorem read_write : forall k,
poram_equiv
eq
(mreturn tt)
(v <- read k ;; write k v) .
Theorem write_read : forall k v,
poram_equiv
eq
(write k v;; mreturn v)
(write k v;; read k).
Theorem read_read : forall k,
poram_equiv
eq
(v <- read k;; mreturn v)
(read k;; read k).
Theorem read_commute : forall k1 k2,
poram_equiv
eq
(v1 <- read k1;; v2 <- read k2;; mreturn (v1, v2))
(v2 <- read k2;; v1 <- read k1;; mreturn (v1, v2)).
Theorem read_write_commute : forall k1 k2 v2,
k1 <> k2 ->
poram_equiv
eq
(v1 <- read k1;; write k2 v2;; mreturn v1)
(write k2 v2;; v1 <- read k1;; mreturn v1).
Theorem write_commute : forall k1 k2 v1 v2,
k1 <> k2 ->
poram_equiv
eq
(write k1 v1;; write k2 v2)
(write k2 v2;; write k1 v1).
Theorem write_absorb : forall k v v',
poram_equiv
eq
(write k v;; write k v')
(write k v').