Skip to content

feat(Data/Nat/Fib): formalize Lamé's theorem#37584

Open
kennethgoodman wants to merge 10 commits intoleanprover-community:masterfrom
kennethgoodman:lame-theorem
Open

feat(Data/Nat/Fib): formalize Lamé's theorem#37584
kennethgoodman wants to merge 10 commits intoleanprover-community:masterfrom
kennethgoodman:lame-theorem

Conversation

@kennethgoodman
Copy link
Copy Markdown

@kennethgoodman kennethgoodman commented Apr 3, 2026

Summary

Formalize Lamé's theorem (1844), the founding result of computational complexity theory.

Lamé's Theorem: If the Euclidean algorithm on inputs (a, b) with b ≤ a takes n + 1 division steps, then b ≥ fib(n + 1) and a ≥ fib(n + 2).

New definitions

  • Nat.euclidSteps: counts the number of division steps in the Euclidean algorithm on natural number inputs.

New theorems

  • Nat.fib_le_of_euclidSteps: the main Lamé bound — Fibonacci lower bound on inputs given a step count.
  • Nat.euclidSteps_le_of_lt_fib: the contrapositive — step count upper bound given a Fibonacci bound on the smaller input.
  • Nat.add_mod_le: helper lemma that b + a % b ≤ a when b ≤ a and 0 < b.

Proof strategy

Induction on n, tracking both elements of the pair. The key insight is that each Euclidean step replaces (a, b) with (b, a % b), and since a ≥ b + a % b (because a / b ≥ 1), the Fibonacci recurrence fib(n+3) = fib(n+2) + fib(n+1) matches the structure of the algorithm.

References

  • Gabriel Lamé, Note sur la limite du nombre des divisions dans la recherche du plus grand commun diviseur entre deux nombres entiers, Comptes rendus de l'Académie des sciences, 1844.

AI usage disclosure

Per the Mathlib AI guidelines: Claude Code (Claude Opus 4.6) was used to assist with writing the Lean 4 proof code, fixing tactic errors, and drafting this PR description. The mathematical proof (induction on step count, tracking both pair elements through the Fibonacci recurrence) was designed by hand and verified on paper before formalization. I have reviewed and understand every line of the resulting Lean code and can explain all proof steps.


  • builds cleanly (lake build Mathlib.Data.Nat.Fib.Lame)
  • no sorry
  • lines ≤ 100 characters, no trailing whitespace
  • autoImplicit false
  • docstrings on all public declarations

@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 Apr 3, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

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.

@github-actions github-actions bot added the merge-conflict The PR has a merge conflict with master, and needs manual merging. (this label is managed by a bot) label Apr 3, 2026
Lamé's theorem (1844) bounds the number of division steps in
the Euclidean algorithm using the Fibonacci sequence: if the
algorithm takes n+1 steps on (a, b) with b ≤ a, then
b ≥ fib(n+1) and a ≥ fib(n+2).

This is the founding result of computational complexity theory.

- `Nat.euclidSteps`: counts division steps in the Euclidean
  algorithm on natural numbers.

- `Nat.fib_le_of_euclidSteps`: Fibonacci lower bound on inputs
  given a step count.
- `Nat.euclidSteps_le_of_lt_fib`: step count upper bound given
  a Fibonacci bound on the smaller input.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@github-actions github-actions bot removed the merge-conflict The PR has a merge conflict with master, and needs manual merging. (this label is managed by a bot) label Apr 3, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

PR summary 290b6cf8be

Import changes for modified files

No significant changes to the import graph

Import changes for all files
Files Import difference
Mathlib.Data.Nat.Fib.Lame (new file) 721

Declarations diff

+ add_mod_le
+ euclidSteps
+ euclidSteps_fib
+ euclidSteps_le_of_lt_fib
+ euclidSteps_of_lt
+ euclidSteps_of_ne_zero
+ euclidSteps_zero_right
+ fib_le_of_euclidSteps
+ fib_mod_fib_succ

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

- euclidSteps_of_lt: when a < b, one step swaps to (b, a)
- euclidSteps_fib: consecutive Fibonacci numbers achieve the
  Lamé bound exactly (tightness)
- fib_mod_fib_succ: helper for tightness proof

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Copy link
Copy Markdown
Collaborator

@vihdzp vihdzp left a comment

Choose a reason for hiding this comment

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

Could you reference this in 1000.yaml?

Kenneth Goodman and others added 5 commits April 3, 2026 20:36
- Remove import Mathlib.Tactic.PushNeg (deleted on master)
- Replace push_neg with simp/by_contra patterns
- Replace native_decide with explicit proof (banned in mathlib)
- Add gcd_euclidSteps connecting euclidSteps to Nat.gcd recursion

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Review feedback from vihdzp:
- Remove `set_option autoImplicit false` (set globally)
- Use `n + 1` not `1 + n` in euclidSteps definition
- Rename euclidSteps_succ → euclidSteps_of_ne_zero, take b ≠ 0
- Remove euclidSteps_pos (contrapositive of euclidSteps_zero_right)
- Remove gcd_euclidSteps (redundant with the above)
- Rephrase main theorem: n ≠ 0 and n ≤ steps, not n+1 ≤ steps
- Use `1 < n` not `2 ≤ n` for fib_mod_fib_succ
- Use `n ≠ 0` not `0 < n` for euclidSteps_fib
- Remove redundant 0 < b from add_mod_le
- Add entry to docs/1000.yaml

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Lean 4.29 module system requires:
- `module` declaration after copyright header
- `public import` instead of `import`
- `@[expose] public section` to export declarations

Verified locally: lake build + lake exe runLinter both pass.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Move fib_mod_fib_succ to Mathlib.Data.Nat.Fib.Basic where it
  belongs as a general Fibonacci fact
- Remove redundant 0 < b hypothesis from add_mod_le (when b = 0,
  a % 0 = a in Lean, so b + a % b = a trivially)
- Add date: 2026 to 1000.yaml entry

Both files pass lake build and lake exe runLinter locally.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@kennethgoodman kennethgoodman requested a review from vihdzp April 4, 2026 01:35
simp [hb]

/-- When `b ≤ a`, we have `b + a % b ≤ a`. -/
theorem add_mod_le {a b : ℕ} (hab : b ≤ a) :
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This should go in an earlier file (you resolved this comment earlier, but it hasn't been addressed)

Copy link
Copy Markdown
Author

@kennethgoodman kennethgoodman Apr 4, 2026

Choose a reason for hiding this comment

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

moved to Mathlib/Data/Nat/Basic.lean, let me know if you have a better place

- Move `add_mod_le` from Lame.lean to Mathlib/Data/Nat/Basic.lean
- Remove redundant docstrings on `euclidSteps_of_ne_zero`,
  `add_mod_le`, and `fib_mod_fib_succ`
- Remove Kenneth Goodman from Fib/Basic.lean authors (minor
  contribution)
- Fix copyright year: 2025 → 2026
- Use `contradiction` instead of `exact absurd rfl hn₀`

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@kennethgoodman kennethgoodman requested a review from vihdzp April 4, 2026 02:26
Kenneth Goodman and others added 2 commits April 3, 2026 22:32
- Use `contradiction` consistently
- Use `obtain` and `refine` instead of `have`/`constructor`
- Inline intermediate hypotheses
- Remove docstrings that restate type signatures
- Simplify `euclidSteps_fib` base case

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new-contributor This PR was made by a contributor with at most 5 merged PRs. Welcome to the community!

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants