Joint Distributions with bind
and pure
#
Constructing deterministic distributions with pure
#
pure a
creates a probability distribution that always returns a
with probability 1.
Interpretation
If a random variable, X : Ω → α
, has PMF pure a
, then it's not random at all!
It's a constant function: X(ω) = a
for all ω ∈ Ω
.
Example#
In our code#
creates a distribution that always returns the specific ciphertext encrypt m k
with probability 1.
Composing random processes with bind
#
bind
chains two random processes together:
- First, sample from one distribution.
- Based on that result, sample from another distribution.
Interpretation
Think of bind p f
as a two-step random process:
- Sample
x
from distributionp
. - Use
x
to choose a new distributionf x
. - Sample from
f x
to get the final result.
Example#
-- Roll a die, then flip that many coins and count heads.
def roll_then_flip : PMF Nat :=
bind die_roll (λ n => flip_n_coins n)
Breaking Down Our Expression#
This means:
- First step: sample a pair
(m, k)
from the joint distributionμMK
- Second step: return
encrypt m k
with probability 1
Since the second step is deterministic (pure
), this simplifies to:
Sample (m, k)
from μMK
and output encrypt m k
.
Why Use bind
and pure
?#
To build complex probability distributions from simple ones:
-- Without bind/pure (conceptually):
μC c = Σ {P(M=m, K=k) : (m, k) is such that c = encrypt m k}
-- With bind/pure:
μC = bind μMK (λ (m, k) => pure (encrypt m k))
The bind
/pure
formulation is cleaner and more compositional.
The General Pattern#
When the second step is deterministic (using pure
), bind
reduces to map
.
So we could also write:
In Probability Terms#
pure a
is the Dirac delta distribution δ_a-
wherebind
is the law of total probability:bind p f
represents the distribution of Y when:- X has distribution p
- Y | X=x has distribution f(x)