Skip to content

refactor: Extract general-purpose lemmas to ForMathlib for upstream contribution#13

Draft
cameronfreer wants to merge 20 commits intomainfrom
mathlib-contribs
Draft

refactor: Extract general-purpose lemmas to ForMathlib for upstream contribution#13
cameronfreer wants to merge 20 commits intomainfrom
mathlib-contribs

Conversation

@cameronfreer
Copy link
Owner

@cameronfreer cameronfreer commented Jan 24, 2026

Summary

This PR organizes general-purpose lemmas from the exchangeability project into a ForMathlib/ directory structure mirroring mathlib's hierarchy, preparing them for potential upstream contribution.

Changes

New ForMathlib Files (mathlib-only imports)

File Main Lemmas Description
Combinatorics/PermutationExtension.lean exists_perm_extending_injective, exists_perm_extending_strictMono Injective functions extend to permutations
MeasureTheory/MeasurableSpace/ComapInfima.lean iInf_comap_eq_comap_iInf_of_surjective Comap commutes with infima for surjective functions
MeasureTheory/MeasurableSpace/SigmaAlgebraHelpers.lean aestronglyMeasurable_iInf_antitone AEStronglyMeasurable preservation under infima
MeasureTheory/Constructions/Pi/Cylinders.lean isPiSystem_prefixCylinders, measure_eq_of_fin_marginals_eq π-system infrastructure for prefix cylinders
MeasureTheory/Function/ConditionalExpectation/Lipschitz.lean condExp_L1_lipschitz L¹-nonexpansivity of conditional expectation
MeasureTheory/Function/LpHelpers.lean eLpNorm_two_sq_eq_integral_sq, abs_integral_mul_le_L2 Bridges ENNReal Lp norms and Real integrals
MeasureTheory/Function/AEHelpers.lean finset_sum_ae_eq Combine finitely many a.e. equalities
Probability/Kernel/ProductMeasurable.lean measurable_measure_pi Product measure kernel measurability via π-systems
Probability/Independence/Conditional.lean condIndep_of_indicator_condexp_eq Doob's characterization of conditional independence
Probability/ConditionalExpectation/Distributional.lean condexp_indicator_eq_of_pair_law_eq CE equality from distributional equality

Modified Project Files

  • Exchangeability/Contractability.lean: Import ForMathlib, re-export exists_perm_extending_strictMono
  • Exchangeability/Tail/TailSigma.lean: Import ForMathlib, re-export comap/infima lemmas

Recent Refinements

Generalized lemmas for better mathlib compatibility

PermutationExtension.lean:

  • Created exists_perm_extending_injective as the main lemma using Function.Injective k
  • Made exists_perm_extending_strictMono a corollary (proof only used injectivity, not order property)

ComapInfima.lean:

  • Generalized index type from Type* to Sort* in iInf_comap_eq_comap_iInf_of_surjective
  • Consistent with comap_iInf_le which already used Sort*

Removed nolint annotations and unused parameters

SigmaAlgebraHelpers.lean:

  • aestronglyMeasurable_iInf_antitone: Removed unused _h_le : ∀ N, m N ≤ m₀ parameter
  • aestronglyMeasurable_sub_of_tendsto_ae: Removed unused _hm : m ≤ m₀ parameter

