Zulip Chat Archive
Stream: new members
Topic: heartbeats w/ modules over ring quotients
Paul Nelson (Jan 19 2024 at 14:32):
This code gives the error "failed to synthesize Module (R ⧸ P) (R ⧸ P)", which goes away if I increase the heartbeat limit substantially. Is there anything obvious that I'm doing wrong?
import Mathlib
-- set_option synthInstance.maxHeartbeats 1000000
-- set_option trace.Meta.synthInstance true in
-- set_option trace.profiler true in
example
(R : Type) [CommRing R]
(P : Ideal R) (hP : Ideal.IsMaximal P)
: 0 = 0 := by
letI h : Field (R ⧸ P) := Ideal.Quotient.field P
let M : Submodule (R ⧸ P) (R ⧸ P) := ⊤
sorry
I can fix this example by swapping the order of the two lines in the proof, but in more complicated situations it would be nice not to have to do that.
Riccardo Brasca (Jan 19 2024 at 15:05):
To fix it you can do something like
import Mathlib
-- set_option synthInstance.maxHeartbeats 1000000
-- set_option trace.Meta.synthInstance true in
-- set_option trace.profiler true in
example
(R : Type) [CommRing R]
(P : Ideal R) (hP : Ideal.IsMaximal P)
: 0 = 0 := by
letI h : Field (R ⧸ P) := Ideal.Quotient.field P
letI ring := Semiring.toModule (R := R ⧸ P)
let M : Submodule (R ⧸ P) (R ⧸ P) := ⊤
sorry
Riccardo Brasca (Jan 19 2024 at 15:06):
But of course this shouldn't happen in the first place. We are aware of these kinds of issues, even if this one looks a little different from the usual ones.
@Matthew Ballard do you recognize a known problem here?
Riccardo Brasca (Jan 19 2024 at 15:06):
Ah, wait
Riccardo Brasca (Jan 19 2024 at 15:07):
It is because of the line
letI h : Field (R ⧸ P) := Ideal.Quotient.field P
Riccardo Brasca (Jan 19 2024 at 15:08):
If you erase it everything is instantaneous. The point is that you are defining a new field structure on R ⧸ P
, and now Lean has to realize that the ring induced by this field structure is the same as the original one. I think this is the part that takes a lot of time.
Riccardo Brasca (Jan 19 2024 at 15:10):
You may use docs#IsField via docs#Ideal.Quotient.maximal_ideal_iff_isField_quotient, but it depends on what you want to prove.
Paul Nelson (Jan 19 2024 at 15:14):
This arises in a situation where I would like to apply a theorem about modules over fields to say something about more general rings, via passage to quotients by maximal ideals. The theorem that I would like to apply has [Field k] in its hypotheses.
Matthew Ballard (Jan 19 2024 at 15:15):
There is something suboptimal with Field
. I’ll poke at later today.
Paul Nelson (Jan 19 2024 at 15:16):
Thanks.
it sounds like Ricardo’s suggestion is that I could rewrite the theorem I’m applying to have [CommRing k] (h : IsField k) as its hypothesis?
Kevin Buzzard (Jan 19 2024 at 15:17):
Yeah but if we think like that then the conclusion is that we should have two versions of every theorem involving a field (and 2^n versions of every theorem involving n fields), which doesn't sound good...
Kevin Buzzard (Jan 19 2024 at 15:17):
It's better to fix the problem than to work around it.
Riccardo Brasca (Jan 19 2024 at 15:21):
@Paul Nelson I was suggesting that maybe in your case you can find a workaround using IsField
, but of course what you did with Field
should 100% work. I think the problem comes from
protected noncomputable def field (I : Ideal R) [hI : I.IsMaximal] : Field (R ⧸ I) :=
{ Quotient.commRing I, Quotient.groupWithZero I with }
that is still the Lean3 way of defining things.
Riccardo Brasca (Jan 19 2024 at 15:24):
The point is that the way algebraic structures are handled by Lean changed completely between Lean 3 and Lean 4, and even if in theory we can still follow the Lean 3 style, sometimes things become very slow. Here Lean has troubles in checking (the mathematically obvious fact) that the ring induced the field structure is the ring structure you started with. This is because the field structure is defined in a way that is adapted to the Lean 3 way, and we should change it.
We become aware of this during the port, and we fixed the most problematic definition, but not all of them.
Paul Nelson (Jan 19 2024 at 15:26):
Many thanks for the clarifications
Riccardo Brasca (Jan 19 2024 at 15:29):
In practice you have to wait a couple of days (maybe a couple of hours) and we will fix the problem. Let me see if I can do something.
Riccardo Brasca (Jan 19 2024 at 15:37):
#9855 seems enough
Kevin Buzzard (Jan 19 2024 at 16:50):
I was going to suggest
@[reducible]
protected noncomputable def field (I : Ideal R) [hI : I.IsMaximal] : Field (R ⧸ I) :=
{ toCommRing := Quotient.commRing I
inv := (Quotient.groupWithZero I).inv
mul_inv_cancel := (Quotient.groupWithZero I).mul_inv_cancel
inv_zero := (Quotient.groupWithZero I).inv_zero }
#align ideal.quotient.field Ideal.Quotient.field
Is yours better? Yours still has a let
in but I'm now confused about how bad they are. Hmm, I timed them both and they're the same.
Riccardo Brasca (Jan 19 2024 at 17:10):
I honestly don't know, I just copied how the field instance is defined on AdjointRoot
because I remember we spent quite a lot of time on that one
Kevin Buzzard (Jan 19 2024 at 17:23):
Eric's comment on the PR is beyond my pay grade.
Last updated: May 02 2025 at 03:31 UTC