Zulip Chat Archive
Stream: mathlib4
Topic: Typeclass instance loops
Artie Khovanov (Aug 13 2025 at 14:05):
The predicate IsOrderedRing R is strictly weaker than IsStrictOrderedRing R (e.g. ). However, over a field, the two are equivalent, and the content of IsOrderedRing is the standard definition.
Since mathlib4 allows instance loops, I tried to make this into an instance in #27178, incurring a mild performance hit. However, @Eric Wieser told me that the right spelling of "ordered field" should be [Field F] [LinearOrder F] [IsStrictOrderedRing F] in order to avoid the instance loop and to make it consistent with the spelling when not over a field.
Two questions
(1) Is there anywhere else in the library that we have this pattern? That is, where the mathlib definition uses a stronger class instance than the "standard" textbook definition would suggest due to how the instances line up in a weaker context?
(2) I have a similar problem with the existing IsSemireal class and my proposed IsFormallyReal class. Over a ring, IsFormallyReal is strictly stronger (e.g. ). Over a field, they are equivalent. Again, the content of IsSemireal is the standard definition. By the same logic, I understand the should be [Field F] [IsFormallyReal F], with no instance from IsSemireal to IsFormallyReal over a Field?
Aaron Liu (Aug 13 2025 at 14:08):
I would like to say that we assume compact Hausdorff spaces as [CompactSpace X] [T2Space X] 97 times according to #loogle, but the equivalent spelling [CompactSpace X] [T4Space X] with stronger typeclasses gets zero results.
Aaron Liu (Aug 13 2025 at 14:10):
@loogle CompactSpace ?X → T2Space ?X → _
loogle (Aug 13 2025 at 14:10):
:search: Ultrafilter.lim_eq_iff_le_nhds, isOpen_iff_ultrafilter', and 95 more
Aaron Liu (Aug 13 2025 at 14:10):
@loogle CompactSpace, T4Space
loogle (Aug 13 2025 at 14:10):
:shrug: nothing found
Artie Khovanov (Aug 13 2025 at 14:11):
Interesting @Aaron Liu - is there an instance [CompactSpace X] [T2Space X] -> [T4Space X] ("compact Hausdorff spaces are normal")? The crucial property in my examples is there there's theory on the T4 / IsStrictOrderedRing / IsFormallyReal class (in the absence of CompactSpace / Field) that I'd like to be able to use automatically.
Aaron Liu (Aug 13 2025 at 14:12):
import Mathlib
variable {X : Type*} [TopologicalSpace X]
[CompactSpace X] [T2Space X]
-- T4Space.of_paracompactSpace_t2Space
#synth T4Space X
Kenny Lau (Aug 13 2025 at 14:14):
Artie Khovanov said:
Since mathlib4 allows instance loops
is that true? i've not been informed of that?
Artie Khovanov (Aug 13 2025 at 14:14):
hm right thanks @Aaron Liu
seems like both design patterns are present in the library
I would strongly push to have the "right" typeclass to use in Mathlib be the one that's intuitive from the literature, where possible
even if this results in a mild performance hit due to the instance loop
eg if somebody writes [Field F] [LinearOrder F] [IsOrderedRing F] it will all look correct except now linarith, positivity etc doesn't work and it's very non obvious why
Artie Khovanov (Aug 13 2025 at 14:15):
Kenny Lau said:
Artie Khovanov said:
Since mathlib4 allows instance loops
is that true? i've not been informed of that?
the code snippet Aaron posted above implies they must be allowed
Yaël Dillies (Aug 13 2025 at 14:20):
Aaron Liu said:
I would like to say that we assume compact Hausdorff spaces as
[CompactSpace X] [T2Space X]97 times according to #loogle, but the equivalent spelling[CompactSpace X] [T4Space X]with stronger typeclasses gets zero results.
I think this is mostly because of how obscure T₄ is. I am an analyst and I can't even tell you what it means off-hand!
Eric Wieser (Aug 13 2025 at 14:20):
Artie Khovanov said:
Is there anywhere else in the library that we have this pattern? That is, where the mathlib definition uses a stronger class instance than the "standard" textbook definition would suggest due to how the instances line up in a weaker context?
Yes, between
[NormedDivisionRing K] [NormedAddCommGroup V] [Module K V] [NormSMulClass K V](what we use)[NormedDivisionRing K] [NormedAddCommGroup V] [Module K V] [IsBoundedSMul K V]("weaker" assumptions, but provably equivalent via docs#NormedDivisionRing.toNormSMulClass)
Eric Wieser (Aug 13 2025 at 14:21):
This example came up in a refactor by @David Loeffler which introduced docs#NormSMulClass, and I think he initially built 2. but I argued for 1.
Artie Khovanov (Aug 13 2025 at 14:23):
@Eric Wieser This was the example you gave in the PR, right? I think that's a bit different, because surely the standard definition of a normed module is that norm is multiplicative?
Artie Khovanov (Aug 13 2025 at 14:24):
Like, if we always want to go with the weaker class and remove loops, then that's fine, but I'd personally prefer loops where they yield more intuitive definitions.
David Loeffler (Aug 16 2025 at 06:25):
Just coming late to this thread: I disagree with @Artie Khovanov about what is the "standard definition"; when you look at modules over normed rings, not fields – modules over Banach algebras, etc – it starts to seem very unnatural and inconvenient to require precise multiplicativity of the norm, and sub-multiplicativity is the much more natural concept. That was the whole point of my refactor: to make it possible to state theorems about Banach modules over Banach algebras in a natural way.
Artie Khovanov (Aug 16 2025 at 06:39):
hmm, fair enough - looks like it is a similar example
Junyan Xu (Aug 16 2025 at 16:42):
The combination [Field R] [IsOrderedRing R] is also being added at https://github.com/leanprover-community/mathlib4/pull/28179/files#diff-992879dba2aba59569a7f9927753bfac51b97ec097d9868083b355cbb93fa772R140-R145 and I personally prefer it.
Artie Khovanov (Aug 16 2025 at 16:53):
@Junyan Xu indeed, in that PR, the instance is added back manually within the proof
I think in either case that PR has the wrong design - either we should make .toStrictOrderedRing an instance, or (much as I dislike this) we should use the stronger instance in the hypotheses
Jireh Loreaux (Aug 18 2025 at 10:58):
We also use [Ring R] [IsTopologicalRing R] in hypotheses instead of IsTopologicalSemiring R, even though these are equivalent.
Eric Wieser (Aug 18 2025 at 11:06):
I think it's clear we should have a linter against these "weaker" spellings if we want to discourage them. Although actually, the instance not existing already works
Artie Khovanov (Aug 18 2025 at 11:15):
Eric Wieser said:
Although actually, the instance not existing already works
This is my point -- I don't think it does! It does in the examples where you can weaken the standard definition, but not in my example or the module over Banach algebra example. You write the obvious thing, and tactics, exact etc. just fail silently. I think a linter would be a good idea if we indeed want to avoid these sorts of threads every so often.
Artie Khovanov (Aug 18 2025 at 11:47):
Secondary consideration: we should formally write the preferred spelling down somewhere in the documentation.
Eric Wieser (Aug 18 2025 at 12:15):
I think if we have a correct linter we shouldn't do that
Aaron Liu (Aug 18 2025 at 12:16):
No we definitely should write the preferred spelling somewhere
Artie Khovanov (Aug 18 2025 at 12:18):
I would even push for library note with @Eric Wieser's rationale + common preferred spellings somewhere (else?)
Eric Wieser (Aug 18 2025 at 12:35):
Aaron Liu said:
No we definitely should write the preferred spelling somewhere
Sounds like a recipe for having it go out of sync with the linter
Aaron Liu (Aug 18 2025 at 12:35):
Things go out of sync all the time
Aaron Liu (Aug 18 2025 at 12:38):
Just yesterday I saw docs#ModelWithCorners.toFun' docstring saying something about how the port is still happening
Coercion of a model with corners to a function. We don't use
e.toFunbecause it is actuallye.toPartialEquiv.toFun, sosimpwill apply lemmas abouttoPartialEquiv. While we may want to switch to this behavior later, doing it mid-port will break a lot of proofs.
Last updated: Dec 20 2025 at 21:32 UTC