Module Type StateMonad.
Parameter state : forall (S X : Type), Type.
Definition State (S X : Type) := S -> state S X.
Parameter ret : forall {S X : Type}, X -> State S X.
Parameter bind : forall {S X Y}, State S X -> (X -> State S Y) -> State S Y.
Parameter get : forall {S}, State S S.
Parameter put : forall {S}, S -> State S unit.
End StateMonad.
Module Type RAM (M : StateMonad).
Parameter K : Type.
Parameter V : Type.
(* Inner implementation of RAM (TODO move or something) *)
Parameter S : Type.
(* Well-formedness over inner implementation (TODO move or remove from interface if possible) *)
Parameter well_formed : S -> Prop.
(* Read and write operations *)
Parameter read : K -> M.State S V.
Parameter write : K -> V -> M.State S unit.
Parameter equiv : forall {X},
M.State S X -> M.State S X -> Prop.

(* IV *)
Axiom read_commute : forall (k1 k2 : K),
equiv
(M.bind (read k1) (fun v1 =>
M.bind (read k2) (fun v2 =>
M.ret (v1, v2))))
(M.bind (read k2) (fun v2 =>
M.bind (read k1) (fun v1 =>
M.ret (v1, v2)))).