LpHelpers.lean:

  • eLpNorm_two_sq_eq_integral_sq: Removed false positive @[nolint unusedArguments]
  • memLp_of_abs_le_const: Removed unused (_ : 1 ≤ p) (_ : p ≠ ∞) parameters (MemLp.of_bound doesn't require them)
  • abs_integral_mul_le_L2: Removed false positive @[nolint unusedArguments]

All files now have zero nolint annotations and use only necessary parameters.

Module Summaries

Phase 3 Additions

Probability/Independence/Conditional.lean

Doob's characterization of conditional independence (reverse direction):

  • condIndep_of_indicator_condexp_eq: If E[1_H | mF ⊔ mG] = E[1_H | mG] a.e. for all H ∈ mH, then mF ⊥⊥ mH | mG

MeasureTheory/Function/AEHelpers.lean

Utility for combining a.e. equalities:

  • finset_sum_ae_eq: Combine finitely many a.e. equalities into sum equality

Probability/ConditionalExpectation/Distributional.lean

Bridge from distributional equality to conditional expectation equality:

  • condexp_indicator_eq_of_pair_law_eq: If (Y,Z) and (Y',Z) have same law, then E[1_{Y∈B}|σ(Z)] = E[1_{Y'∈B}|σ(Z)] a.e.

Earlier Phases

MeasureTheory/Function/LpHelpers.lean

Bridges ENNReal-valued Lp norms and Real-valued integrals:

  • eLpNorm_two_sq_eq_integral_sq: L² norm² = integral of square
  • abs_integral_mul_le_L2: Cauchy-Schwarz for L² functions
  • setIntegral_le_eLpNorm_mul_measure: |∫_A g| ≤ ‖g‖₂·√(μ A)

MeasureTheory/MeasurableSpace/SigmaAlgebraHelpers.lean

Support for AEStronglyMeasurable with respect to infima:

  • aestronglyMeasurable_iInf_antitone: preservation under antitone infima

Probability/Kernel/ProductMeasurable.lean

Measurability of product measure kernels:

  • measurable_measure_pi: ω ↦ ∏ᵢ ν(ω) is measurable

Design Decisions

  1. Mathlib-only imports: All ForMathlib files import only from mathlib, no Exchangeability.* dependencies
  2. Re-exports for backward compatibility: Original declarations re-exported so blueprint references and downstream code continue to work
  3. Standard axioms only: All lemmas verified to use only propext, Classical.choice, Quot.sound
  4. Style compliance: All lines < 100 chars, comprehensive module docstrings
  5. Golfed proofs: Proofs simplified using existing mathlib lemmas:
    • isPiSystem_pi, generateFrom_pi (ProductMeasurable)
    • condExp_mul_of_stronglyMeasurable_right (Lipschitz)
    • Equiv.ofInjective (PermutationExtension)
    • inter_indicator_one (Conditional)
    • indicator_comp_right, setIntegral_indicator (Distributional)
    • Lighter imports where possible (AEHelpers uses MeasureSpace instead of ConditionalExpectation.Basic)

Axiom Verification

$ #print axioms Combinatorics.exists_perm_extending_injective
[propext, Classical.choice, Quot.sound]

$ #print axioms ProbabilityTheory.condIndep_of_indicator_condexp_eq
[propext, Classical.choice, Quot.sound]

$ #print axioms MeasureTheory.finset_sum_ae_eq
[propext, Classical.choice, Quot.sound]

$ #print axioms ProbabilityTheory.condexp_indicator_eq_of_pair_law_eq
[propext, Classical.choice, Quot.sound]

PR Sequencing (for future mathlib PRs)

Level 0 (independent - can be submitted in parallel):
  PR1: PermutationExtension - pure combinatorics
  PR2: ComapInfima - σ-algebra infrastructure
  PR3: TrimInstances - already essentially in mathlib

Level 1 (after Level 0):
  PR4: Cylinders - π-system infrastructure
  PR5: Lipschitz - conditional expectation helpers
  PR6: LpHelpers - Lp norm/integral bridges
  PR7: SigmaAlgebraHelpers - AEStronglyMeasurable for infima
  PR8: AEHelpers - finset_sum_ae_eq utility

Level 2 (after Level 1):
  PR9: ProductMeasurable - uses π-system infrastructure
  PR10: Independence/Conditional - Doob's characterization
  PR11: ConditionalExpectation/Distributional - CE equality from dist equality

