Skip to content

feat(Probability/Quantile): the lower quantile function of a real cdf - #42461

Open
Ganton23 wants to merge 5 commits into
leanprover-community:masterfrom
Ganton23:quantile-foundations
Open

feat(Probability/Quantile): the lower quantile function of a real cdf#42461
Ganton23 wants to merge 5 commits into
leanprover-community:masterfrom
Ganton23:quantile-foundations

Conversation

@Ganton23

@Ganton23 Ganton23 commented Aug 4, 2026

Copy link
Copy Markdown

This adds ProbabilityTheory.lowerQuantile, the lower quantile function
(the generalized inverse of a cdf-like monotone function on ℝ), with the
order core, the Galois connection under right-continuity, the plug-in
identity, left-continuity in the level, uniqueness, equivariance under
order isomorphisms, and the specialization to cdf μ where both standing
side conditions become theorems.


This adds the LOWER QUANTILE FUNCTION, that is the generalized inverse of a cdf-like
monotone function on , in a new file Mathlib/Probability/Quantile.lean beside
Mathlib/Probability/CDF.lean.

What it adds

ProbabilityTheory.quantileSet F p = {x | p ≤ F x} and
ProbabilityTheory.lowerQuantile F p = sInf (quantileSet F p), with:

  • the order core: monotonicity in the level, and the two csInf bounds;
  • attainment p ≤ F (lowerQuantile F p) under monotonicity and right continuity;
  • the Galois connection lowerQuantile F p ≤ x ↔ p ≤ F x, and its strict form;
  • the plug-in identity F (lowerQuantile F p) = p under continuity;
  • left continuity of the quantile in the level;
  • uniqueness under strict monotonicity, and existence on an interval via the IVT;
  • equivariance under an OrderIso ℝ ℝ, in both functional and pushforward form;
  • the specialization to cdf μ for a probability measure at 0 < p < 1, where both
    standing side conditions become theorems.

Why

sInf of an empty or unbounded-below set is Lean's junk value 0. A quantile lemma
stated without Set.Nonempty and BddBelow is therefore either false or accidentally
true of the junk value, and a reader cannot tell which. Every general lemma here carries
both by name, and the cdf section discharges both from the limits of the cdf at atBot
and atTop. That discharge is what makes the general statements non-vacuous.

Three lemmas record that the continuity hypotheses are load bearing, stated as
¬ ∀ ... rather than as existentials. An existential says a bad case exists; the negated
universal says the weakened lemma is FALSE, which is what a reader asking "is this
hypothesis decorative" actually wants. The witness is a monotone step function that is
left continuous at its jump: monotone, bounded, well behaved quantile set, and not right
continuous, which alone breaks attainment, the forward half of the adjunction, and the
plug-in identity.

not_galoisConnection_lowerQuantile_cdf is included deliberately as a NEGATIVE result.
The bundled GaloisConnection packaging quantifies over all levels, and a cdf has an
unbounded quantile set at level 0 and an empty one at level 2, so the bundled
conclusion is false for every probability measure. Reaching the cdf case would need the
level indexed by the open unit interval as a subtype. I would rather state that boundary
than let a reader discover it.

What it depends on

Mathlib.Probability.CDF for the cdf and its monotonicity and limits;
Mathlib.Topology.Order.IntermediateValue; Mathlib.Topology.Order.MonotoneContinuity;
Mathlib.Order.ConditionallyCompleteLattice.Indexed. No new axioms: every declaration
reports exactly propext, Classical.choice, Quot.sound.

Prior art, named because a reviewer will find it

Mathlib/Order/SemiconjSup.lean defines IsOrderRightAdjoint f g := ∀ y, IsLUB {x | f x ≤ y} (g y), built by isOrderRightAdjoint_csSup as a supremum over a
SUB-level set. That is the order-dual construction, the UPPER generalized inverse; the
two functions are different and neither definition unfolds to the other. Its file is
about circle homeomorphisms, which is why searching for "quantile" does not find it.
GaloisConnection is used rather than reinvented.

There is no existing quantile in mathlib: zero case-insensitive hits across the tree.
median exists but is the median of a simplex in affine geometry, a different word in a
different subject.

Generality, stated rather than left to review

