(* Lemma blockEntry_in_path_or_stsh: forall memSz s0 bId dataN, *)
  (*     init_invariant s0 memSz -> *)
  (*     forall oldVal strm stsh pbt, *)
  (*       (oldVal, (strm, (stsh, pbt))) := runState (access Wr bId (Some dataN)) s0 -> *)
  (*                         readBlockFromStash stsh bId = dataN \/  *)

  Definition smonad S X := S -> X * S.Definition state_lift {S} {X} (Inv : S -> Prop) (P : X -> Prop) : smonad S X -> Prop :=
    fun f => forall s, Inv s -> P (fst (f s)) /\ Inv (snd (f s)).Definition sm_bind {S X Y} : smonad S X -> (X -> smonad S Y) -> smonad S Y :=
    fun m f s => let (x,s') := m s in f x s'.

(* Specifications: *)
Lemma bind_lift_lemma {S} {X Y} (Inv : S -> Prop) (P : X -> Prop) (Q : Y -> Prop) (sx : smonad S X) (f : X -> smonad S Y) : state_lift Inv P sx -> (forall x, P x -> state_lift Inv Q (f x)) -> state_lift Inv Q (sm_bind sx f).
Lemma bind_lift_lemma {S} {X Y} (Inv : S -> Prop) (P : X -> Prop) (Q : Y -> Prop) (sx : smonad S X) (f : X -> smonad S Y) : state_lift Inv P sx -> (forall x, P x -> state_lift Inv Q (f x)) -> state_lift Inv Q (sm_bind sx f).