Test plan

  • lake build passes
  • All ForMathlib files have mathlib-only imports
  • Axiom verification passes for all main lemmas
  • Line lengths < 100 chars
  • Blueprint references still valid (declarations re-exported)
  • Zero nolint annotations remaining

References

  • Kallenberg (2005), Probabilistic Symmetries and Invariance Principles, Theorem 1.1
  • Williams (1991), Probability with Martingales

Extract reusable infrastructure from the exchangeability project into
ForMathlib/ subdirectories mirroring mathlib's hierarchy:

- ForMathlib/Combinatorics/PermutationExtension.lean
  exists_perm_extending_strictMono for subsequence ↔ permutation

- ForMathlib/MeasureTheory/MeasurableSpace/ComapInfima.lean
  iInf_comap_eq_comap_iInf_of_surjective for tail σ-algebra equality

- ForMathlib/MeasureTheory/Constructions/Pi/Cylinders.lean
  π-system infrastructure and measure_eq_of_fin_marginals_eq

- ForMathlib/MeasureTheory/Function/ConditionalExpectation/Lipschitz.lean
  condExp_L1_lipschitz and related operator properties

Update source files to re-export from ForMathlib for backward compat.
Add ForMathlib/README.md with PR tracking and sequencing strategy.
- PermutationExtension: Condense succ case induction from 10 lines to 3
- ComapInfima: Use existing mathlib lemma hf.preimage_injective
- ComapInfima: Inline comap_iInf_le proof
- Cylinders: Inline isPiSystem_prefixCylinders And.intro
- Lipschitz: Use Integrable.of_bound for integrable_of_bounded
Replace filter_upwards block with h_linear.mono + congrArg
Mark all 5 ForMathlib files as extracted with axiom verification.
Simplify directory structure to match actual files.
Batch 1 of ForMathlib extraction Phase 2:

- ComapInfima: Remove custom preimage_injective_of_surjective, use
  Function.Surjective.preimage_injective directly; inline hge proof
  using comap_iInf_le; simplify witness equality proof

- Lipschitz: Use Integrable.mul_bdd directly in integrable_of_bounded_mul;
  simplify condExp_mul_pullout using single trans chain

- Cylinders: Replace custom takePrefix with mathlib's Fin.take;
  import Mathlib.Data.Fin.Tuple.Take

- PermutationExtension: Use Fin.castLEquiv for domain equivalence;
  import Mathlib.Logic.Equiv.Fin.Basic; simplify proof structure

Net reduction: -82 lines across 5 files
Batch 2 of ForMathlib extraction Phase 2:

ForMathlib/MeasureTheory/Function/LpHelpers.lean:
- eLpNorm_two_sq_eq_integral_sq: L² norm² = integral of square
- eLpNorm_lt_of_integral_sq_lt: integral bound → norm bound
- memLp_of_abs_le_const: bounded functions in Lp
- memLp_two_of_bounded: bounded functions in L²
- setIntegral_le_eLpNorm_mul_measure: Cauchy-Schwarz on sets
- abs_integral_mul_le_L2: Cauchy-Schwarz for L²
- L2_tendsto_implies_L1_tendsto_of_bounded: L² → L¹ convergence
- integral_pushforward_id/sq_diff/continuous: pushforward integrals

ForMathlib/MeasureTheory/MeasurableSpace/SigmaAlgebraHelpers.lean:
- aestronglyMeasurable_iInf_antitone: preservation under infima
- aestronglyMeasurable_sub_of_tendsto_ae: preservation under limits

These bridge ENNReal-valued Lp norms and Real-valued integrals for
probability theory applications.
Batch 3 of ForMathlib extraction Phase 2:

ForMathlib/Probability/Kernel/ProductMeasurable.lean:
- measurable_prod_ennreal: product of measurable ENNReal functions
- rectangles_isPiSystem: measurable rectangles form π-system
- rectangles_generate_pi_sigma: product σ-algebra = generateFrom rectangles
- measurable_measure_pi: key lemma for ConditionallyIID property