Everything is at F : ℝ → ℝ. Running mathlib's environment linters locally flagged
[IsProbabilityMeasure μ] as unused in nine cdf-facing declarations. Five (the two
side-condition dischargers and the three negative results) are generalized: they now
hold for the cdf of any measure, since the cdf's limit lemmas hold unconditionally.
Four convenience wrappers (lowerQuantile_cdf_le_iff, lowerQuantile_cdf_mono,
le_cdf_lowerQuantile, continuousWithinAt_lowerQuantile_cdf_Iic) KEEP the instance
under @[nolint unusedArguments], deliberately: for a non-probability measure,
cdf μ is a normalizing construction, so the generalized statements would be
accidentally true of the construction rather than of the object the name suggests,
which is the failure mode the Why section above exists to avoid. If reviewers prefer
the fully general forms, I am happy to drop the instances; the proofs do not use
them. Two declarations (cdf_map_orderIso, lowerQuantile_cdf_map) consume the
instance and keep it.

The ORDER CORE generalizes to a ConditionallyCompleteLinearOrder domain with a
Preorder codomain with proof terms UNCHANGED, and I have checked that rather than
assumed it. Two caveats found while checking, which is why I would rather do it as a
follow-up than fold it in here:

  • apply_lt_of_lt_lowerQuantile needs a LINEAR codomain, since it goes from
    ¬ (p ≤ F x) to F x < p.
  • exists_apply_lt_of_bddBelow is FALSE without NoMinOrder on the domain. Over it
    is proved by exhibiting b - 1; on a domain with a least element, a constant F at
    level p has a quantile set that is everything, is bounded below, and has no point
    with F a < p.

The TOPOLOGICAL layer does not transcribe: tendsto_lowerQuantile_nhdsLT takes the
midpoint (c + q) / 2, which uses the field structure, and a general version needs
DenselyOrdered. Happy to do the generalization in a follow-up, or in this PR if a
reviewer prefers it landed general the first time.

Open, and not claimed

The UPPER quantile and the lemmas relating the two; the probability integral transform;
Measure.map along a general measurable monotone function rather than an order
isomorphism; and a GaloisConnection packaging indexed by the open unit interval that
would reach the cdf case.

