RSA — Latent-aware unbundled operators #
@cite{lassiter-goodman-2017} @cite{kao-etal-2014-hyperbole} @cite{nouwen-2024}
Latent-variable extensions to the unbundled Operators.lean API. RSA models
with latent variables (thresholds, QUDs, lexicons) parameterize their L0/S1
on a latent type L; the L1 marginalizes over L against a latent prior.
The audit in project_rsa_v2_functional.md flagged that 87% of RSAConfig
consumers use Latent ≠ Unit — so latent support must be first-class in any
unbundled v2 API, not an afterthought.
Operators #
L0LassiterGoodman— L&G L0 with prior baked in:P.reweight meaning. The paper-name alias for the standardPMF.reweightoperation specialized to the L&G "prior in literal listener" pattern (eq 70/71 of @cite{lassiter-goodman-2017}).marginalizeKernel— marginalize a latent-parameterized kernel against a latent prior. JustPMF.bindof the latent prior into the kernel slice at each world. This is the operator that turns aLatent → W → PMF Ufamily into a singleW → PMF Ufor use as the speaker inL1.
(Latent-parameterized *Latent wrappers and composeStages were deleted
in 0.230.373 — they added no operator content over partial application
or function composition. See HISTORY at end.)
L&G "two priors" pattern #
For the L&G family (used by @cite{lassiter-goodman-2017},
@cite{nouwen-2024}, intensifier studies), the same prior P enters BOTH:
- L0 via
P.reweight meaning(the literal listener is Bayesian with priorP) - L1 via
PMF.posterior speaker P(the pragmatic listener is Bayesian with priorP)
This double-occurrence is faithful to the paper specification, not
double-counting. With this file's operators, the pattern is straightforward:
construct L0 via L0LassiterGoodman P meaning, build the speaker on top,
then close with PMF.posterior speaker P. The same P shows up in both
function calls — the structure makes it explicit.
Sequential composition #
Sequential between-stage composition (Nouwen 2024 eq 73: Π = stage 1's L1
becomes stage 2's prior) is just function composition: pass the previous
stage's PMF.posterior output as the prior argument to the next stage's
construction. No new operator needed — the existing PMF infrastructure is
sufficient.
The composeStages helper below is a thin alias documenting this idiom.
Relationship to Phase 5 migration #
This file is part of Phase 1.5 of the RSA → mathlib-PMF migration
(project_rsa_pmf_migration.md). It extends the unbundled operator suite
to cover the latent and L&G patterns identified in the consumer audit
(6 canonical patterns, 47 files). Phase 5 study migrations build on these.
A Nouwen2024PMF pilot demonstrating the L&G two-prior + latent + sequential
pattern end-to-end is the natural next step — see commented sketch in
L0LassiterGoodman and marginalizeKernel docstrings for how to use them.
L0 with L&G "prior in literal listener" pattern #
Lassiter-Goodman literal listener (eq 71 of @cite{lassiter-goodman-2017}):
the prior P is part of the literal listener's Bayesian update. For a
Boolean-valued meaning function meaning : U → W → Bool, this returns
P reweighted by the indicator function of the meaning's extension.
Mathematically:
L0_LG(w | u) = P(w) · ⟦u⟧(w) / Σ_{w'} P(w') · ⟦u⟧(w')
This is exactly PMF.reweight P (fun w => indicator (meaning u w)).
Equations
- RSA.L0LassiterGoodman P meaning u h_pos = P.reweight (fun (w : W) => if meaning u w = true then 1 else 0) h_pos ⋯
Instances For
Vacuous-utterance reduction: when meaning u is identically true
(e.g. .silent), the L&G L0 at u reduces to the prior unchanged.
This is the building block for many positivity discharges in consumer code: "the silent utterance has L0 = prior (positive everywhere by assumption), so its contribution to any normalization sum is non-zero."
Inequality decomposition for L&G L0: at a fixed utterance, comparing
two worlds' literal-listener probabilities reduces to comparing their
unnormalised scores P(w) · indicator(meaning u w). The partition function
Z(u) depends on the utterance but not the world, so it cancels.
Direct lift from PMF.reweight_lt_iff_lt.
The ≤ companion of L0LassiterGoodman_apply_lt_iff.
Convenience corollary: when the utterance's meaning is true at both
worlds, the L0 comparison collapses to a prior comparison. The indicator is
1 on both sides, the partition function cancels — only P(w) is left.
The ≤ companion of L0LassiterGoodman_apply_lt_iff_prior_lt.
Marginalization over latents #
The latent-parameterized "wrappers" L0OfMeaningLatent, L0LassiterGoodmanLatent,
S1BeliefLatent were deleted in 0.230.373 (mathlib hygiene audit). They added
no operator content over partial application: e.g.
L0OfMeaningLatent meaning l u h0 hTop was just L0OfMeaning (meaning l) u h0 hTop.
Mathlib doesn't define Function.compLatent. Consumers should write the partial
application directly.
Marginalize a latent-parameterized kernel against a latent prior:
marginalize prior κ a = ∑_l prior(l) · κ(l, a) as a PMF over β.
This is PMF.bind of the latent prior into the kernel slice at each a.
The operator that turns a L → α → PMF β family into a single α → PMF β
suitable for use as the speaker kernel in L1 = PMF.posterior.
For Nouwen2024-style models where the latent is a Threshold marginalized in L1, the typical pattern is:
def speakerLatent : Threshold → Height → PMF EvalUtterance := S1BeliefLatent ...
def marginalizedSpeaker : Height → PMF EvalUtterance :=
marginalizeKernel (PMF.uniformOfFintype Threshold) speakerLatent
def L1 : EvalUtterance → PMF Height :=
fun u => PMF.posterior marginalizedSpeaker heightPrior u (h_marginal_ne_zero u)
Equations
- RSA.marginalizeKernel latentPrior κ a = latentPrior.bind fun (l : L) => κ l a
Instances For
Inequality decomposition for marginalizeKernel (cross-a, same b):
when the kernel slice at a₂ dominates the slice at a₁ pointwise — and is
strict at some latent l₀ with positive prior mass — the marginalized kernel
inherits the strict inequality.
Direct lift of PMF.marginal_lt_marginal after unfolding bind_apply.
Use case: "the marginalized speaker assigns higher probability to utterance u
at world w₂ than at world w₁" reduces to "for every latent threshold, the
per-latent speaker prefers u at w₂, with strict preference at some
threshold."
The ≤ companion of marginalizeKernel_lt_marginalizeKernel.
Sequential between-stage composition (Nouwen eq 73) #
Two successive ρ updates, where stage 2's prior is stage 1's L1 output at a specific stage-1 utterance. This is just function composition — pass the previous-stage L1 as the prior argument to the next stage's L1 construction.
For example, given:
evalL1 : EvalUtterance → PMF Height— stage 1 L1adjL1Builder : PMF Height → AdjUtterance → PMF Height— stage 2 L1 parameterized by its prior
The sequential L1 at the specific stage-1 observation u_eval = .eval_pos is:
seqAdjL1 u₂ := adjL1Builder (evalL1 .eval_pos) u₂
No operator needed. (The composeStages alias was deleted in 0.230.373 —
function-application doesn't need a name.)