Zulip Chat Archive
Stream: Is there code for X?
Topic: Transfering algebra structure via ring homomorphism
Michał Staromiejski (Jan 24 2025 at 19:47):
From time to time in my proofs I encounter a need to transfer Algebra R A
structure via a ring homomorphism f : A →+* B
to get compatible Algebra R B
(so that I can lift f
to an algebra homomorphism). It can be done quite simply:
import Mathlib.Algebra.Algebra.Defs
/-- Transfer `R`-algebra structure via ring homomorphism. -/
def Algebra.of_algebra_of_ringHom (R : Type*) {A B : Type*} [CommSemiring R] [Semiring A]
[CommSemiring B] [Algebra R A] (f : A →+* B) : Algebra R B :=
f.comp (algebraMap R A) |>.toAlgebra
and I could not find this kind of tool in Mathlib, so maybe we want it?
I was also thinking to make a version that can return both Algebra R B
and the lifted f
:
def Algebra.of_algebra_of_ringHom₂ (R : Type*) {A B : Type*} [CommSemiring R] [Semiring A]
[CommSemiring B] [Algebra R A] (f : A →+* B) : (_ : Algebra R B) ×' (A →ₐ[R] B) :=
letI inst := of_algebra_of_ringHom R f; ⟨inst, ⟨f, fun _r ↦ rfl⟩⟩
and it kind of works but in some cases creates unexpected results:
example (R : Type*) {A B C : Type*} [CommSemiring R] [Semiring A] [CommSemiring B] [CommSemiring C]
[Algebra R A] (f : A →+* B × C) : ... :=
letI ⟨algBC, f'⟩ := Algebra.of_algebra_of_ringHom₂ R f /- `Algebra R (B × C)` and lifted `f` -/
letI algB := Algebra.of_algebra_of_ringHom R (RingHom.fst B C) /- `Algebra R B` -/
letI algC := Algebra.of_algebra_of_ringHom R (RingHom.snd B C) /- `Algebra R C` -/
let g := (AlgHom.fst R B C).comp f' /- error -/
Error in the last line occures because I guess for AlgHom.fst R B C
the Algebra R (B × C)
structure comes from the instance Prod.algebra
, wheras the one for f'
is algBC
which is a different 'object', even if it contains same data (not definitionally equal). Is there any mechanism that allows AlgHom.fst R B C
to take the structure from the local context?
Michał Staromiejski (Jan 24 2025 at 22:47):
Ok, I think clean solution would be to use lifts at each stage and use the lift of RingHom.fst B C
instead of AlgHom.fst R B C
:
example (R : Type*) {A B C : Type*} [CommSemiring R] [Semiring A] [CommSemiring B] [CommSemiring C]
[Algebra R A] (f' : A →+* B × C) : ... :=
letI ⟨algBC, f⟩ := Algebra.of_algebra_of_ringHom₂ R f' /- `Algebra R (B × C)` and lifted `f'` -/
letI ⟨algB, g⟩ := Algebra.of_algebra_of_ringHom₂ R (RingHom.fst B C) /- `Algebra R B` + lift of `RingHom.fst` -/
letI ⟨algC, h⟩ := Algebra.of_algebra_of_ringHom₂ R (RingHom.snd B C) /- `Algebra R C` + lift -/
let k := g.comp f /- ok -/
Michał Staromiejski (Jan 24 2025 at 22:49):
I'd add this to Mathlib, any suggestions for a good name(s)?
Eric Wieser (Jan 24 2025 at 23:39):
Eric Wieser (Jan 24 2025 at 23:39):
Ah, this is the wrong argument for you
Johan Commelin (Jan 25 2025 at 06:10):
@Michał Staromiejski Maybe something like Algebra.ofCompRight
?
Johan Commelin (Jan 25 2025 at 06:10):
And yes, adding this to mathlib sounds like a good plan
Michał Staromiejski (Jan 25 2025 at 08:47):
@Eric Wieser this one almost feels like a dual, I'm actually surprised that it's not defined just via docs#RingHom.toAlgebra.
@Johan Commelin You mean version with lifting, right?
Michał Staromiejski (Jan 25 2025 at 10:08):
One more question: according to the definition of Algebra.of_algebra_of_ringHom₂
above, the toFun
of both the ring hom and its lift should be defeq:
example (R : Type*) {A B : Type*} [CommSemiring R] [Semiring A] [CommSemiring B]
[Algebra R A] {f : A →+* B} : (of_algebra_of_ringHom₂ R f).2 = f := rfl /- ok -/
However, when I use it with pattern matching (is this the right term?), it seems not to work:
example (R : Type*) {A B : Type*} [CommSemiring R] [Semiring A] [CommSemiring B]
[Algebra R A] (f' : A →+* B) : ... :=
let ⟨_, f⟩ := Algebra.of_algebra_of_ringHom₂ R f' /- `Algebra R B` and lifted `f'` -/
have : f = f' := rfl /- error -/
What is going on here?
Kevin Buzzard (Jan 25 2025 at 12:40):
Can you give a #mwe ? I've not been following this thread and I'm not sure what goes in the ... .
Eric Wieser (Jan 25 2025 at 13:04):
The issue here is that pattern matching is forgetful, like have
Eric Wieser (Jan 25 2025 at 13:05):
If you use .1
and .2
instead it will work
Michał Staromiejski (Jan 25 2025 at 17:29):
Kevin Buzzard said:
Can you give a #mwe ? I've not been following this thread and I'm not sure what goes in the ... .
My original code is quite complicated but I will try with some sorries (I do have proofs for them, just wanted to simplify):
import Mathlib.Algebra.Algebra.Defs
import Mathlib.Algebra.Algebra.Hom
import Mathlib.Algebra.Ring.Prod
import Mathlib.RingTheory.LocalRing.Basic
def of_algebra_of_ringHom (R : Type*) {A B : Type*} [CommSemiring R] [Semiring A]
[CommSemiring B] [Algebra R A] (f : A →+* B) : Algebra R B :=
f.comp (algebraMap R A) |>.toAlgebra
def of_algebra_of_ringHom₂ (R : Type*) {A B : Type*} [CommSemiring R] [Semiring A]
[CommSemiring B] [Algebra R A] (f : A →+* B) : (_ : Algebra R B) ×' (A →ₐ[R] B) :=
letI inst := of_algebra_of_ringHom R f; ⟨inst, ⟨f, fun _r ↦ rfl⟩⟩
example (R : Type*) {A₁ A₂ : Type*} [CommSemiring R] [Semiring A₁] [CommSemiring A₂]
[Algebra R A₁] {f : A₁ →+* A₂} (hf : Function.Surjective f) :
Function.Surjective (of_algebra_of_ringHom₂ R f).2 := hf /- works -/
/-- For a non-local ring, there exists a surjection onto product of two fields. -/
lemma nonLocalProj {R : Type u} [CommRing R] [Nontrivial R] (h : ¬ IsLocalRing R) :
∃ (K₁ K₂ : Type u) (_ : Field K₁) (_ : Field K₂) (f : R →+* K₁ × K₂),
Function.Surjective f := sorry
theorem bigTheorem {F A : Type*} [Field F] [CommRing A] [Algebra F A] [Nontrivial A] : IsLocalRing A := by
by_contra h
let ⟨K₁, K₂, fK₁, fK₂, f', hf'⟩ := nonLocalProj h
let ⟨_, f⟩ := of_algebra_of_ringHom₂ F f'
/- now to proceed I need: -/
have hf : Function.Surjective f := hf'
/- does not work either: -/
have : f.toRingHom = f' := rfl
sorry
It actually does not matter what is the goal here, my question is about more general setting.
@Eric Wieser Thanks, will try, although it's not very consistent then with regular let
behavior...
Michał Staromiejski (Jan 25 2025 at 17:36):
Found also this, I'd say it is indeed an issue.
Junyan Xu (Jan 25 2025 at 17:37):
Does obtain
work here? (I guess not)
Michał Staromiejski (Jan 25 2025 at 17:38):
Actually seems to work :tada:
Ah no... Lean server has stopped :rolling_on_the_floor_laughing:
Michał Staromiejski (Jan 25 2025 at 18:15):
Just to confirm, in the MWE above, if I use
let alg_f := of_algebra_of_ringHom₂ F f'
letI := alg_f.1
let f := alg_f.2
instead of let ⟨_, f⟩ := of_algebra_of_ringHom₂ F f'
then everything is fine.
But it's rather a workaround...
Edward van de Meent (Jan 25 2025 at 18:35):
i suspect the earlier approach might need of_algebra_of_ringHom₂
to be reducible to work, then?
Michał Staromiejski (Jan 25 2025 at 18:48):
@Edward van de Meent I'm quite a beginner here so not sure what that would mean?
Jz Pan (Jan 26 2025 at 02:51):
Michał Staromiejski said:
My original code is quite complicated but I will try with some sorries (I do have proofs for them, just wanted to simplify):
If you don't need to make your auxiliary defs public, I think maybe algebraize
tactics is more suitable.
Michał Staromiejski (Jan 26 2025 at 09:47):
@Jz Pan Thanks for pointing it out. I had a look but not sure how would I use it in my MWE?
Jz Pan (Jan 26 2025 at 15:45):
I'm not familiar with it either. From the documents it seems that it can only generate Algebra
and IsScalarTower
automatically. Maybe let's ask the developer.
Last updated: May 02 2025 at 03:31 UTC