Zulip Chat Archive
Stream: Is there code for X?
Topic: Submonoid formed by the units
Xavier Xarles (Feb 16 2024 at 12:06):
Given a Monoid
, how can one construct the Submonoid
formed by the elements that have inverse? The Units
are not a Submonoid
, but something else...
Yaël Dillies (Feb 16 2024 at 12:11):
cc @Wrenna Robson
Wrenna Robson (Feb 16 2024 at 12:15):
So I think this is (\top : Submonoid M).units.ofUnits
Wrenna Robson (Feb 16 2024 at 12:16):
Or equivalently, actually, (\top : Subgroup M\times).ofUnits
Wrenna Robson (Feb 16 2024 at 12:16):
(not on pc, can't add proper symbols)
Wrenna Robson (Feb 16 2024 at 12:17):
But given a subgroup of units, ofUnits gives you the corresponding submonoid, and you want the subgroup of all units.
Wrenna Robson (Feb 16 2024 at 12:17):
If you want the subgroup of units corresponding to a given submonoid, that's what Submonoid.units is for
Eric Wieser (Feb 16 2024 at 13:01):
Is this also Units.coeHom.mrange
?
Wrenna Robson (Feb 16 2024 at 13:01):
Well that's as a set, but yeah I think so
Eric Wieser (Feb 16 2024 at 13:02):
docs#MonoidHom.mrange disagrees with you
Wrenna Robson (Feb 16 2024 at 13:02):
Oh lol
Wrenna Robson (Feb 16 2024 at 13:02):
Then yes
Eric Wieser (Feb 16 2024 at 13:02):
Whoops, I meant mrange
Wrenna Robson (Feb 16 2024 at 13:02):
Ahhhhh
Wrenna Robson (Feb 16 2024 at 13:03):
Yeah
Eric Wieser (Feb 16 2024 at 13:03):
But range
is a subgroup, not a set
Wrenna Robson (Feb 16 2024 at 13:04):
Yeah ofUnits is essentially just the image of coeHom so that sounds correct
Xavier Xarles (Feb 16 2024 at 22:04):
How do you feel about adding something like this in the Mathlib.GroupTheory.Submonoid.Units
?
import Mathlib.GroupTheory.Submonoid.Units
variable {M : Type*}
variable [CommMonoid M]
theorem mem_ofUnits_of_top_iff_isUnit (x:M) : x ∈ Subgroup.ofUnits ⊤ ↔ IsUnit x := by
rw [Subgroup.mem_ofUnits_iff_exists_isUnit]
exact exists_iff_of_forall fun _ => trivial
Wrenna Robson (Feb 16 2024 at 22:05):
Yeah we should probably have that.
Wrenna Robson (Feb 16 2024 at 22:05):
I'm wondering if there's any other analogous things that need adding
Wrenna Robson (Feb 16 2024 at 22:08):
We have one direction of it, it seems
Wrenna Robson (Feb 16 2024 at 22:08):
Subgroup.isUnit_of_mem_ofUnits
Wrenna Robson (Feb 16 2024 at 22:09):
Ah.
Wrenna Robson (Feb 16 2024 at 22:10):
And Subgroup.mem_ofUnits_of_isUnit_of_unit_mem is the other direction
Wrenna Robson (Feb 16 2024 at 22:10):
Or is once you consider everything is mem_top
Wrenna Robson (Feb 16 2024 at 22:11):
But your proof is also good
Wrenna Robson (Feb 16 2024 at 22:14):
Oh! Also, answering your original question again: it's also IsUnit.submonoid
Wrenna Robson (Feb 16 2024 at 22:15):
The table at the top of Submonoid/Units would say this, if it worked
Wrenna Robson (Feb 16 2024 at 22:16):
Yeah if you want the units as a submonoid of a monoid, use IsUnit.submonoid
Wrenna Robson (Feb 16 2024 at 22:22):
If you want the units as a submonoid of the monoid in which a submonoid lies, then that is S.units.ofUnits
Wrenna Robson (Feb 16 2024 at 22:23):
I guess Subgroup.ofUnits \top = IsUnit.submonoid M might be useful to have!
Wrenna Robson (Feb 16 2024 at 22:27):
Subgroup.ofUnits_top
Wrenna Robson (Feb 16 2024 at 22:30):
Yes, I think that would be good to have. We could also have the lemma you mention, which is naturally a consequence
Xavier Xarles (Feb 16 2024 at 22:32):
I don't like the proof, but something like this?
import Mathlib.GroupTheory.Submonoid.Units
variable {M : Type*}[CommMonoid M]
theorem Subgroup.ofUnits_top : Subgroup.ofUnits ⊤ = IsUnit.submonoid M := by
refine Submonoid.ext ?h
simp_rw [IsUnit.mem_submonoid_iff,Subgroup.mem_ofUnits_iff_exists_isUnit]
exact fun x => exists_iff_of_forall fun _ => trivial
Wrenna Robson (Feb 16 2024 at 22:33):
Yes, precisely.
Eric Wieser (Feb 16 2024 at 22:38):
A shorter proof:
import Mathlib.GroupTheory.Submonoid.Units
variable {M : Type*} [Monoid M]
theorem Units.mrange_coeHom : MonoidHom.mrange (Units.coeHom M) = IsUnit.submonoid M := rfl
theorem Subgroup.ofUnits_top : Subgroup.ofUnits ⊤ = IsUnit.submonoid M := (MonoidHom.mrange_eq_map _).symm
Wrenna Robson (Feb 16 2024 at 22:40):
Very nice
Wrenna Robson (Feb 16 2024 at 22:42):
Units.mrange_coeHom wants to be in a different file
Xavier Xarles (Feb 16 2024 at 23:03):
I really don't get how can the proof be so shorter, and using a result that doesn't seem related...
Wrenna Robson (Feb 16 2024 at 23:03):
Well, ofUnits is by definition (coeHom M).map
Wrenna Robson (Feb 16 2024 at 23:05):
So the LHS is map, by definition. And it turns out in fact IsUnit.submonoid is defeq to mrange
Wrenna Robson (Feb 16 2024 at 23:06):
That's more surprising maybe
Wrenna Robson (Feb 16 2024 at 23:13):
Oh this does mean that Submonoid.units (IsUnit.submonoid M) = \top as well
Wrenna Robson (Feb 16 2024 at 23:13):
If we don't have that too, we should
Wrenna Robson (Feb 16 2024 at 23:14):
call it Submonoid.units_isUnit_eq_top or something
Wrenna Robson (Feb 16 2024 at 23:17):
(it's an immediate consequence of the above, given the Galois insertion)
Wrenna Robson (Feb 16 2024 at 23:35):
@Yaël Dillies how do I say "the lattice of subgroups of units is equivalent to the lattice of submonoids contained in IsUnit.subMonoid, with the units/ofUnits Galois Coinsertion defining the maps across"?
Yaël Dillies (Feb 16 2024 at 23:39):
Subgroup (Units M) o~= {s : Submonoid M // s <= IsUnit.submonoid}
?
Wrenna Robson (Feb 16 2024 at 23:48):
Cool! I don't know if we tend to have theorems like that.
Yaël Dillies (Feb 17 2024 at 00:01):
Probably we have at least one direction
Eric Wieser (Feb 17 2024 at 00:11):
Isn't that just a special case of Subgroup M o~= {s : Submonoid N // s <= mrange f}
or similar?
Wrenna Robson (Feb 17 2024 at 00:12):
Hmm, perhaps!
Wrenna Robson (Feb 17 2024 at 00:12):
Is that true for arbitrary f?
Wrenna Robson (Feb 17 2024 at 00:13):
ofUnits is just map, but units needed a little more to it, so it would seem surprising to me if it came out of that.
Xavier Xarles (Feb 18 2024 at 11:21):
It seems that we don't have
import Mathlib.Algebra.Group.Units
variable {M:Type*}
lemma IsUnit.exists_inv [Monoid M] {a : M}(h : IsUnit a) :
∃ b, (a * b = 1) ∧ (b * a = 1) := by
rcases h with ⟨⟨a, b, hab,hba⟩, rfl⟩
exact ⟨b, ⟨ hab, hba⟩⟩
theorem isUnit_iff_exists [Monoid M] {a : M} : IsUnit a ↔
∃ b, (a * b = 1) ∧ (b * a = 1) :=
⟨fun h => IsUnit.exists_inv h , fun ⟨b, hab,hba⟩ => by use ⟨_, b, hab,hba⟩ ⟩
Eric Wieser (Feb 18 2024 at 11:25):
I think that's probably because you never need those lemmas
Xavier Xarles (Feb 18 2024 at 11:26):
May be. Although I discovered because I need them...
Eric Wieser (Feb 18 2024 at 11:26):
It's usually more convenient to keep a Unit
around than to unpack it into the val and inv
Xavier Xarles (Feb 18 2024 at 11:27):
In fact I need the other way: if I have such a b
, then a
is a Unit.
Eric Wieser (Feb 18 2024 at 11:29):
Can you share your context?
Damiano Testa (Feb 18 2024 at 11:29):
There are results around docs#isUnit_iff_exists_inv
Jireh Loreaux (Feb 18 2024 at 14:58):
If you actually have a b
, you can easily just build a term of Units
directly, and even use the lift
tactic to turn a
itself into a unit.
Junyan Xu (Feb 18 2024 at 15:48):
IsUnit a ↔ (∃ b, a * b = 1) ∧ (∃ c, c * a = 1)
is probably more useful ...
Wrenna Robson (Feb 18 2024 at 15:49):
Why?
Junyan Xu (Feb 18 2024 at 15:52):
It's not just a rephrasing of the definition (i.e. you can't get it by permuting arguments of the constructors), instead you need associativity to prove the reverse direction.
Xavier Xarles (Feb 19 2024 at 11:30):
So, how do you feel about this result?
import Mathlib.GroupTheory.Submonoid.Units
variable {M : Type*} [Monoid M]
theorem isUnit_iff_exists_both_units (a:M): IsUnit a ↔ (∃ b, a * b = 1) ∧ (∃ c, c * a = 1):= by
constructor <;> intro h
· rcases h with ⟨⟨a, b, hab,hba⟩, rfl⟩
exact ⟨Exists.intro b hab, Exists.intro b hba⟩
· let ⟨b,hab⟩ := h.1
let ⟨c,hca⟩ := h.2
have beqc: b = c:= by
calc
b = 1*b := (one_mul b).symm
_ = (c*a)*b := congrFun (congrArg HMul.hMul (id hca.symm)) b
_ = c*(a*b) := mul_assoc c a b
_ = c*1:= congrArg (HMul.hMul c) hab
_ = c := mul_one c
rw [←beqc] at hca
use ⟨_, b, hab,hca⟩
Wrenna Robson (Feb 19 2024 at 11:31):
Junyan Xu said:
It's not just a rephrasing of the definition (i.e. you can't get it by permuting arguments of the constructors), instead you need associativity to prove the reverse direction.
Hmm. Yeah I suppose it being both directions is the interesting bit.
Wrenna Robson (Feb 19 2024 at 11:32):
Xavier Xarles said:
So, how do you feel about this result?
import Mathlib.GroupTheory.Submonoid.Units variable {M : Type*} [Monoid M] theorem isUnit_iff_exists_both_units (a:M): IsUnit a ↔ (∃ b, a * b = 1) ∧ (∃ c, c * a = 1):= by constructor <;> intro h · rcases h with ⟨⟨a, b, hab,hba⟩, rfl⟩ exact ⟨Exists.intro b hab, Exists.intro b hba⟩ · let ⟨b,hab⟩ := h.1 let ⟨c,hca⟩ := h.2 have beqc: b = c:= by calc b = 1*b := (one_mul b).symm _ = (c*a)*b := congrFun (congrArg HMul.hMul (id hca.symm)) b _ = c*(a*b) := mul_assoc c a b _ = c*1:= congrArg (HMul.hMul c) hab _ = c := mul_one c rw [←beqc] at hca use ⟨_, b, hab,hca⟩
It feels like in many ways we should have a defined predicate for "IsLeftUnit" but it's good.
Eric Wieser (Feb 19 2024 at 11:43):
That golfs to
theorem isUnit_iff_exists_both_units (a : M) : IsUnit a ↔ (∃ b, a * b = 1) ∧ (∃ c, c * a = 1):= by
constructor
· rintro ⟨⟨a, b, hab, hba⟩, rfl⟩
exact ⟨⟨b, hab⟩, ⟨b, hba⟩⟩
· rintro ⟨⟨b, hab⟩, ⟨c, hca⟩⟩
suffices b = c from ⟨⟨a, b, hab, this ▸ hca⟩, rfl⟩
calc
b = 1*b := (one_mul b).symm
_ = (c*a)*b := congrArg (· * b) hca.symm
_ = c*(a*b) := mul_assoc c a b
_ = c*1 := congrArg (c * ·) hab
_ = c := mul_one c
Damiano Testa (Feb 19 2024 at 12:28):
Or you could use regular
elements:
theorem isUnit_iff_exists_both_units (a : M) : IsUnit a ↔ (∃ b, a * b = 1) ∧ (∃ c, c * a = 1):= by
constructor
· rintro ⟨⟨a, b, hab, hba⟩, rfl⟩
exact ⟨⟨b, hab⟩, ⟨b, hba⟩⟩
· rintro ⟨⟨b, hab⟩, ⟨c, hca⟩⟩
suffices b = c from ⟨⟨a, b, hab, this ▸ hca⟩, rfl⟩
have : IsRegular a := ⟨isLeftRegular_of_mul_eq_one ‹_›, isRightRegular_of_mul_eq_one ‹_›⟩
exact this.right (this.left (by simp [← mul_assoc, *]))
Kevin Buzzard (Feb 19 2024 at 18:51):
You can also use docs#left_inv_eq_right_inv
Kevin Buzzard (Feb 19 2024 at 19:52):
This is the only interesting theorem I know about monoids :-)
Last updated: May 02 2025 at 03:31 UTC