Documentation

VCVio.EvalDist.Instances.ReaderT

Evaluation Semantics for ReaderT #

This file provides monad homomorphisms for evaluating ReaderT ρ m computations by fixing the environment parameter.

Unlike StateT, ReaderT evaluation at a fixed environment is a valid monad homomorphism because the environment is read-only and doesn't change during computation.

Main definitions #

Design notes #

We do NOT provide global HasEvalSPMF (ReaderT ρ m) instances because there's no canonical choice of environment. Instead, users explicitly provide the environment when constructing the evaluation homomorphism.

For cryptographic games with random oracles, the typical pattern is:

  1. Generate oracle table with some distribution
  2. Use readerAt to evaluate the protocol at that table
  3. Compose with the table distribution to get overall game probability
def ReaderT.evalAt {ρ : Type u} {m : Type u → Type v} [Monad m] (ρ0 : ρ) :

Evaluate a ReaderT computation at a fixed environment ρ0. This is a monad homomorphism because ReaderT is read-only.

Instances For
    @[simp]
    theorem ReaderT.evalAt_apply {ρ : Type u} {m : Type u → Type v} [Monad m] {α : Type u} (ρ0 : ρ) (mx : ReaderT ρ m α) :
    (fun {α : Type u} (x : ReaderT ρ m α) => (evalAt ρ0).toFun α x) mx = mx ρ0
    @[simp]
    theorem ReaderT.evalAt_pure {ρ : Type u} {m : Type u → Type v} [Monad m] {α : Type u} (ρ0 : ρ) (x : α) :
    (fun {α : Type u} (x : ReaderT ρ m α) => (evalAt ρ0).toFun α x) (pure x) = pure x
    @[simp]
    theorem ReaderT.evalAt_bind {ρ : Type u} {m : Type u → Type v} [Monad m] {α β : Type u} (ρ0 : ρ) (mx : ReaderT ρ m α) (f : αReaderT ρ m β) :
    (fun {α : Type u} (x : ReaderT ρ m α) => (evalAt ρ0).toFun α x) (mx >>= f) = do let x(fun {α : Type u} (x : ReaderT ρ m α) => (evalAt ρ0).toFun α x) mx (fun {α : Type u} (x : ReaderT ρ m α) => (evalAt ρ0).toFun α x) (f x)
    noncomputable def HasEvalSPMF.readerAt {ρ : Type u} {m : Type u → Type v} [Monad m] (ρ0 : ρ) [HasEvalSPMF m] :

    Lift HasEvalSPMF m to a homomorphism ReaderT ρ m →ᵐ SPMF by fixing ρ0.

    This allows evaluating reader computations to sub-probability distributions when the base monad m has such an evaluation.

    Instances For
      noncomputable def HasEvalPMF.readerAt {ρ : Type u} {m : Type u → Type v} [Monad m] (ρ0 : ρ) [HasEvalPMF m] :

      Lift HasEvalPMF m to a homomorphism ReaderT ρ m →ᵐ PMF by fixing ρ0.

      This allows evaluating reader computations to probability distributions when the base monad m has such an evaluation.

      Instances For
        @[simp]
        theorem ReaderT.evalSPMF_pure {ρ : Type u} {m : Type u → Type v} [Monad m] {α : Type u} [HasEvalSPMF m] (ρ0 : ρ) (x : α) :
        (fun {α : Type u} (x : ReaderT ρ m α) => (HasEvalSPMF.readerAt ρ0).toFun α x) (pure x) = (fun {α : Type u} (x : m α) => HasEvalSPMF.toSPMF.toFun α x) (pure x)

        Evaluating pure x at any environment gives the same result as pure x in the base monad.

        @[simp]
        theorem ReaderT.evalSPMF_bind {ρ : Type u} {m : Type u → Type v} [Monad m] {α β : Type u} [HasEvalSPMF m] (ρ0 : ρ) (mx : ReaderT ρ m α) (f : αReaderT ρ m β) :
        (fun {α : Type u} (x : ReaderT ρ m α) => (HasEvalSPMF.readerAt ρ0).toFun α x) (mx >>= f) = do let x(fun {α : Type u} (x : ReaderT ρ m α) => (HasEvalSPMF.readerAt ρ0).toFun α x) mx (fun {α : Type u} (x : ReaderT ρ m α) => (HasEvalSPMF.readerAt ρ0).toFun α x) (f x)

        Evaluating a bind distributes through the monad homomorphism.

        @[simp]
        theorem ReaderT.evalPMF_pure {ρ : Type u} {m : Type u → Type v} [Monad m] {α : Type u} [HasEvalPMF m] (ρ0 : ρ) (x : α) :
        (fun {α : Type u} (x : ReaderT ρ m α) => (HasEvalPMF.readerAt ρ0).toFun α x) (pure x) = (fun {α : Type u} (x : m α) => HasEvalPMF.toPMF.toFun α x) (pure x)
        @[simp]
        theorem ReaderT.evalPMF_bind {ρ : Type u} {m : Type u → Type v} [Monad m] {α β : Type u} [HasEvalPMF m] (ρ0 : ρ) (mx : ReaderT ρ m α) (f : αReaderT ρ m β) :
        (fun {α : Type u} (x : ReaderT ρ m α) => (HasEvalPMF.readerAt ρ0).toFun α x) (mx >>= f) = do let x(fun {α : Type u} (x : ReaderT ρ m α) => (HasEvalPMF.readerAt ρ0).toFun α x) mx (fun {α : Type u} (x : ReaderT ρ m α) => (HasEvalPMF.readerAt ρ0).toFun α x) (f x)

        Optional: Instances with canonical environments #

        If you have a canonical choice of environment (e.g., via [Inhabited ρ]), you can uncomment these to get automatic HasEvalSPMF/PMF instances.

        However, for most cryptographic use cases, it's better to keep the environment explicit and use the readerAt homomorphisms directly.

        noncomputable instance [HasEvalSPMF m] [Inhabited ρ] :
            HasEvalSPMF (ReaderT ρ m) where
          toSPMF := HasEvalSPMF.readerAt (m := m) default
        
        noncomputable instance [HasEvalPMF m] [Inhabited ρ] :
            HasEvalPMF (ReaderT ρ m) where
          toPMF := HasEvalPMF.readerAt (m := m) default