Skip to content

feat: String.toNat? lemmas#12828

Merged
TwoFX merged 10 commits intoleanprover:masterfrom
TwoFX:string-tonat-lemmas
Mar 19, 2026
Merged

feat: String.toNat? lemmas#12828
TwoFX merged 10 commits intoleanprover:masterfrom
TwoFX:string-tonat-lemmas

Conversation

@TwoFX
Copy link
Member

@TwoFX TwoFX commented Mar 6, 2026

This PR redefines the String.isNat function to use less state and perform short-circuiting. It then verifies the String.isNat and String.toNat? functions.

Recall that isNat and toNat? allow _ as a digit separator. This is why we get the complicated statement

public theorem isNat_iff {s : String} :
    s.isNat = true ↔
      s ≠ "" ∧
      (∀ c ∈ s.toList, c.isDigit ∨ c = '_') ∧
      ¬ ['_', '_'] <:+: s.toList ∧
      s.toList.head? ≠ some '_' ∧
      s.toList.getLast? ≠ some '_'

For toNat?, we prove the fully general

public theorem toNat?_eq_some_ofDigitChars {s : String} (h : s.isNat = true) :
    s.toNat? = some (Nat.ofDigitChars 10 (s.toList.filter (· != '_')) 0)

as well as the useful (Nat.repr n).toNat? = some n (and the corollary that Nat.repr is injective).

For people implementing formatting routines that involve digit separators, we have

public theorem isNat_of_isDigit {s : String} (hne : s ≠ "")
    (hdigit : ∀ c ∈ s.toList, c.isDigit) : s.isNat = true

public theorem isNat_append_underscore_append {s t : String}
    (hs : s.isNat = true) (ht : t.isNat = true) :
    (s ++ "_" ++ t).isNat = true

public theorem toNat?_append_underscore_append_eq_some {s t : String} {n m : Nat}
    (hs : s.toNat? = some n) (ht : t.toNat? = some m) :
   (s ++ "_" ++ t).toNat? =
      some (10 ^ (t.toList.filter (· != '_')).length * n + m)

The missing bit here is (s.leftpad k '0').toNat? = s.toNat?, which is missing because we don't have String.leftpad (yet). For any reasonable definition of leftpad, this will follow from toNat?_eq_some_ofDigitChars since we prove the necessary ingredients about ofDigitChars.

There are some rough edges around ofDigitChars, and in the future it will be nice to connect this all to mathlib's Nat.digits and Nat.ofDigits, which are similar but different.

@TwoFX TwoFX added WIP This is work in progress, and only a PR for the sake of CI or sharing. No review yet. changelog-library Library labels Mar 6, 2026
@github-actions github-actions bot added the toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN label Mar 6, 2026
@mathlib-lean-pr-testing
Copy link

Mathlib CI status (docs):

  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase fe1ad52f88a2b72913f9cb5f218146cb5a0c584f --onto 333ab1c6f0ce11f33551d6a736054cb72812cad9. You can force Mathlib CI using the force-mathlib-ci label. (2026-03-06 15:23:10)

@leanprover-bot
Copy link
Collaborator

leanprover-bot commented Mar 6, 2026

Reference manual CI status:

  • ❗ Reference manual CI will not be attempted unless your PR branches off the nightly-with-manual branch. Try git rebase fe1ad52f88a2b72913f9cb5f218146cb5a0c584f --onto cda84702e9b31165f1f83c657b532f36f34e0bd0. You can force reference manual CI using the force-manual-ci label. (2026-03-06 15:23:11)
  • ❗ Reference manual CI can not be attempted yet, as the nightly-testing-2026-03-17 tag does not exist there yet. We will retry when you push more commits. If you rebase your branch onto nightly-with-manual, reference manual CI should run now. You can force reference manual CI using the force-manual-ci label. (2026-03-18 16:45:58)

@TwoFX TwoFX force-pushed the string-tonat-lemmas branch from 220844b to 13727e6 Compare March 17, 2026 18:24
mathlib-nightly-testing bot pushed a commit to leanprover-community/batteries that referenced this pull request Mar 18, 2026
@github-actions github-actions bot added the mathlib4-nightly-available A branch for this PR exists at leanprover-community/mathlib4-nightly-testing:lean-pr-testing-NNNN label Mar 18, 2026
mathlib-nightly-testing bot pushed a commit to leanprover-community/mathlib4-nightly-testing that referenced this pull request Mar 18, 2026
@mathlib-lean-pr-testing mathlib-lean-pr-testing bot added the breaks-mathlib This is not necessarily a blocker for merging: but there needs to be a plan label Mar 18, 2026
@mathlib-lean-pr-testing
Copy link

Mathlib CI status (docs):

@TwoFX TwoFX force-pushed the string-tonat-lemmas branch from 48aebc5 to 69ba74f Compare March 19, 2026 10:50
@TwoFX TwoFX removed the WIP This is work in progress, and only a PR for the sake of CI or sharing. No review yet. label Mar 19, 2026
@TwoFX TwoFX marked this pull request as ready for review March 19, 2026 11:00
@TwoFX TwoFX requested a review from kim-em as a code owner March 19, 2026 11:00
@TwoFX TwoFX enabled auto-merge March 19, 2026 11:00
@TwoFX TwoFX added this pull request to the merge queue Mar 19, 2026
Merged via the queue into leanprover:master with commit e758c0e Mar 19, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaks-mathlib This is not necessarily a blocker for merging: but there needs to be a plan changelog-library Library mathlib4-nightly-available A branch for this PR exists at leanprover-community/mathlib4-nightly-testing:lean-pr-testing-NNNN toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants