Zulip Chat Archive

Stream: mathlib4

Topic: Renaming monotonicity of powers lemmas


Yaël Dillies (Dec 18 2023 at 08:27):

This is an announcement that #9095 landed. This is a rather disruptive PR since it renamed 58 lemmas that are among the most used in mathlib. If you have a project depending on mathlib, you should check how the lemmas were renamed to adapt.

Yaël Dillies (Dec 18 2023 at 08:28):

The lemmas in question are all about monotonicity of (a ^ ·) and (· ^ n). The full list of renames by file is

Algebra.GroupPower.Order

  • pow_monopow_right_mono
  • pow_le_powpow_le_pow_right
  • pow_le_pow_of_le_leftpow_le_pow_left
  • pow_lt_pow_of_lt_leftpow_lt_pow_left
  • strictMonoOn_powpow_left_strictMonoOn
  • pow_strictMono_rightpow_right_strictMono
  • pow_lt_powpow_lt_pow_right
  • pow_lt_pow_iffpow_lt_pow_iff_right
  • pow_le_pow_iffpow_le_pow_iff_right
  • self_lt_powlt_self_pow
  • strictAnti_powpow_right_strictAnti
  • pow_lt_pow_iff_of_lt_onepow_lt_pow_iff_right_of_lt_one
  • pow_lt_pow_of_lt_onepow_lt_pow_right_of_lt_one
  • lt_of_pow_lt_powlt_of_pow_lt_pow_left
  • le_of_pow_le_powle_of_pow_le_pow_left
  • pow_lt_pow₀pow_lt_pow_right₀

Algebra.GroupPower.CovariantClass

  • pow_le_pow_of_le_left'pow_le_pow_left'
  • nsmul_le_nsmul_of_le_rightnsmul_le_nsmul_right
  • pow_lt_pow'pow_lt_pow_right'
  • nsmul_lt_nsmulnsmul_lt_nsmul_left
  • pow_strictMono_leftpow_right_strictMono'
  • nsmul_strictMono_rightnsmul_left_strictMono
  • StrictMono.pow_right'StrictMono.pow_const
  • StrictMono.nsmul_leftStrictMono.const_nsmul
  • pow_strictMono_right'pow_left_strictMono
  • nsmul_strictMono_leftnsmul_right_strictMono
  • Monotone.pow_rightMonotone.pow_const
  • Monotone.nsmul_leftMonotone.const_nsmul
  • lt_of_pow_lt_pow'lt_of_pow_lt_pow_left'
  • lt_of_nsmul_lt_nsmullt_of_nsmul_lt_nsmul_right
  • pow_le_pow'pow_le_pow_right'
  • nsmul_le_nsmulnsmul_le_nsmul_left
  • pow_le_pow_of_le_one'pow_le_pow_right_of_le_one'
  • nsmul_le_nsmul_of_nonposnsmul_le_nsmul_left_of_nonpos
  • le_of_pow_le_pow'le_of_pow_le_pow_left'
  • le_of_nsmul_le_nsmul'le_of_nsmul_le_nsmul_right'
  • pow_le_pow_iff'pow_le_pow_iff_right'
  • nsmul_le_nsmul_iffnsmul_le_nsmul_iff_left
  • pow_lt_pow_iff'pow_lt_pow_iff_right'
  • nsmul_lt_nsmul_iffnsmul_lt_nsmul_iff_left

Data.Nat.Pow

  • Nat.pow_lt_pow_of_lt_leftNat.pow_lt_pow_left
  • Nat.pow_le_iff_le_leftNat.pow_le_pow_iff_left
  • Nat.pow_lt_iff_lt_leftNat.pow_lt_pow_iff_left

Yaël Dillies (Dec 18 2023 at 08:28):

On top of that, the following lemmas were removed:

  • self_le_pow was a duplicate of le_self_pow.
  • Nat.pow_lt_pow_of_lt_right is defeq to pow_lt_pow_right.
  • Nat.pow_right_strictMono is defeq to pow_right_strictMono.
  • Nat.pow_le_iff_le_right is defeq to pow_le_pow_iff_right.
  • Nat.pow_lt_iff_lt_right is defeq to pow_lt_pow_iff_right.

Yaël Dillies (Dec 18 2023 at 08:28):

And finally:

  • Some lemma assumptions have been turned from 0 < n or 1 ≤ n to n ≠ 0.
  • A few Nat lemmas have been protected.

Yaël Dillies (Dec 18 2023 at 08:29):

There are other changes that are non-breaking that you can look up in #9095 if you're interested.

Yaël Dillies (Dec 18 2023 at 08:31):

I should remind you that the information of what lemma has been changed in what PR is available in the #changelog. The changelog does not however contain lists of renames.

Johan Commelin (Dec 18 2023 at 08:35):

Thanks for clearly documenting the changes!

Tudor achim (Dec 23 2023 at 01:59):

Just curious, what is the benefit of these changes? The cost of the change is substantial since existing non-mathlib codebases have to be refactored, and muscle memory needs to be re-trained. In this case the lemmas seem to be among the most-used in mathlib which is especially rough.

And if renames are necessary, it seems that an alternative that should be considered is leaving the old lemmas in place as aliases for the new lemmas, possibly with a deprecation attribute or something of the sort. It would be great to introduce those for this change if possible. That way there's a smooth off-ramp from the old lemmas to the new ones.

Jireh Loreaux (Dec 23 2023 at 04:24):

@Alex J. Best I meant to send this earlier, but got caught during the Zulip outage. This PR would be an ideal test candidate for evaluating Leaff's renaming detection. It would be awesome if you could generate the list that Yaël created manually above automatically from Leaff.

Johan Commelin (Dec 23 2023 at 06:44):

@Tudor achim Thanks for posting. You are right, and I think mathlib might need to start thinking about these issues. In general, I think we are quite unaware of all the projects that depend on mathlib. So it's good that you tell us about such examples.
I'm optimistic that in the near future we will have much better tooling around such renames.
Already the latest Lean release seems to have brought us functionality for automatically renaming declarations. If we can run that in batch mode, and those batches can be scripted, then these transitions should become almost painfree.

Yaël Dillies (Dec 23 2023 at 06:47):

In that specific case, my motivation was that the lemma names were all over the place and as a result it was impossible to infer what the name of a lemma is going off the name of a similar lemma, and in fact some of those similar lemmas were missing!

Ruben Van de Velde (Dec 23 2023 at 06:52):

And in particular, mathlib strongly leans on "guessability" of names, so there's also a cost to having inconsistent names. That doesn't mean we can't have a deprecation period, though

Johan Commelin (Dec 23 2023 at 06:54):

Certainly! We shouldn't stop making these changes. But we can try to be a bit less disruptive, in support of other projects depending on mathlib.

Yaël Dillies (Dec 23 2023 at 06:55):

I know there's a new deprecation feature, but it's a bit unergonomic to use within mathlib since it throws warnings on uses of the deprecated lemmas, and mathlib CI errors on warnings.

Mario Carneiro (Dec 23 2023 at 07:04):

well yeah, mathlib should not have warnings in itself, doesn't mean it shouldn't flag deprecations for downstream use

Mario Carneiro (Dec 23 2023 at 07:05):

besides you can always suppress the deprecation warning if you can't be bothered / it's a larger project to update mathlib itself after a deprecation

Mario Carneiro (Dec 23 2023 at 07:06):

certainly if this is pushing you to just remove instead of deprecate then it's the wrong reaction

Yaël Dillies (Dec 23 2023 at 07:07):

How can I suppress the deprecation warning? With a nolint?

Mario Carneiro (Dec 23 2023 at 07:07):

the linter warning should tell you the name of the linter to disable

Mario Carneiro (Dec 23 2023 at 07:08):

if it's the kind of warning that pops up immediately rather than at the end of the build with #lint, you suppress it using set_option linter.foo false in

Mario Carneiro (Dec 23 2023 at 07:09):

all linter warnings (including the unused variable linter) can be suppressed in this way

Yaël Dillies (Dec 23 2023 at 07:09):

Yes but that involves disabling the linter of nn declarations where nn is the number of downstream uses. When I first heard of the deprecation tool, I was hoping this meant I could touch 00 (zero) declarations downstream while still saying "you shouldn't use this lemma, but that one instead".

Johan Commelin (Dec 23 2023 at 07:09):

I think the workflow should be something like:

  1. Rename a lemma, and tag it with @[old_name foo_bar].
  2. The attribute creates an alias, and deprecates the old name in favour of the new name.
  3. mathlib has a boatload of warnings
  4. automatic tooling fixes all those warnings to switch over to the new names
  5. PR
  6. a week later: remove all the @[old_name] attributes.

Mario Carneiro (Dec 23 2023 at 07:09):

what the heck kind of deprecation is that @Yaël Dillies

Mario Carneiro (Dec 23 2023 at 07:10):

the whole point is to get the downstream uses to use something else

Yaël Dillies (Dec 23 2023 at 07:10):

Listen, the way I do refactors is

  1. Shuffle many lemmas around, possibly leaving duplicates for me to clean up afterwards
  2. Fix the downstream uses

Mario Carneiro (Dec 23 2023 at 07:10):

okay?

Mario Carneiro (Dec 23 2023 at 07:10):

warnings don't break the build

Yaël Dillies (Dec 23 2023 at 07:10):

Each step is a sufficiently hard to review PR on its own. I don't want to mix the steps together.

Mario Carneiro (Dec 23 2023 at 07:11):

at least they shouldn't

Yaël Dillies (Dec 23 2023 at 07:11):

Mario Carneiro said:

warnings don't break the build

Sorry, what??

Mario Carneiro (Dec 23 2023 at 07:11):

they make CI fail but it should still produce oleans and such

Yaël Dillies (Dec 23 2023 at 07:11):

All I'm complaining here is that @[deprecated] doesn't naturally let me split steps 1 and 2 into two PRs.

Mario Carneiro (Dec 23 2023 at 07:12):

Sure it does, step 1 can not deprecate the old declaration and just have both

Yaël Dillies (Dec 23 2023 at 07:13):

I'm not a super big fan of this, but if the PR deprecating them comes around quickly I guess it's alright.

Mario Carneiro (Dec 23 2023 at 07:13):

Johan Commelin said:

  1. a week later: remove all the @[old_name] attributes.

I would really like us to start thinking on a time scale more like 3 months for this kind of thing

Johan Commelin (Dec 23 2023 at 07:14):

also fine with me

Mario Carneiro (Dec 23 2023 at 07:14):

this is the kind of thing that gives mathlib a bad name

Johan Commelin (Dec 23 2023 at 07:14):

week was a meta-syntactic variable in that step (-;

Yaël Dillies (Dec 23 2023 at 07:15):

FWIW, I'm happy with having a long list of @[deprecated] alias for a long time.

Mario Carneiro (Dec 23 2023 at 07:15):

The thing is, deprecation and migration are aspects of library design too, and they actually take work to achieve

Yaël Dillies (Dec 23 2023 at 07:16):

The amount of work I spent in my PR description is probably no less than what it would have taken me to deprecate. Migration I don't know.

Mario Carneiro (Dec 23 2023 at 07:17):

Right now our best tools for migration are tied up in deprecations

Mario Carneiro (Dec 23 2023 at 07:18):

Maybe we want a @[soft_deprecated] which is a info message instead of a warning, this should fix the issue with breaking CI since noisy files also cause CI to fail but lake will run to completion

Newell Jensen (Dec 23 2023 at 07:19):

Mario Carneiro said:

this is the kind of thing that gives mathlib a bad name

blasphemy! ... :grinning_face_with_smiling_eyes:

Yaël Dillies (Dec 23 2023 at 07:19):

Yes, that would be an improvement as I could then fix all of mathlib in one go instead of many

Mario Carneiro (Dec 23 2023 at 07:19):

seems like a hack around our current tools though, I wouldn't want to actually have users dealing with that

Mario Carneiro (Dec 23 2023 at 07:19):

deprecations are morally warnings

Yaël Dillies (Dec 23 2023 at 07:21):

No but I mean I could @[soft_deprecated] all the lemmas I want, build mathlib, remove all downstream uses, replace all the @[soft_deprecated] with @[deprecated].

Mario Carneiro (Dec 23 2023 at 07:21):

right, I was imagining exactly that workflow

Mario Carneiro (Dec 23 2023 at 07:22):

unfortunately it doesn't help consumers that are also big projects

Newell Jensen (Dec 23 2023 at 07:22):

Does mathlib have some sort of stable release schedule? From what it seems most of the tagged releases are from toolchain updates.

Mario Carneiro (Dec 23 2023 at 07:23):

It has a version compatible with each lean stable release, but it doesn't have stable releases in the "stable" sense

Yaël Dillies (Dec 23 2023 at 07:23):

Mario Carneiro said:

unfortunately it doesn't help consumers that are also big projects

Then maybe the solution is to have a lake flag for warning/info on deprecation?

Mario Carneiro (Dec 23 2023 at 07:23):

I think lake should just not stop on warnings-as-errors

Yaël Dillies (Dec 23 2023 at 07:23):

That's a fair position. I always found that a bit surprising.

Mario Carneiro (Dec 23 2023 at 07:24):

it's a very low effort implementation

Yaël Dillies (Dec 23 2023 at 07:24):

It would also be interesting to have an extra date argument to @[deprecated] so that a bot can watch for them and send a reminder nn months later "Those lemmas have been deprecated for a long time. Should we delete them?" (and also for general information of the source code readers).

Mario Carneiro (Dec 23 2023 at 07:24):

it literally just turns all warning messages into error messages, with all the downstream effects of an error message on the server and lake

Mario Carneiro (Dec 23 2023 at 07:25):

yes the whole thing could be redesigned, someone needs to look into how other languages do it

Yaël Dillies (Dec 23 2023 at 07:25):

Without that bot checking for long-deprecated lemmas, I would be a bit wary of using @[deprecated].

Mario Carneiro (Dec 23 2023 at 07:26):

since := NNN is part of most deprecation mechanisms I know

Mario Carneiro (Dec 23 2023 at 07:26):

or will_be_removed_in := NNN

Yaël Dillies (Dec 23 2023 at 07:26):

Also, do deprecated lemmas show up in search tools like rw?, apply?, exact? and the docs?

Mario Carneiro (Dec 23 2023 at 07:26):

I think so

Mario Carneiro (Dec 23 2023 at 07:27):

every such tool has to implement this kind of logic independently so it's very haphazard what is checked

Yaël Dillies (Dec 23 2023 at 07:27):

Okay, docs#and_assoc' does show up the docs with a @[deprecated and_assoc] tag, but it's not as flashing yellow as I would have wanted it to.

Mario Carneiro (Dec 23 2023 at 07:27):

there are half a dozen isInternal or isBlacklisted functions in lean+mathlib

Mario Carneiro (Dec 23 2023 at 07:28):

that also relates to the fact that there is no generic way to show attributes on a definition like lean 3 #print

Mario Carneiro (Dec 23 2023 at 07:29):

so every such metaprogram has to go and query every attribute it cares about, and since this is extensible in both programs and attributes you can see why this is difficult to arrange

Yaël Dillies (Dec 23 2023 at 07:29):

I should also say I have many other breaking refactors underway and I am willing for them to be the testing ground of any deprecation/migration method we come up with.

Mario Carneiro (Dec 23 2023 at 07:30):

I think we need a holistic proposal for how deprecation is supposed to work, what the attribute looks like, the code action, auto fix etc

Yaël Dillies (Dec 23 2023 at 07:40):

Mario/Johan, would you welcome a PR that turns the PR description of #9095 into a long list of @[deprecated] alias in the relevant files?

Yaël Dillies (Dec 23 2023 at 07:40):

(for the lemmas whose old name hasn't been taken by a new lemma)

Johan Commelin (Dec 23 2023 at 07:44):

I don't want to push you to do that work now. But if you do it, I'm happy to merge that PR

Johan Commelin (Dec 23 2023 at 07:45):

Yaël Dillies said:

(for the lemmas whose old name hasn't been taken by a new lemma)

This is also something that the holistic deprecation proposal should address.

Yaël Dillies (Dec 23 2023 at 07:45):

It should be pretty easy. Let's try.

Yaël Dillies (Dec 23 2023 at 07:45):

I've just deprecated my first ever lemmas in #9219.

Thomas Murrills (Dec 23 2023 at 07:48):

For documentation purposes, it would be nice for the deprecated attribute to be able to store a blurb on why something was deprecated, even if it’s just a link to a PR or issue. (Ideally it would be a little bit more.) :)

Johan Commelin (Dec 23 2023 at 07:49):

The value of deprecated since should ideally be updated just before the PR is merged by bors...

Johan Commelin (Dec 23 2023 at 07:50):

@Thomas Murrills you can already give a string argument, if you want to

Thomas Murrills (Dec 23 2023 at 07:51):

Ah, I’ve just never seen that string argument used, so I assumed it didn’t exist :sweat_smile:

Yaël Dillies (Dec 23 2023 at 07:54):

Johan Commelin said:

The value of deprecated since should ideally be updated just before the PR is merged by bors...

Yes, although I think it's fine if the date is off by a few days. It's not like huge refactor PRs sit around for a long time anyway.

Thomas Murrills (Dec 23 2023 at 08:00):

What would the value of since be, in general? A date, a PR number, a commit…? (All three?)

Yaël Dillies (Dec 23 2023 at 08:01):

#9235

Mario Carneiro (Dec 23 2023 at 08:02):

PR number sounds like the most reliable

Mario Carneiro (Dec 23 2023 at 08:03):

I think we could still make a script to find old deprecations with only PR numbers to go by

Yaël Dillies (Dec 23 2023 at 08:03):

And then we say something like "The deprecation period is 3000 PRs long"?

Thomas Murrills (Dec 23 2023 at 08:22):

If we stored time as well, and if each mathlib commit somehow knew the time at which the commit itself was committed, we wouldn’t need soft_deprecated: we could calculate the amount of time from the deprecation to the current commit you were on, and decide to either log info or warn based on the result.

E.g. log “this declaration will be deprecated in the version of <project> released <x> days after the current version” where x = deprecationTime + gracePeriodDuration – projectCommitTime (where here mathlib is the project). If x ≤ 0, you get a warning instead.

(Maybe there are reasons not to want this behavior, but just putting it out there as an idea.)

Johan Commelin (Dec 23 2023 at 08:41):

@Mario Carneiro Can you tell me whether there is now a way to do batch renames? Can we give Lean or VScode or the LSP a dictionary of names mapping to new names , and it will just update all of mathlib to use those new names?

Eric Wieser (Dec 23 2023 at 09:09):

Mario Carneiro said:

Maybe we want a @[soft_deprecated] which is a info message instead of a warning

Python has PendingDeprecationWarning for this

Eric Rodriguez (Dec 23 2023 at 09:15):

I guess the way to deprecate lemmas that have a name that is then used elsewhere is to have a special deprecation attribute that only comes up if there's an error applying the lemma (e.g. if there's a type error applying the lemma/a rw doesn't work/etc, it can say 'you may be wanting lemma X, which was recently renamed from this')

Tudor achim (Dec 23 2023 at 17:11):

To me, mathlib feels like the standard library of other languages (and less like functionality-specific libraries that developers build around the core language). Generally speaking, standard libraries rarely if ever undergo breaking API changes outside of major version bumps. This includes both renaming things as well as changing API type signatures in a breaking way. The counterargument to this, of course, is that the mathlib library is significantly more complex than the stdlib of any major language, and it's also early days, so it's natural that there should be more breaking changes otherwise the long-term potential of the library is diminished. I don't think anybody would argue this point.

I would suggest the following principles:

  1. If a function or definition exists in a given mathlib master commit without the deprecated tag, it is guaranteed to be preserved (with the exact module/name/type signature) for at least 6 months. However, it may later be tagged as deprecated.
  2. If a function is deprecated, that means that it cannot be used elsewhere in mathlib, which ensures that it doesn't propagate to the core codebase in ways that other people would pattern match on. So it is the responsibility of someone deprecating functions to replace them in the rest of mathlib.
  3. Over time, as the library matures and design patterns are solidified, I think it's reasonable to increase the 6 month window to something on the order of several years (but likely not beyond).

Following these principles would provide a much more stable platform to build on, and I think they, in spirit, capture the key points of the discussion above.

There was a suggestion in the thread about deprecating more quickly and providing migration tools to keep up -- just note that these can be serious papercuts to impose on a user community (e.g. even python's 2to3 was pretty annoying to use, speaking from personal experience). I think for folks working on mathlib who are very familiar with these things they don't seem like a big deal, but as the popularity of mathlib keeps growing, there will be lots of users for whom it will be a turnoff to have to regularly run housekeeping scripts on their repos.

Tudor achim (Dec 23 2023 at 17:14):

As a test case, in this specific instance, would it be acceptable to open a PR to reintroduce those functions with whatever deprecated tag is most appropriate? I'd be happy to handle that.

Johan Commelin (Dec 23 2023 at 18:04):

@Tudor achim thanks for your thoughts. @Yaël Dillies also offered to add back the functions, together with deprecated tags. I'll be happy to merge that PR.

Yaël Dillies (Dec 23 2023 at 18:33):

I don't think deprecation even makes sense for most of mathlib. Many parts of the library are leaves that are under active development, and each lemma can change many times in a few months. In contrast, the lemmas that I renamed here are part of the algebraic order hierarchy, which is very central.

Yury G. Kudryashov (Dec 23 2023 at 19:29):

I opened a new topic for the discussion about backward compatibility of mathlib: https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/Backward.20compatibility

Eric Rodriguez (Dec 23 2023 at 19:33):

(also, @Joachim Breitner, when will loogle be updated? It doesn't have the new lemma names yet)

Yuyang Zhao (Dec 23 2023 at 20:04):

I recall that I have an ancient mathlib3 PR that uses suffixes for some lemmas with positivity assumptions. I felt this looks better than suffixes like ' and _of_pos_of_nonneg.

Yaël Dillies (Dec 23 2023 at 20:05):

Sadly, many search tools don't support unicode, so I think it would in practice be a downgrade.

Eric Rodriguez (Dec 23 2023 at 20:14):

I disagree and think it would be a strong upgrade. ' is unsearchable anyways, and searching for _of_blah sucks

Yaël Dillies (Dec 23 2023 at 20:17):

The other thing is that _of_pos and _of_nonneg are sometimes good ways to disambiguate similar lemmas.

Yury G. Kudryashov (Dec 23 2023 at 20:17):

E.g., I think that we should have many versions of docs#mul_lt_mul

Yury G. Kudryashov (Dec 23 2023 at 20:18):

And of_le_of_lt/of_lt_of_le/..., possibly with extra of_pos/of_nonneg seem like a good way to disambiguate.

Yuyang Zhao (Dec 23 2023 at 20:21):

I came up with this idea inspired by the suffix (also a unicode).

Yuyang Zhao (Dec 23 2023 at 20:35):

Another motivation is that lemmas like docs#mul_lt_mul_of_nonneg_of_pos and docs#mul_lt_mul_of_le_of_lt' have inconsistent names. Using the suffix p allows them to have consistent names with no more than one ', and can clearly distinguish docs#mul_lt_mul_of_le_of_lt which does not require positivity assumptions.

Yuyang Zhao (Dec 23 2023 at 20:40):

#782 is the old synchronizing PR, I'll make a new one.

Yaël Dillies (Dec 23 2023 at 20:57):

Please don't! I am halfway through a PR touching those lemmas.

Eric Rodriguez (Dec 23 2023 at 20:59):

Yael, if you are doing this already, can we at least add aliases with names of that form? I think it's very valuable, and aliases are _cheap_

Yuyang Zhao (Dec 23 2023 at 21:06):

I think I kept the original name as an alias in my previous PR. No, but most of them.

Joachim Breitner (Dec 23 2023 at 21:08):

Eric Rodriguez said:

(also, Joachim Breitner, when will loogle be updated? It doesn't have the new lemma names yet)

Manually, once in a while. Thanks for the ping :-)

I should automate it if course eventually.

Yuyang Zhao (Dec 23 2023 at 21:18):

It looks like some inconsistent names and wrong names like docs#mul_lt_mul_of_le_of_le' are not kept. In any case I can wait for the other changes to be done first. I'm in no hurry to change it. I already have several PRs that have been there for more than 6 months.

Yuyang Zhao (Dec 23 2023 at 23:21):

#9249 In fact, nothing in mathlib has been broken.

upd: Wait, I may have misunderstood. But I can wait for other PRs anyway.

Tudor achim (Dec 24 2023 at 00:22):

@Yaël Dillies , just to confirm, are you currently making a PR to mathlib to reintroduce those lemmas as aliases that are marked deprecated? If you guys want to defer this decision until later that's also totally cool, just trying to plan out some things internally.

Yaël Dillies (Dec 24 2023 at 06:43):

Yaël Dillies said:

#9235

Yes, see :wait_one_second:


Last updated: May 02 2025 at 03:31 UTC