Code Representation #
This file defines the representation of stateful probabilistic computations.
We use the direct semantic model: SPComp α = Heap → SDistr (α × Heap).
Main definitions #
SPComp α- Stateful probabilistic computation returningαSPComp.pure- Pure computationSPComp.get- Read from a locationSPComp.set- Write to a locationSPComp.sample- Sample from uniform distributionSPComp.fail- Failed computationSPComp.assert- Assertion (fail if false)
Stateful probabilistic computation. A function from initial heap to a sub-distribution over (result, final heap) pairs.
Equations
Instances For
Monad operations #
Pure computation: return value without changing state
Equations
Instances For
Equations
- One or more equations did not get rendered due to their size.
State operations #
Read from a memory location
Equations
Instances For
Write to a memory location
Equations
- CatCrypt.Core.SPComp.set l v h = CatCrypt.Prob.SDistr.pure ((), h.set l v)
Instances For
Probabilistic operations #
Sample uniformly from a finite nonempty type
Equations
- CatCrypt.Core.SPComp.sample α h = (CatCrypt.Prob.SDistr.uniform α).bind fun (a : α) => CatCrypt.Prob.SDistr.pure (a, h)
Instances For
Failed computation
Equations
Instances For
Assertions #
Assert a decidable proposition; fail if false
Equations
Instances For
Derived operations #
Basic lemmas #
Sample followed by pure with a function simplifies to uniform bind with pure. This is key for coupling proofs where we need the distribution over (result, heap).
Sample followed by pure of the sampled value simplifies to uniform bind. Special case where f is identity.
Associativity and unit laws #
Bind.bind form of pure_bind. When a goal arrives with the typeclass-method
Bind.bind (from Monad SPComp instance projection) rather than the prefix
SPComp.bind, pure_bind's LHS pattern does not unify because the head symbols
differ syntactically. This bridge lemma is a definitional rfl (the Monad
instance defines bind := SPComp.bind) and is safe as @[simp]: confluent
with pure_bind and monad_bind_eq.
HBind operator form (x >>= f) of pure_bind. Mirrors bind_pure_left
for the bind operator. Safe as @[simp]: rfl-true and confluent.
Functorial map #
Functorial map for SPComp
Equations
- CatCrypt.Core.SPComp.map f c = c.bind fun (a : α) => CatCrypt.Core.SPComp.pure (f a)
Instances For
Bijection on Uniform Sample #
Applying a bijection inside a uniform sample doesn't change the distribution.
If e : α ≃ β is a bijection, then sampling a : α uniformly and returning f (e a)
is the same as sampling b : β uniformly and returning f b.
This lifts SDistr.uniform_bind_bij to SPComp.
Applying a bijection inside a uniform sample with arbitrary continuation.
Generalizes sample_bind_pure_equiv to non-pure continuations.
If e : α ≃ β, then sample α >>= (k ∘ e) = sample β >>= k.
Bijection cancellation in context: apply a context-dependent bijection
inside bind c (fun x => sample >>= ...).
This handles the common ROM pattern where a key x determines a bijection
e x : α ≃ β applied to a uniform sample.
Purity: Heap-Independent Computations #
A computation is pure if it doesn't depend on or modify the heap.
Formally, there exists a sub-distribution d over values such that
for every initial heap h, the computation returns (a, h) (unchanged heap)
with probability d(a).
Equations
- c.IsPure = ∃ (d : CatCrypt.Prob.SDistr α), ∀ (h : CatCrypt.Core.Heap), c h = d.bind fun (a : α) => CatCrypt.Prob.SDistr.pure (a, h)
Instances For
Two pure computations commute in bind (Fubini for SPComp).
If c₁ and c₂ are both pure, then:
c₁ >>= fun a => c₂ >>= fun b => k a b
equals
c₂ >>= fun b => c₁ >>= fun a => k a b
This is the key lemma for hybrid game decomposition in PKE security proofs.
One-sided commutativity: an IsPure computation can be commuted past ANY
computation (not just another IsPure one).
This generalizes isPure_bind_comm by dropping the requirement that c₂ be IsPure.
The proof uses SDistr.bind_comm (Fubini) at the distribution level, where
c₁'s extracted distribution commutes with c₂ h for any heap h.
LawfulMonad instance #
SPComp is a lawful monad. The laws follow from pure_bind, bind_pure, bind_assoc.
Monadic fold #
Monadic fold over a list of steps. Useful for key schedules and hybrid arguments.
foldM init [f, g, h] = f init >>= fun a => g a >>= fun b => h b
Each step takes the accumulator and produces a new computation.
Equations
- CatCrypt.Core.SPComp.foldM init [] = CatCrypt.Core.SPComp.pure init
- CatCrypt.Core.SPComp.foldM init (f :: rest) = do let a ← f init CatCrypt.Core.SPComp.foldM a rest
Instances For
SDistr → SPComp Lift #
Lift a pure distribution to a stateful computation (heap-independent).
Equations
- CatCrypt.Core.liftSDistr d h = d.bind fun (a : α) => CatCrypt.Prob.SDistr.pure (a, h)