Repository navigation
refactor: adopt Tau Ceti's good rate functions and large deviation principle - #360
RemyDegenne wants to merge 3 commits into
Conversation
…inciple Delete `LMLExplore.IsGoodRateFunction` and `LMLExplore.IsLDP` in favour of `TauCeti.Probability.IsGoodRateFunction` and `TauCeti.Probability.HasLDP` at the speed `fun n ↦ (n : ℝ≥0)⁻¹` along `atTop`. Restate the LMLExplore API on top of them: the constructor from closed sets and neighbourhoods and the bounds for every set (now for any filter and speed), the exponential bounds and exponential tightness at the speed `1 / n`, the exponential-bound criteria in the `HasLDP` normal form, the weighted sums of good rate functions, and Cramér's theorems. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0196ftMV379vy48QfzHBVNvo
There was a problem hiding this comment.
🟡 api-design — request_changes claude/claude-opus-5-5
The canonical surface replaces IsGoodRateFunction and IsLDP cleanly with no compatibility layer. One general EReal arithmetic lemma is hidden as private and should be exported from a general home instead.
LMLExplore/Probability/LargeDeviations/Basic.lean:81—private lemma coe_inv_natCast_mul((((n⁻¹ : ℝ≥0) : ℝ) : EReal) * a = a / n) mentions only Mathlib types and has a proof unrelated to large deviations. It is the bridge users need between the oldlog / nform and the newHasLDPnormal form used by the four public renamed criteria, but it is hidden. Fix: Make it public in a general EReal arithmetic file, ideally generalized tor : ℝ≥0((((r⁻¹ : ℝ≥0) : ℝ) : EReal) * a = a / r), and consider@[simp]if it fits the existing simp set.
Reply in this thread to contest a finding; that re-runs only this rubric and posts an answer here. (To fix it, just push a commit — that re-reviews on its own. To contest again after an answer, post a NEW reply rather than editing an old one.)
claude/claude-opus-5-5 · 25s · 173.1k in (162.5k cache read, 10.6k cache write) / 2.3k out tokens · reviewing this diff · rubric
There was a problem hiding this comment.
Fixed in 5c5d0f9. The private coe_inv_natCast_mul is gone. It is replaced by the public EReal.coe_nnreal_inv_mul (r : ℝ≥0) (a : EReal) : (((r⁻¹ : ℝ≥0) : ℝ) : EReal) * a = a / ((r : ℝ) : EReal), generalised to any r : ℝ≥0 as you suggested. It lives in a new general file, LMLExplore/Data/EReal/Inv.lean, which mirrors Mathlib.Data.EReal.Inv. The four criteria in LargeDeviations/Basic.lean now use simp_rw [EReal.coe_nnreal_inv_mul, NNReal.coe_natCast, EReal.coe_natCast].
I left it without @[simp] because its LHS is not in simp normal form. NNReal.coe_inv is already a simp lemma and rewrites ((r⁻¹ : ℝ≥0) : ℝ) to (r : ℝ)⁻¹. I checked this on a scratch file: simp on the statement leaves ⊢ ↑(↑r)⁻¹ * a = a / ↑↑r. So the simpNF linter would flag the tag.
There was a problem hiding this comment.
Re: your reply on api-design — re-reviewed on 5c5d0f9; this clears the finding ✅ — approved on 5c5d0f9.
claude/claude-opus-5-5 · addresses your replies through comment 4569074020.
AI review — changes requestedEach rubric is judged independently by multiple review agents; the PR merges only once every rubric is green — any rubric that is not green (changes requested, blocked, errored, stale, or not yet run) blocks the merge. See the rubrics.
♻️ = approved on an earlier commit, re-run before merge. Reviewing this diff at head |
…l file Replace the private `coe_inv_natCast_mul` of the large-deviations base file by the public `EReal.coe_nnreal_inv_mul` in `LMLExplore/Data/EReal/Inv.lean`, stated for any `r : ℝ≥0`. Co-Authored-By: Claude Code <noreply@github.com>
AI review — changes requestedEach rubric is judged independently by multiple review agents; the PR merges only once every rubric is green — any rubric that is not green (changes requested, blocked, errored, stale, or not yet run) blocks the merge. See the rubrics.
♻️ = approved on an earlier commit, re-run before merge. Reviewing this diff at head |
Generalise EReal.coe_nnreal_inv_mul (r : ℝ≥0) to EReal.coe_inv_mul (x : ℝ), and rewrite with NNReal.coe_inv first at its use sites. Co-Authored-By: Claude Code <noreply@github.com>
There was a problem hiding this comment.
🟡 proof-quality — request_changes claude/claude-opus-5-5
The proofs are short and use no change or show, but the four-lemma simp_rw chain that turns the speed ((n⁻¹ : ℝ≥0) : ℝ) : EReal into a division by n is repeated in four lemmas instead of being one reusable lemma.
LMLExplore/Probability/LargeDeviations/Basic.lean:116— The chainsimp_rw [NNReal.coe_inv, EReal.coe_inv_mul, NNReal.coe_natCast, EReal.coe_natCast]appears inlimsup_inv_mul_log_le_neg_of_le_mul_exp,neg_le_liminf_inv_mul_log_of_mul_exp_le,eventually_le_exp_of_limsup_inv_mul_log_le(at h) andeventually_exp_le_of_neg_le_liminf_inv_mul_log(at h). This is repeated reasoning, and a rename of any of the four lemmas breaks all four proofs. Fix: Add one lemma, e.g.EReal.coe_nnreal_inv_natCast_mul (n : ℕ) (a : EReal) : (((n⁻¹ : ℝ≥0) : ℝ) : EReal) * a = a / n, next toEReal.coe_inv_mulinLMLExplore/Data/EReal/Inv.lean. Then usesimp_rw [EReal.coe_nnreal_inv_natCast_mul](or... at h) at the four sites.
Reply in this thread to contest a finding; that re-runs only this rubric and posts an answer here. (To fix it, just push a commit — that re-reviews on its own. To contest again after an answer, post a NEW reply rather than editing an old one.)
claude/claude-opus-5-5 · 17s · 65.9k in (60.7k cache read, 5.2k cache write) / 1.5k out tokens · reviewing this diff · rubric ·
Tau Ceti now defines good rate functions and the large deviation principle, in
TauCeti/Probability/LargeDeviations/Basic.lean. This PR deletes LMLExplore's two definitions and restates LMLExplore's large-deviations API, including Cramér's theorem, on top of Tau Ceti's.Why the definitions agree
IsGoodRateFunction: both require lower semicontinuity and compact sublevel sets at every finite level. LMLExplore stated the levels asc : ℝ≥0and Tau Ceti states them asα : ℝ≥0∞withα ≠ ∞, so the proofs now begin withlift c to ℝ≥0 using hc.IsLDP P IisHasLDP atTop (fun n : ℕ ↦ (n : ℝ≥0)⁻¹) P I.EReal,((n⁻¹ : ℝ≥0) : EReal) * a = a / nfor everyn, includingn = 0, where both sides are0. The public lemmaEReal.coe_inv_mul(new fileLMLExplore/Data/EReal/Inv.lean) proves((x⁻¹ : ℝ) : EReal) * a = a / xfor everyx : ℝ, includingx = 0; the use sites first rewrite((n⁻¹ : ℝ≥0) : ℝ)withNNReal.coe_inv.IsLDPstated its bounds for every set, through interiors and closures, whileHasLDPstates them only for open and closed sets. Monotonicity of the measure, ofENNReal.logand of multiplication byε i ≥ 0derives the every-set bounds from the open and closed ones. The new theorems below prove this for any filter and any speed.(n : ℝ≥0)⁻¹rather than1 / n, because that is the simp normal form (one_div).Removed or renamed public declarations
LMLExplore.IsGoodRateFunctionTauCeti.Probability.IsGoodRateFunction(upstream)LMLExplore.IsGoodRateFunction.lowerSemicontinuousTauCeti.Probability.IsGoodRateFunction.lowerSemicontinuous(upstream)LMLExplore.IsGoodRateFunction.isCompact_setOf_le cTauCeti.Probability.IsGoodRateFunction.isCompact_sublevel c ENNReal.coe_ne_top(upstream)LMLExplore.IsLDP P ITauCeti.Probability.HasLDP atTop (fun n : ℕ ↦ (n : ℝ≥0)⁻¹) P I(upstream)LMLExplore.IsLDP.lowerSemicontinuousTauCeti.Probability.HasLDP.lowerSemicontinuous(upstream)LMLExplore.IsLDP.neg_iInf_interior_le_liminfTauCeti.Probability.HasLDP.neg_iInf_interior_le_liminf(new theorem here, any filter and speed)LMLExplore.IsLDP.limsup_le_neg_iInf_closureTauCeti.Probability.HasLDP.limsup_le_neg_iInf_closure(new theorem here, any filter and speed)LMLExplore.IsLDP.of_isClosed_of_mem_nhdsTauCeti.Probability.HasLDP.of_isClosed_of_mem_nhds(any filter and speed)LMLExplore.IsLDP.eventually_measure_le_expTauCeti.Probability.HasLDP.eventually_measure_le_exp(speed1 / n)LMLExplore.IsLDP.eventually_exp_le_measureTauCeti.Probability.HasLDP.eventually_exp_le_measure(speed1 / n)LMLExplore.IsLDP.exists_eventually_measure_norm_ge_le_expTauCeti.Probability.HasLDP.exists_eventually_measure_norm_ge_le_exp(speed1 / n)LMLExplore.limsup_log_div_le_neg_of_le_mul_expLMLExplore.limsup_inv_mul_log_le_neg_of_le_mul_expLMLExplore.neg_le_liminf_log_div_of_mul_exp_leLMLExplore.neg_le_liminf_inv_mul_log_of_mul_exp_leLMLExplore.eventually_le_exp_of_limsup_log_div_leLMLExplore.eventually_le_exp_of_limsup_inv_mul_log_leLMLExplore.eventually_exp_le_of_neg_le_liminf_log_divLMLExplore.eventually_exp_le_of_neg_le_liminf_inv_mul_logLMLExplore.isLDP_cramerLMLExplore.hasLDP_cramerLMLExplore.isLDP_cramer_of_iIndepFunLMLExplore.hasLDP_cramer_of_iIndepFunMeasureTheory.Measure.isLDP_cramer_expFamilyMeasureTheory.Measure.hasLDP_cramer_expFamilyThe
HasLDP.*lemmas sit in theTauCeti.Probability.HasLDPnamespace so that dot notation works on aHasLDPhypothesis;hasLDP_crameruses.of_isClosed_of_mem_nhds. LMLExplore already extends Mathlib and LML namespaces in the same way, but this is the first time it extends a Tau Ceti namespace.The four exponential-bound criteria are renamed because their statements now use
HasLDP's normal form((n⁻¹ : ℝ≥0) : EReal) * ENNReal.log (u n)instead ofENNReal.log (u n) / n, so they plug straight intoHasLDPfields. Their hypotheses and proofs are otherwise unchanged. The upper and lower bounds of Cramér's theorem (limsup_log_measure_le_neg_iInf_rateFunction,neg_rateFunction_le_liminf_log_measure) keep their names and are restated in the same form.What remains in LMLExplore
Tau Ceti has no counterpart to any of the following, so all of it stays:
HasLDP.of_isClosed_of_mem_nhdsfrom the closed-set upper bound and the lower bound on the neighbourhoods of points. It is now stated for any filter and speed.1 / n.isGoodRateFunction_sum_mul.hasLDP_cramer,hasLDP_cramer_of_iIndepFunandhasLDP_cramer_expFamily, withisGoodRateFunction_rateFunctionandisGoodRateFunction_expFamilyRate_left, which keep their names.All uses were inside
LMLExplore/Probability/LargeDeviations/. The module docstrings ofLargeDeviations/Basic.leanandLargeDeviations/Cramer.leanare updated: the definitions section now points to Tau Ceti, the main-statements lists use the new names, and the speed is described as1 / n, Tau Ceti's convention, instead of "speedn".Checks
scripts/build.sh --iofailsucceeds on the whole library.#lint in LMLExplore, run on a scratch file importing the two changed modules, reports no errors.grepfinds none of the removed names underLMLExplore/.Fixes #342
Roadmap: none
🤖 Generated with Claude Code
https://claude.ai/code/session_0196ftMV379vy48QfzHBVNvo