AI disclosure

  • Lean definitions and proofs generated with the assistance of AI agents (Utilized Anthropic's Claude, operating through Claude Code). Done over numerous working sessions wherein I, Gabriel Anton, directed, reviewed and authorized each session.
  • Every declaration is kernel-checked; Zero sorry, and everyone of the 48 submitted declarations reports exactly [Propext, Classical.choice, Quot.sound] under transitive #print axioms; clean lake build against current master.
    -Ran aggressive adversarial review process on each agents work with a separate agent; A hostile-reviewer pass, refutation lemmas proving the hypotheses are load bearing, and a certified negative result for the packaging that does not work. The corrections forced by this process are in the file and history.
  • Ran Mathlib's environment linters BEFORE submission; their finding (Unused in nine declarations) was adopted, which produced the generalization-versus-nolint split described in the PR body.
  • Commit messages are terse factual summaries; PR body was drafted by agents and reviewed and edited by me, this disclosure is also written by me, Gabriel Anton.
  • I will apply the LLM-Generated label (by comment) and I will answer review questions myself.

Open in Gitpod

… core

Define `ProbabilityTheory.quantileSet F p = {x | p <= F x}` and
`ProbabilityTheory.lowerQuantile F p = sInf (quantileSet F p)`, the lower
generalized inverse of a cdf-like function on the reals, together with the
order-theoretic lemmas that need no topology.

`sInf` of an empty or unbounded-below set is the junk value `0`, so each lemma
carries exactly the side conditions its proof consumes, which is not always
both of `Set.Nonempty` and `BddBelow`. A later commit discharges both for the
cdf of a probability measure at a level in `(0, 1)`.

Prior art: `Mathlib/Order/SemiconjSup.lean` defines `IsOrderRightAdjoint` as a
supremum over a sub-level set. That is the order dual, the upper generalized
inverse, and neither definition unfolds to the other.
…ug-in identity

Add the adjunction `lowerQuantile F p <= x <-> p <= F x` for `F` monotone and
right continuous at the quantile, its strict form, attainment
`p <= F (lowerQuantile F p)`, and the plug-in identity
`F (lowerQuantile F p) = p` under continuity.

Add the witness `jumpAtZero` and three lemmas refuting the weakened forms of
attainment, the forward half of the adjunction, and the plug-in identity. They
are stated as `not (forall ...)` rather than as existentials, so each records
that the weakened lemma is false rather than that a bad case exists.
…junction

Specialize to the cdf of a measure: the quantile set is nonempty at every level below one
and bounded below at every level above zero, so the adjunction holds at
`0 < p < 1` with no remaining side condition.

Add three lemmas recording that the bundled `GaloisConnection` packaging is not
reachable here. The quantile set of a cdf is unbounded below at level zero and
empty at level two, so the bundled conclusion is false.

Five of these lemmas take a general measure rather than a probability measure.
Their proofs consume only `tendsto_cdf_atBot` and `tendsto_cdf_atTop`, both of
which hold without `IsProbabilityMeasure`.

The three probability-measure-facing lemmas keep the instance under
`@[nolint unusedArguments]`, so that the API a user reaches for still says what
it is about. The docstring at `lowerQuantile_cdf_le_iff` states the choice and
invites the reviewer to ask for the general form instead.
…iance

Add left continuity of the lower quantile in the level, uniqueness under strict
monotonicity, existence on an interval via the intermediate value theorem, and
equivariance under an `OrderIso` of the reals in both functional and
pushforward form.

The cdf specialization of left continuity keeps `IsProbabilityMeasure` under
`@[nolint unusedArguments]`, matching the probability-measure-facing lemmas of
the previous commit. The equivariance lemmas keep it because their proofs do
consume it, through `Measure.isProbabilityMeasure_map`.
@github-actions github-actions Bot added the new-contributor This PR was made by a contributor with at most 5 merged PRs. Welcome to the community! label Aug 4, 2026
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

Welcome new contributor!

Thank you for contributing to Mathlib! If you haven't done so already, please review our contribution guidelines, as well as the style guide and naming conventions. In particular, we kindly remind contributors that we have guidelines regarding the use of AI when making pull requests.

We use a review queue to manage reviews. If your PR does not appear there, it is probably because it is not successfully building (i.e., it doesn't have a green checkmark), has the awaiting-author tag, or another reason described in the Lifecycle of a PR. The review dashboard has a dedicated webpage which shows whether your PR is on the review queue, and (if not), why.

If you haven't already done so, please come to https://leanprover.zulipchat.com/, introduce yourself, and mention your new PR.

Thank you again for joining our community.

@Ganton23

Ganton23 commented Aug 4, 2026

Copy link
Copy Markdown
Author

LLM-generated

@github-actions github-actions Bot added the LLM-generated PRs with substantial input from LLMs - review accordingly label Aug 4, 2026
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

PR summary 1bfd2e2ec4

Import changes for modified files

No significant changes to the import graph

Import changes for all files
Files Import difference
Mathlib.Probability.Quantile (new file) 2391

Declarations diff (regex)

+ and
+ apply_lowerQuantile
+ apply_lt_of_lt_lowerQuantile
+ bddBelow_quantileSet_cdf
+ bddBelow_quantileSet_jumpAtZero_one
+ bddBelow_quantileSet_of_lt
+ cdf_map_orderIso
+ continuousWithinAt_lowerQuantile_Iic
+ continuousWithinAt_lowerQuantile_cdf_Iic
+ exists_apply_lt_of_bddBelow
+ exists_lowerQuantile_eq_of_monotone_of_continuousOn_of_strictMonoOn
+ galoisConnection_lowerQuantile
+ galoisConnection_lowerQuantile_id
+ jumpAtZero
+ jumpAtZero_one
+ jumpAtZero_zero
+ le_apply_lowerQuantile
+ le_cdf_lowerQuantile
+ le_lowerQuantile
+ lowerQuantile
+ lowerQuantile_cdf_le_iff
+ lowerQuantile_cdf_map
+ lowerQuantile_cdf_mono
+ lowerQuantile_comp_symm
+ lowerQuantile_def
+ lowerQuantile_eq
+ lowerQuantile_eq_of_strictMono
+ lowerQuantile_id
+ lowerQuantile_jumpAtZero_one
+ lowerQuantile_le_iff
+ lowerQuantile_le_iff_of_rightContinuous
+ lowerQuantile_le_of_le
+ lowerQuantile_mono
+ lt_lowerQuantile_iff
+ monotone_jumpAtZero
+ nonempty_quantileSet_cdf
+ nonempty_quantileSet_jumpAtZero_one
+ not_forall_apply_lowerQuantile
+ not_forall_bddBelow_quantileSet_cdf
+ not_forall_le_apply_lowerQuantile
+ not_forall_lowerQuantile_le_iff
+ not_forall_nonempty_quantileSet_cdf
+ not_galoisConnection_lowerQuantile_cdf
+ quantileSet
+ quantileSet_comp_symm
+ quantileSet_def
+ quantileSet_id
+ quantileSet_jumpAtZero_one
+ tendsto_lowerQuantile_nhdsLT

You can run this locally as follows
## from your `mathlib4` directory:
git clone https://github.com/leanprover-community/mathlib-ci.git ../mathlib-ci

## summary with just the declaration names:
../mathlib-ci/scripts/pr_summary/declarations_diff.sh <optional_commit>

## more verbose report:
../mathlib-ci/scripts/pr_summary/declarations_diff.sh long <optional_commit>

The doc-module for scripts/pr_summary/declarations_diff.sh in the mathlib-ci repository contains some details about this script.

Declarations diff (Lean)

Lean-aware diff — post-build, computed from the Lean environment (commit 1bfd2e2).

  • +48 new declarations
  • −0 removed declarations
+ProbabilityTheory.apply_lowerQuantile
+ProbabilityTheory.apply_lt_of_lt_lowerQuantile
+ProbabilityTheory.bddBelow_quantileSet_cdf
+ProbabilityTheory.bddBelow_quantileSet_jumpAtZero_one
+ProbabilityTheory.bddBelow_quantileSet_of_lt
+ProbabilityTheory.cdf_map_orderIso
+ProbabilityTheory.continuousWithinAt_lowerQuantile_Iic
+ProbabilityTheory.continuousWithinAt_lowerQuantile_cdf_Iic
+ProbabilityTheory.exists_apply_lt_of_bddBelow
+ProbabilityTheory.exists_lowerQuantile_eq_of_monotone_of_continuousOn_of_strictMonoOn
+ProbabilityTheory.galoisConnection_lowerQuantile
+ProbabilityTheory.galoisConnection_lowerQuantile_id
+ProbabilityTheory.jumpAtZero
+ProbabilityTheory.jumpAtZero_one
+ProbabilityTheory.jumpAtZero_zero
+ProbabilityTheory.le_apply_lowerQuantile
+ProbabilityTheory.le_cdf_lowerQuantile
+ProbabilityTheory.le_lowerQuantile
+ProbabilityTheory.lowerQuantile
+ProbabilityTheory.lowerQuantile_cdf_le_iff
+ProbabilityTheory.lowerQuantile_cdf_map
+ProbabilityTheory.lowerQuantile_cdf_mono
+ProbabilityTheory.lowerQuantile_comp_symm
+ProbabilityTheory.lowerQuantile_def
+ProbabilityTheory.lowerQuantile_eq
+ProbabilityTheory.lowerQuantile_eq_of_strictMono
+ProbabilityTheory.lowerQuantile_id
+ProbabilityTheory.lowerQuantile_jumpAtZero_one
+ProbabilityTheory.lowerQuantile_le_iff
+ProbabilityTheory.lowerQuantile_le_iff_of_rightContinuous
+ProbabilityTheory.lowerQuantile_le_of_le
+ProbabilityTheory.lowerQuantile_mono
+ProbabilityTheory.lt_lowerQuantile_iff
+ProbabilityTheory.monotone_jumpAtZero
+ProbabilityTheory.nonempty_quantileSet_cdf
+ProbabilityTheory.nonempty_quantileSet_jumpAtZero_one
+ProbabilityTheory.not_forall_apply_lowerQuantile
+ProbabilityTheory.not_forall_bddBelow_quantileSet_cdf
+ProbabilityTheory.not_forall_le_apply_lowerQuantile
+ProbabilityTheory.not_forall_lowerQuantile_le_iff
+ProbabilityTheory.not_forall_nonempty_quantileSet_cdf
+ProbabilityTheory.not_galoisConnection_lowerQuantile_cdf
+ProbabilityTheory.quantileSet
+ProbabilityTheory.quantileSet_comp_symm
+ProbabilityTheory.quantileSet_def
+ProbabilityTheory.quantileSet_id
+ProbabilityTheory.quantileSet_jumpAtZero_one
+ProbabilityTheory.tendsto_lowerQuantile_nhdsLT

No changes to strong technical debt.

Increase in weak tech debt: (relative, absolute) = (1.00, 0.00)
Current number Change Type (weak)
5048 1 exposed public sections

Current commit 1bfd2e2ec4
Reference commit 4d6f98930f

This script lives in the mathlib-ci repository. To run it locally, from your mathlib4 directory:

git clone https://github.com/leanprover-community/mathlib-ci.git ../mathlib-ci
../mathlib-ci/scripts/reporting/technical-debt-metrics.sh pr_summary
  • The relative value is the weighted sum of the differences with weight given by the inverse of the current value of the statistic.
  • The absolute value is the relative value divided by the total sum of the inverses of the current values (i.e. the weighted average of the differences).

@github-actions github-actions Bot added the t-measure-probability Measure theory / Probability theory label Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

LLM-generated PRs with substantial input from LLMs - review accordingly new-contributor This PR was made by a contributor with at most 5 merged PRs. Welcome to the community! t-measure-probability Measure theory / Probability theory

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant