Zulip Chat Archive
Stream: mathlib4
Topic: new elaborator: ofNat()
Eric Wieser (Jan 01 2025 at 22:04):
Just a heads up about:
rss-bot said:
refactor: add an ofNat() elaborator (mathlib4#20169)
ofNat(n)
is a shorthand forno_index (OfNat.ofNat n)
.
(click through for the full commit message)
There are still stray OfNat.ofNat
s left in mathlib, but we should try to use ofNat()
in any new work.
Eric Wieser (Jan 01 2025 at 22:05):
If anyone fancies writing a linter to detect these and including them in our tech debt stats, that would be great!
Eric Wieser (Jan 01 2025 at 22:43):
@Violeta Hernández, there are 27 matches for See note [no_index around OfNat.ofNat]
in SetTheory
; next time you put your tidying hat on, could you perhaps look at switching these to use ofNat()
instead?
Violeta Hernández (Jan 02 2025 at 08:53):
Sure! I've been on somewhat of a vacation but I'll keep that in mind
Johan Commelin (Jan 02 2025 at 09:06):
@Eric Wieser Is this the counter you had in mind? Or something more subtle
$ rg "OfNat.ofNat" Mathlib | wc -l
403
Because this one would be trivial to add to the tech debt stats.
Eric Wieser (Jan 02 2025 at 09:40):
I think that might be too aggressive; as a conservative option we could start by counting the library note
Johan Commelin (Jan 02 2025 at 10:34):
So
$ rg "See note.*OfNat.ofNat" Mathlib | wc -l
97
Eric Wieser (Jan 02 2025 at 10:58):
Is that the same as the result for "See note \[no_index around OfNat.ofNat\]"
? Would your regex match See note<100 lines follow>OfNat
, or does rg
operate on a per-line basis?
Johan Commelin (Jan 02 2025 at 11:12):
It is per line
Johan Commelin (Jan 02 2025 at 11:13):
The number is indeed the same if we match on the exact string.
Edward van de Meent (Jan 02 2025 at 11:24):
btw, does that mean we also have to update the library note itself? currently (i.e. on latest mathlib on the playground) the note reads as follows:
library_note "no_index around OfNat.ofNat"
* When writing lemmas about `OfNat.ofNat` that assume `Nat.AtLeastTwo`, the term needs to be wrapped
in `no_index` so as not to confuse `simp`, as `no_index (OfNat.ofNat n)`.
Rather than referencing this library note, use `ofNat(n)` as a shorthand for
`no_index (OfNat.ofNat n)`.
Some discussion is [on Zulip here](https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/.E2.9C.94.20Polynomial.2Ecoeff.20example/near/395438147).
Eric Wieser (Jan 02 2025 at 11:25):
What are you proposing? The purpose of the library note is:
- To explain the existing uses of
no_index (OfNat.ofNat
in the library - To tell you not to write more code in this way, and use
ofNat(
instead
Edward van de Meent (Jan 02 2025 at 11:26):
it seems i can't read :see_no_evil:
Edward van de Meent (Jan 02 2025 at 11:27):
indeed, the library note does explain that the shorthand should be used
Eric Wieser (Jan 02 2025 at 11:33):
Of course, really we want to delete the library note entirely, but we have to clear up the 52 (non-SetTheory in 19 files) + 27 (SetTheory in 7 files) references to it first
Edward van de Meent (Jan 02 2025 at 11:35):
still, a library note as to what the purpose of ofNat()
is and what the distinction is between it and OfNat.ofNat
might be useful?
Eric Wieser (Jan 02 2025 at 11:35):
Isn't that role served by the docstring of ofNat()
?
Edward van de Meent (Jan 02 2025 at 11:38):
:thinking: i think you're right
Eric Wieser (Jan 02 2025 at 11:41):
Feel free to improve the wording there if it is unclear, but I'm pretty sure that's the right place for an explanation to be
Michael Stoll (Jan 02 2025 at 11:53):
The problem with having the info in the docstring of ofNat()
is that one has to know aboutofNat()
to find it. It would perhaps be good to have some info in the docstring of docs#OfNat.ofNat itself, but IIRC it is not (yet?) possible to extend docstrings in a later file. (OfNat.ofNat
is in Init.Prelude
...)
Johan Commelin (Jan 02 2025 at 12:13):
@Eric Wieser #20394 adds the tech debt metric
Anne Baanen (Jan 06 2025 at 16:20):
#20521 replaces all occurrences of no_index (ofNat _)
that grep
could find with the new ofNat()
macro.
Eric Wieser (Jan 20 2025 at 00:28):
A spinoff from this discussion:
Eric Wieser (Jan 20 2025 at 00:29):
I remember saying in review at one point that I was uncomfortable with ofNat(n + 1)
, this provides some justification for that hunch.
Johan Commelin (Jan 20 2025 at 11:28):
Could that become a parse error? So that ofNat(x)
only parses when x
is a variable name?
Eric Wieser (Jan 20 2025 at 11:40):
Yes, certainly; but if we do that we should probably remove docs#Real.Gamma_ofNat_eq_factorial which breaks the rule
Eric Wieser (Jan 20 2025 at 11:41):
I think there are quite a few places where we want to apply a theorem with a literal like 37
on one side and get 36
on the other though, so it would be nice to have a mechanism to do this that doesn't require a simproc
each time
Oliver Nash (Jan 20 2025 at 21:40):
Eric Wieser said:
Yes, certainly; but if we do that we should probably remove docs#Real.Gamma_ofNat_eq_factorial which breaks the rule
Glancing at this now is shouldn't we replace the horrid [(n + 1).AtLeastTwo]
with [NeZero n]
?
Oliver Nash (Jan 20 2025 at 21:40):
I guess we might need to add:
instance (n : ℕ) [NeZero n] : (n + 1).AtLeastTwo := ⟨have := NeZero.ne n; by omega⟩
Eric Wieser (Jan 20 2025 at 22:06):
I think the ofNat
is the bigger concern in that lemma statement
Oliver Nash (Jan 20 2025 at 22:09):
Yes absolutely, I was just noting this in passing.
Eric Wieser (Jan 20 2025 at 22:34):
I would extend my claim to (almost) every occurence of (n + 1).AtLeastTwo
being also guilty of this ofNat gray area!
Last updated: May 02 2025 at 03:31 UTC