SEM: Deterministic Specialization (canonical developDet) #
Per-vertex form of forward development for deterministic acyclic SEMs. The per-vertex pattern is intrinsically the deterministic specialization — see "Why per-vertex is deterministic-only" below.
developDetVtx M s v : α v is the per-vertex value, defined via
IsDAG.wf.fix (recurses on IsStrictAncestor). The whole-valuation
wrapper developDet M s : Valuation α is the canonical public name
for "develop a deterministic acyclic SEM against a partial valuation."
Returns some at every vertex (every vertex reaches a value via parent
recursion bottoming out at roots).
Mathlib analogue: Mathlib/Probability/Kernel/Deterministic.lean —
canonical type is the general Kernel α β (measure-valued); the
deterministic case is a Dirac specialization with its own constructor
and bridge theorems. Same pattern here: canonical develop M s : PMF (Valuation α) (in Basic.lean) lives alongside this deterministic
specialization, connected by develop_eq_pure_of_deterministic.
Why per-vertex is deterministic-only #
The deterministic per-vertex recursion developDetVtx M s v = mech.toFun (M.mech v) (fun u => developDetVtx M s u.val) works because each vertex
has a unique value computable from parents.
Generalizing to stochastic (return PMF (α v)) requires composing
per-parent marginals into a joint parent assignment to feed to
the mechanism. But marginals don't compose into joints via PMF.bind
without independence, and parents may be correlated through shared
ancestors. Counterexample: A → B, A → C, mechanisms B := A, C := A. Per-vertex marginals: B Bernoulli(0.5), C Bernoulli(0.5). Naive
PMF.bind composition: joint = uniform over (0,0)/(0,1)/(1,0)/(1,1).
Truth: joint = (0,0) w.p. 0.5 OR (1,1) w.p. 0.5. The naive composition
is mathematically wrong.
The canonical stochastic object is the joint develop M s : PMF (Valuation α) (in Basic.lean), which threads PMF.bind through the
partial joint, preserving correlations. There is no clean per-vertex
form for stochastic SEMs without belief-propagation infrastructure.
The computational specialization developDetOn M vs n s (in Basic.lean)
is a separate axis — kernel-reducible iteration over an explicit vertex
list, for proofs over concrete SEMs. Polynomial.eval₂ analogue.
Reduction #
developDetVtx M s v reduces structurally via:
rw [developDetVtx_unfold](or the convenience lemmasdevelopDetVtx_extended/developDetVtx_undet) — opens one layer of theWellFounded.fix_eqrecursion.rfl(orsimpwhens.get vis determined) — closes when ground.
For 5-vertex SEMs, ~5 layers of unfolding suffice. No Fintype reasoning;
no opaque Multiset.toList.
Per-vertex forward development: given a deterministic acyclic
SEM M and a partial valuation s, compute the value at vertex
v by recursing on parents via IsStrictAncestor well-foundedness.
For determined vertices (s.get v = some x), returns x (idempotent
on extension). For undetermined vertices, applies M.mech v's
deterministic function to the recursively-computed parent values.
Total: every vertex in a deterministic acyclic SEM reaches a value
(roots either have explicit values in s or are computed by their
constant mechanisms). The whole-valuation wrapper developDet
therefore returns some everywhere.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Canonical forward development of a deterministic acyclic SEM
against a partial valuation, returning a Valuation α. Wraps
developDetVtx with some at every vertex. Total under
IsDAG + IsDeterministic.
Replaces the old Basic.lean developDet (Fintype-based,
iteration-based, noncomputable, opaque). Same call-site shape
((M.developDet s).hasValue v x); cleanly reducible internals.
Equations
- M.developDet s v = some (M.developDetVtx s v)
Instances For
Step lemma: one layer of WellFounded.fix_eq unfolding. Use with
rw to open developDetVtx M s v in proofs.
When v is already determined in s, development is the value.
When v is undetermined in s, development applies the mechanism
to the recursively-developed parent values.
developDet M s always returns some at every vertex.
developDet is some ∘ developDetVtx.
(M.developDet s).hasValue v x ↔ developDetVtx M s v = x.