feat(NumberTheory/Bernoulli): von Staudt-Clausen theorem#34906
feat(NumberTheory/Bernoulli): von Staudt-Clausen theorem#34906seewoo5 wants to merge 57 commits intoleanprover-community:masterfrom
Conversation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…n section - Remove unused `Units.val_mk` from simp calls - Convert deprecated `induction'` to `induction` in three lemmas - Fix whitespace: `2*m` → `2 * m`, `2*k` → `2 * k`, `)^(` → `) ^ (` - Fix resulting lines exceeding 100 char limit - Add `set_option linter.style.longFile 1800` for file length Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Simplify several proofs by inlining single-use haves, using pow_succ, removing redundant intermediate steps, and leveraging Finset.sum_filter. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…a proofs Remove `have IH := IH` identity bindings, unwrap redundant `have h1 := ...; exact h1` wrapping, inline single-use omega equalities into pow_succ rewrites, and merge consecutive single-use rewrite steps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…o callers Merge trivial single-use helper lemmas directly into their sole call sites to reduce declaration count and improve code locality. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Golf 4 verbose proofs by replacing manual have-chains with field_simp/ring, leveraging core_algebraic_identity, and eliminating redundant cast round-trips. Net savings: ~130 lines. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…callers Remove lemmas with 1-2 line proof bodies that are used only once or not at all, inlining their proofs at call sites to reduce indirection. Dead code removed: pIntegral_add, pIntegral_even_term Inlined: geom_sum_of_root_of_unity, generator_pow_card_sub_one_eq_one, pIntegral_neg_pow_div_two, pIntegral_odd_term, power_sum_eq_faulhaber, coprime_add_of_coprime_den, von_staudt_clausen_pos Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…d_rest Replace ~120-line proof with ~15-line proof using by_cases on divisibility, Finset.add_sum_erase for the positive case, and Finset.filter_congr for the negative case. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PR summary 216d48f3deImport changes exceeding 2%
|
| File | Base Count | Head Count | Change |
|---|---|---|---|
| Mathlib.NumberTheory.Bernoulli | 1639 | 2055 | +416 (+25.38%) |
Import changes for all files
| Files | Import difference |
|---|---|
8 filesMathlib.NumberTheory.ModularForms.DedekindEta Mathlib.NumberTheory.ModularForms.Delta Mathlib.NumberTheory.ModularForms.Derivative Mathlib.NumberTheory.ModularForms.Discriminant Mathlib.NumberTheory.ModularForms.EisensteinSeries.E2.MDifferentiable Mathlib.NumberTheory.ModularForms.EisensteinSeries.E2.Summable Mathlib.NumberTheory.ModularForms.EisensteinSeries.E2.Transform Mathlib.NumberTheory.ModularForms.EisensteinSeries.QExpansion |
6 |
Mathlib.NumberTheory.LSeries.HurwitzZetaValues |
77 |
Mathlib.NumberTheory.ZetaValues |
78 |
Mathlib.NumberTheory.BernoulliPolynomials |
414 |
Mathlib.NumberTheory.Bernoulli |
416 |
Declarations diff
+ bernoulli_add_indicator_den_not_dvd
+ bernoulli_add_indicator_eq_sub
+ choose_two_mul_succ_mul_div_eq
+ exists_int_sum_pow_add_indicator_eq
+ factorization_succ_le_sub_one
+ faulhaber_sum_div_prime_eq
+ pIntegral
+ pIntegral_bernoulli_even_term
+ pIntegral_bernoulli_one_term
+ pIntegral_choose_mul_pow_div
+ pIntegral_faulhaber_sum
+ pIntegral_iff_not_dvd
+ pIntegral_mul
+ pIntegral_ofInt
+ pIntegral_pow_div
+ pIntegral_sub
+ pIntegral_sum
+ prod_one_div_prime_den_coprime
+ sum_den_dvd_prod_den
+ sum_one_div_prime_eq_indicator_div_add
+ sum_pow_add_indicator_eq_zero
+ sum_pow_filter_eq_faulhaber
+ vonStaudtIndicator
+ vonStaudt_clausen
+ vonStaudt_sum_den_not_dvd
You can run this locally as follows
## summary with just the declaration names:
./scripts/pr_summary/declarations_diff.sh <optional_commit>
## more verbose report:
./scripts/pr_summary/declarations_diff.sh long <optional_commit>The doc-module for scripts/pr_summary/declarations_diff.sh contains some details about this script.
No changes to technical debt.
You can run this locally as
./scripts/reporting/technical-debt-metrics.sh pr_summary
- The
relativevalue is the weighted sum of the differences with weight given by the inverse of the current value of the statistic. - The
absolutevalue is therelativevalue divided by the total sum of the inverses of the current values (i.e. the weighted average of the differences).
Add missing documentation for `vonStaudtIndicator` and `pIntegral`. Remove unused arguments from `cast_ne_zero_of_mem_filter`, `generator_pow_ne_one`, `sum_units_pow_eq_zero_of_not_dvd`, `den_pow_div_dvd`, `valuation_bound`, `pIntegral_pow_div_factor`, and `pIntegral_T1`, along with their call sites. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove unused arguments from pIntegral_T2, pIntegral_case_one, even_term_decomposition_identity, power_sum_indicator_divisible_by_p, divisibility_to_rat_eq, sum_other_primes_coprime_p_pos, and cascading unused arguments in pIntegral_second_term, pIntegral_coeff_term, pIntegral_first_term, and pIntegral_even_term_in_sum. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ther Move pIntegral_of_int, pIntegral_mul, pIntegral_mul_int, pIntegral_mul_nat, and pIntegral_sub to directly after pIntegral_sum so all basic pIntegral closure properties are co-located. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove pIntegral_nat_mul and use pIntegral_int_mul directly at call sites, relying on Lean's automatic ℕ → ℤ coercion. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Merge the single-use von_staudt_clausen_zero lemma directly into the k = 0 case of von_staudt_clausen. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove single-use i1_term_forms_eq and replace it with a shorter `convert` + `push_cast` + `field_simp` proof inside pIntegral_i1_term_in_sum. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Inline ~20 single-use helper lemmas into their callers, reducing the file from ~1053 to 884 lines and from ~80 to 60 definitions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Michael Stoll <99838730+MichaelStollBayreuth@users.noreply.github.com>
|
This pull request is now in draft mode. No active bors state needed cleanup. While this PR remains draft, bors will ignore commands on this PR. Mark it ready for review before using commands like |
|
I made some changes addressing comments but still WIP - I'll re open when I think it is more ready (probably in few days). |
Inline 11 single-use private lemmas into their sole callers, reducing the von Staudt-Clausen proof section by 76 lines without changing the proof strategy. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Compress four proofs by using field_simp/ring, inlining intermediates, and chaining rewrites: pIntegral_bernoulli_even_term (-18 lines), faulhaber_sum_div_prime_eq (-6), sum_pow_filter_eq_faulhaber (-5), pIntegral_pow_div (-6). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace pIntegral_sum induction with Valuation.map_sum_le, use Nat.choose_succ_self_right, positivity, omega, and inline intermediate hypotheses in several lemmas. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…i_even_term In the odd prime case, reuse pIntegral_pow_div instead of manually tracking denominator divisibility and coprimality. Factor out pIntegral_choose_mul_pow_div to avoid duplication across branches, and use mul_assoc/mul_div_assoc instead of verbose show-by-ring. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove unnecessary `: ℕ` annotations on expressions already in ℕ (e.g., `(p - 1 : ℕ)` → `(p - 1)`, `(2 * k + 1 - i : ℕ)` → `2 * k + 1 - i`), redundant `: ℤ` on ℤ expressions, `(bernoulli i : ℚ)` where `bernoulli` already returns ℚ, and similar. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Simplify bijection forward map using `mt` + `Nat.not_dvd_of_pos_of_lt`, replace `rw [show ... by ring]` with `mul_div_assoc`, inline single-use `have` statements, use `push_cast; ring` instead of `norm_cast; grind`, and remove unnecessary `conv_lhs`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@MichaelStollBayreuth I think I addressed some parts of your comments - I can do further cleanups, but it might be better to get second round of feedbacks. The proofs also shortened from 500-ish lines to 400-ish lines. |
|
You'll have to merge master to fix the build. ( |
| grind | ||
|
|
||
| /-- A rational number `x` is `p`-integral if `p` does not divide its denominator. -/ | ||
| private def pIntegral (p : ℕ) (x : ℚ) [Fact p.Prime] : Prop := Rat.padicValuation p x ≤ 1 |
There was a problem hiding this comment.
If you make this an abbrev instead of a def, then you can inline the proofs of all the private pIntegral_... lemmas where they are currently used. This saves a lot of boilerplate.
| pIntegral p x ↔ ¬ p ∣ x.den := by | ||
| simp only [pIntegral, Rat.padicValuation_le_one_iff] | ||
|
|
||
| private lemma sum_den_dvd_prod_den {ι : Type*} (s : Finset ι) (f : ι → ℚ) : |
There was a problem hiding this comment.
| private lemma sum_den_dvd_prod_den {ι : Type*} (s : Finset ι) (f : ι → ℚ) : | |
| private lemma den_sum_dvd_prod_den {ι : Type*} (s : Finset ι) (f : ι → ℚ) : |
(it's really Rat.den (∑ i ∈ s, f i) ...)
|
|
||
| /-- If the `p`-adic valuation of `M` is at most `N`, then `p^N / M` is `p`-integral. -/ | ||
| private lemma pIntegral_pow_div (p M N : ℕ) [Fact p.Prime] (hM : M ≠ 0) | ||
| (hv : M.factorization p ≤ N) : pIntegral p ((p : ℚ)^N / M) := by |
There was a problem hiding this comment.
| (hv : M.factorization p ≤ N) : pIntegral p ((p : ℚ)^N / M) := by | |
| (hv : M.factorization p ≤ N) : pIntegral p ((p : ℚ) ^ N / M) := by |
|
|
||
| namespace bernoulli | ||
|
|
||
| /-- Indicator function that is `1` if `(p - 1) ∣ k` and `0` otherwise. -/ |
There was a problem hiding this comment.
| /-- Indicator function that is `1` if `(p - 1) ∣ k` and `0` otherwise. -/ | |
| /- Indicator function that is `1` if `(p - 1) ∣ k` and `0` otherwise. -/ |
Docstrings for private declarations don't make sense (private declarations are not shown in the docs anyway), so this should just be a regular comment. Similarly below.
| /-- Denominators of the "other primes" part of the indicator sum | ||
| stay coprime to a fixed prime `p`. -/ | ||
| private lemma prod_one_div_prime_den_coprime (k p : ℕ) [Fact p.Prime] : | ||
| (∏ q ∈ Finset.range (2 * k + 2) with q.Prime ∧ (q - 1) ∣ 2 * k ∧ q ≠ p, |
There was a problem hiding this comment.
It may make sense to introduce an abbrev for the Finset of all primes q < 2*k+2 such that q-1 ∣ 2*k and use that.
| refine ⟨_, Rat.coe_int_num_of_den_eq_one ?_⟩ | ||
| by_contra h | ||
| obtain ⟨p, hp, hdvd⟩ := ne_one_iff_exists_prime_dvd.mp h | ||
| exact absurd hdvd (by letI : Fact p.Prime := ⟨hp⟩; exact vonStaudt_sum_den_not_dvd k p hk) |
There was a problem hiding this comment.
| exact absurd hdvd (by letI : Fact p.Prime := ⟨hp⟩; exact vonStaudt_sum_den_not_dvd k p hk) | |
| exact absurd hdvd (by let : Fact p.Prime := ⟨hp⟩; exact vonStaudt_sum_den_not_dvd k p hk) |
In Lean 4, the "I" in letI/haveI has nothing to do with instances (terms of class type in the context are always available as instances), rather, "I" means "inline", which is unnecessary in proofs.
Rado's proof ("A New Proof of a Theorem of v. Staudt", JLMS 1935) of von Staudt-Clausen theorem. Initially written by AxiomProver (see commit 97a308e) with further golfs with Claude and Codex.