mixle.epistemic.coherence module¶
Program plan §2’s three CI-checkable coherence properties, as plain testable functions.
“Checked continuously in CI, not asserted” – these compute a violation magnitude (or boolean) over a
HypothesisPortfolio and a caller-supplied likelihood; nothing here
is wired into an enforcement path, matching the program plan’s own framing. Where a fitting primitive
already exists (mixle.data.exchangeability.exchangeability_check()), it’s a dataset-shaped
permutation test over row order in a flat table, not over a portfolio-update trajectory – the shapes
don’t line up cleanly enough to delegate directly, so exchangeability_violation() below is a
thin, purpose-built adapter using the same permutation-test idea rather than a forced reuse.
- CONSERVATION_ATOL = 1e-09
The contractual ABSOLUTE scale at which
evidence_conservation_violation()calls two posteriors equal.Compared against with
rtol=0.numpy.allclose()was previously givenatol=1e-9while its defaultrtol=1e-5stayed enabled, so the effective threshold was1e-9 + 1e-5 * |w|– up to 250x the advertised absolute scale on ordinary weights. A repeat ingestion that moved a weight by2.5e-7was reported as conserved. Double ingestion is exactly what this check exists to catch, so the stated absolute test is the intended one and the relative term is switched off.
- exchangeability_violation(portfolio0, observations, likelihood, *, n_permutations=20, rng=None)[source]
Max posterior-weight deviation across random reorderings of
observations(program plan §2(i)).Sequentially reweights
portfolio0throughobservationsin its given order, then again throughn_permutationsrandom permutations of the same set; returns the largest per-hypothesis (or open-world) weight deviation seen across permutations. Zero (up to float noise) for a likelihood whose per-step reweighting is a pure multiplicative update with no hidden order dependence – successive Bayesian multiply-and-renormalize steps commute exactly in that case.n_permutationsmust be a positive exact integer: a zero budget returned0.0– read by any caller as “no violation” – having permuted nothing at all. An open-world-only portfolio (no active hypotheses) is a valid input and reports onw_openalone; see_max_abs().observationsmust hold at least two entries, for the same reason on the other axis: a sequence of length 0 or 1 has exactly one ordering, so every “permutation” is the base order, every deviation is identically0.0, and the function reports “no violation” from a test it could not run. Order-dependence is undefined on a sequence that has no alternative order, so this refuses rather than certifies (MXR-080-1758).
- martingale_violation(portfolio, observation_sampler, likelihood, *, n=1000, rng=None)[source]
|E[w_{t+1} | B_t] - w_t|under the model’s own predictive (program plan §2(ii)).observation_sampler(rng) -> observationmust draw from the portfolio’s own predictive distribution (e.g. sample a hypothesis proportional to its current weight, then simulate one observation from it) – the martingale property is a statement about self-consistency under the model’s own predictive measure, not about any particular real data-generating process. Returns the largest per-hypothesis (or open-world) deviation between the prior weight and the weight averaged overnresampled predictive observations.nmust be a positive exact integer:n=0divided the (zero) accumulator by zero, producing aZeroDivisionErroron the open-world term and a NaN weight vector rather than reporting that no measurement was requested. An open-world-only portfolio is a valid input; see_max_abs().
- evidence_conservation_deviation(portfolio0, observation, likelihood)[source]
How far re-ingesting the identical
observationmoves the posterior again, as a magnitude.The same quantity
evidence_conservation_violation()thresholds, reported rather than collapsed to a Boolean – like the other two properties in this module, whose violations are magnitudes. The maximum absolute deviation over the per-hypothesis weights andw_open, both on the same absolute scale (0.0for an open-world-only portfolio’s empty weight vector).
- evidence_conservation_violation(portfolio0, observation, likelihood)[source]
Whether re-ingesting the identical
observationa second time changes the posterior further.Program plan §2(iii): “the same underlying measurement, ingested twice through different routes, updates once.” This function tests the math given an already-deduped input path – it does not itself provide the content-addressed dedup key that real conservation needs (program plan §3.1 is where that lives, a storage-layer concern outside this plan’s scope). Concretely: a plain
likelihoodwith no memory of what it has already seen WILL show a violation here (double application double-counts the evidence, changing the weights again) – that is the honest, correct outcome for an undeduped path, not a bug in this function. Alikelihoodthat is itself dedup-aware (e.g. returns a neutral1.0for anobservationit has already scored, tracked by identity/content-key in a closure the caller owns) shows no violation, demonstrating the property holds once dedup is actually wired in.The comparison is purely absolute, at
CONSERVATION_ATOL; useevidence_conservation_deviation()for the magnitude behind this Boolean.