Skip to content

feat(NumberTheory/Bernoulli): von Staudt-Clausen theorem#34906

Open
seewoo5 wants to merge 57 commits intoleanprover-community:masterfrom
seewoo5:vsc
Open

feat(NumberTheory/Bernoulli): von Staudt-Clausen theorem#34906
seewoo5 wants to merge 57 commits intoleanprover-community:masterfrom
seewoo5:vsc

Conversation

@seewoo5
Copy link
Copy Markdown
Collaborator

@seewoo5 seewoo5 commented Feb 6, 2026


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.

Open in Gitpod

seewoo5 and others added 14 commits February 5, 2026 15:46
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>
@github-actions github-actions bot added large-import Automatically added label for PRs with a significant increase in transitive imports t-number-theory Number theory (also use t-algebra or t-analysis to specialize) labels Feb 6, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 6, 2026

PR summary 216d48f3de

Import changes exceeding 2%

% File
+25.38% Mathlib.NumberTheory.Bernoulli

Import changes for modified files

Dependency changes

File Base Count Head Count Change
Mathlib.NumberTheory.Bernoulli 1639 2055 +416 (+25.38%)
Import changes for all files
Files Import difference
8 files Mathlib.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 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).

seewoo5 and others added 9 commits February 5, 2026 22:23
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>
@seewoo5 seewoo5 marked this pull request as draft February 6, 2026 17:14
seewoo5 and others added 3 commits February 7, 2026 21:03
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>
@grunweg grunweg added the LLM-generated PRs with substantial input from LLMs - review accordingly label Mar 16, 2026
@seewoo5 seewoo5 marked this pull request as draft March 19, 2026 21:20
@mathlib-bors
Copy link
Copy Markdown
Contributor

mathlib-bors bot commented Mar 19, 2026

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 bors r+ or bors try.

@seewoo5
Copy link
Copy Markdown
Collaborator Author

seewoo5 commented Mar 19, 2026

I made some changes addressing comments but still WIP - I'll re open when I think it is more ready (probably in few days).

seewoo5 and others added 7 commits March 21, 2026 14:14
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>
@seewoo5 seewoo5 marked this pull request as ready for review April 7, 2026 07:44
seewoo5 and others added 2 commits April 7, 2026 00:44
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>
@seewoo5 seewoo5 removed the awaiting-author A reviewer has asked the author a question or requested changes. label Apr 16, 2026
@seewoo5
Copy link
Copy Markdown
Collaborator Author

seewoo5 commented Apr 16, 2026

@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.

@MichaelStollBayreuth
Copy link
Copy Markdown
Contributor

You'll have to merge master to fix the build. (git fetch upstream; git merge upstream/master)

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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 : ι → ℚ) :
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(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. -/
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/-- 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,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.

@MichaelStollBayreuth MichaelStollBayreuth added the awaiting-author A reviewer has asked the author a question or requested changes. label Apr 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-author A reviewer has asked the author a question or requested changes. large-import Automatically added label for PRs with a significant increase in transitive imports LLM-generated PRs with substantial input from LLMs - review accordingly t-number-theory Number theory (also use t-algebra or t-analysis to specialize)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants