Definition StateT (S : Type) (M : Type -> Type) (X : Type) : Type :=
S -> M (X * S)%type.
Definition StateT_ret {S} {M} `{Monad M} {X} :
X -> StateT S M X :=
fun x s => mreturn (x, s).
Definition StateT_bind {S} {M} `{Monad M} {X Y} :
StateT S M X ->
(X -> StateT S M Y) ->
StateT S M Y :=
fun mx f s =>
mbind (mx s) (fun '(x, s') => f x s').
Global Instance StateT_Monad {M} {S} `{Monad M} : Monad (StateT S M) := {|
mreturn A := StateT_ret;
mbind X Y := StateT_bind
|}.
Definition get {S M} `{Monad M}: StateT S M S :=
fun s => mreturn(s,s).
Definition put {S M} `{Monad M} (st : S) :
StateT S M unit := fun s => mreturn(tt, st).
Definition liftT {S M} `{Monad M} {A} (m : M A) : StateT S M A :=
fun st =>
a <- m ;; mreturn (a, st).
Definition state_plift {S} {M} `{Monad M} `{PredLift M} {X} (Pre Post : S -> Prop) (P : X -> Prop) :
StateT S M X -> Prop :=
fun mx =>
forall s, Pre s -> plift (fun '(x, s') => P x /\ Post s') (mx s).

Lemma state_plift_put {S} {M} `{PredLift M} {Pre Pre' : S -> Prop} : forall s,
Pre' s -> state_plift Pre Pre' (fun _ => True) (put s).