Note: Conditional independence lemmas (CondIndep) not extracted due to
project-specific dependencies on CondExpHelpers. The ProductMeasurable
lemmas are the truly general-purpose content.

Also updates copyright year to 2026 for new ForMathlib files.
Update tracking table and module summaries for Phase 2 extraction:
- LpHelpers.lean: Lp norm/integral bridges
- SigmaAlgebraHelpers.lean: AEStronglyMeasurable for infima
- ProductMeasurable.lean: Product measure kernel measurability
Replace custom rectangles_isPiSystem and rectangles_generate_pi_sigma with
mathlib's isPiSystem_pi and generateFrom_pi from MeasurableSpace.Pi.
Also remove unneeded univ_pi_eq_setOf_forall helper.
…rable_right

Use condExp_mul_of_stronglyMeasurable_right directly instead of
condExp_stronglyMeasurable_mul_of_bound with double commutativity.
This removes the need for SigmaFinite (μ.trim hm) and the TrimInstances import.
Replace manual Classical.choose scaffolding with Equiv.ofInjective
followed by Equiv.subtypeEquivRight to convert between range and
existential predicate representations.
Add explicit natural number argument to make type inference work
correctly for the squared norm case.
…E bridge lemmas

Add three new ForMathlib files with general-purpose lemmas:

1. Probability/Independence/Conditional.lean
   - `condIndep_of_indicator_condexp_eq`: Doob's characterization of conditional
     independence (reverse direction) - projection property implies cond indep

2. MeasureTheory/Function/AEHelpers.lean
   - `finset_sum_ae_eq`: Combine finitely many a.e. equalities into sum equality

3. Probability/ConditionalExpectation/Distributional.lean
   - `condexp_indicator_eq_of_pair_law_eq`: If (Y,Z) and (Y',Z) have same law,
     then E[1_{Y∈B}|σ(Z)] = E[1_{Y'∈B}|σ(Z)] a.e.

All files:
- Import only mathlib (no Exchangeability.* dependencies)
- Use only standard axioms (propext, Classical.choice, Quot.sound)
- Follow mathlib style (<100 char lines)
Conditional.lean (118 lines, -17):
- Use `inter_indicator_one` for indicator product formula
- Cleaner proof structure with consistent naming

Distributional.lean (117 lines, -26):
- Use `hZ.comap_le` instead of manual comap proof
- Streamlined integral calculations
Distributional.lean (107 lines, -10):
- Use indicator_comp_right to rewrite indicator compositions
- Use setIntegral_indicator + setIntegral_const for cleaner integral calculations
- Remove duplicate proof structure

AEHelpers.lean (59 lines, -3):
- Replace heavy ConditionalExpectation.Basic import with MeasureSpace
- Remove unused ENNReal, ProbabilityTheory, Set opens
- SigmaAlgebraHelpers: Remove unused _h_le and _hm parameters
- LpHelpers: Remove false positive nolint annotations, remove unused
  params from memLp_of_abs_le_const
- PermutationExtension: Create `exists_perm_extending_injective` as the
  main lemma using `Function.Injective k`, make `exists_perm_extending_strictMono`
  a corollary (proof only used injectivity, not order property)

- ComapInfima: Generalize index type from `Type*` to `Sort*` in
  `iInf_comap_eq_comap_iInf_of_surjective` and helper lemmas, consistent
  with `comap_iInf_le` which already used `Sort*`
- Change main API from `k : Fin m → ℕ` to cleaner `k : Fin m → Fin n`
- Move to `Equiv.Perm` namespace (mathlib convention)
- Golf main theorem from 10+ lines to 2 lines (pure term mode)
- Remove unused `strictMono_Fin_ge_id` lemma
- Add backward-compatible wrappers in `Combinatorics` namespace
- Simplify docstrings (remove project-specific references)

Line count: 113 → 79 (mathlib PR portion: ~45 lines)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant