Zulip Chat Archive
Stream: mathlib4
Topic: First Isomorphism Theorem
brokkilisoup (Dec 21 2023 at 09:06):
Hello, I'm a master student (new in Lean) trying to Re-proving First Isomorphism Theorem. I managed to give a proof of the First Isomorphism Theorem using the "lift" function and the code is the following
import Mathlib.GroupTheory.Sylow
import Mathlib.GroupTheory.Perm.Cycle.Concrete
import Mathlib.GroupTheory.Perm.Subgroup
import Mathlib.GroupTheory.PresentedGroup
import Mathlib.GroupTheory.Subgroup.Basic
open QuotientGroup
theorem first_isomorphism_theorem {G : Type*} [Group G] {H : Type*} [Group H] (f : G →* H) : ((G ⧸ f.ker) ≃* f.range) := by
--have h : f.ker.Normal := inferInstance -- Serve? No, perché è un'istanza di Group, non di GroupWithZero
have h : f.ker ≤ f.ker := by
exact le_rfl
done
set f' := QuotientGroup.lift f.ker f h with hf'
have f'_range := MonoidHom.rangeRestrict_surjective f' -- Set.rangeFactorization f'
have h' : f'.ker = ⊥ := by
rw[eq_bot_iff_forall]
intro x
intro hx
rw[MonoidHom.mem_ker] at hx
have hp := QuotientGroup.mk'_surjective f.ker
unfold Function.Surjective at hp
rcases hp x with ⟨x', hx'⟩
have : f x' = f' x := by
rw[←hx']
exact rfl
done
rw[hx] at this
rw[← MonoidHom.mem_ker] at this
have x'_in_ker : (QuotientGroup.mk' f.ker) x' = 1 := by
rw [coe_mk']
rw [eq_one_iff]
exact this
done
rw[←hx',x'_in_ker]
done
rw[MonoidHom.ker_eq_bot_iff] at h'
have h'' : f'.range = f.range := by
ext y
constructor
-- sinistra -> destra
intro hy
rcases hy with ⟨x, hx⟩
have hp' := QuotientGroup.mk'_surjective f.ker
unfold Function.Surjective at hp'
rcases hp' x with ⟨x', hx'⟩
have : f x' = f' x := by
rw[←hx']
exact rfl
done
rw[hx] at this
rw[MonoidHom.mem_range]
use x'
-- destra -> sinistra
intro hy
rcases hy with ⟨y', hy'⟩
rw[MonoidHom.mem_range]
use y'
rw[←hy']
exact rfl
done
rw[← h'']
have f''_inj : (Function.Injective (MonoidHom.rangeRestrict f')) := MonoidHom.rangeRestrict_injective_iff.mpr h'
have sp : Function.Surjective (MonoidHom.rangeRestrict f') := f'_range
have f''_iso : Function.Bijective (MonoidHom.rangeRestrict f') := by
exact ⟨f''_inj, sp⟩
exact MulEquiv.ofBijective (MonoidHom.rangeRestrict f') f''_iso
As you see, everything is built around the lien set f' := QuotientGroup.lift f.ker f h with hf'
and everything works perfectly. What I wanted to know is whether there is a way (although sub-optimal), and if yes how, to define without invoking any theorem f' as a group function from the quotient to the image and then proving that is well defined, and then using it as f' of theorem above (since set f' := QuotientGroup.lift f.ker f h with hf'
already does all this work for me).
Any help or even tip about my code would be appreciated, thank you for your time.
Martin Dvořák (Dec 21 2023 at 11:59):
Imports are missing.
brokkilisoup (Dec 21 2023 at 12:02):
I'm sorry youre right, these are my imports
import Mathlib.GroupTheory.Sylow
import Mathlib.GroupTheory.Perm.Cycle.Concrete
import Mathlib.GroupTheory.Perm.Subgroup
import Mathlib.GroupTheory.PresentedGroup
import Mathlib.GroupTheory.Subgroup.Basic
Martin Dvořák (Dec 21 2023 at 12:05):
I get "unknown identifier 'eq_bot_iff_forall'".
Eric Wieser (Dec 21 2023 at 12:15):
Please edit your importants into your previous message so that the "view in lean4 playground" link works!
brokkilisoup (Dec 21 2023 at 12:29):
Martin Dvořák ha scritto:
I get "unknown identifier 'eq_bot_iff_forall'".
I don't know why, could be that I have an update version of Lean or? eq_bot_iff_forall is not a lemma I added, with #check I get
Subgroup.eq_bot_iff_forall.{u_1} {G : Type u_1} [inst✝ : Group G] (H : Subgroup G) : H = ⊥ ↔ ∀ x ∈ H, x = 1
brokkilisoup (Dec 21 2023 at 12:30):
Eric Wieser ha scritto:
Please edit your importants into your previous message so that the "view in lean4 playground" link works!
Done, thank you for the tip
Martin Dvořák (Dec 21 2023 at 12:35):
Some superficial (i.e., without understanding the proof) refactoring for you (let diff be your code review):
import Mathlib.GroupTheory.Sylow
import Mathlib.GroupTheory.Perm.Cycle.Concrete
import Mathlib.GroupTheory.Perm.Subgroup
import Mathlib.GroupTheory.PresentedGroup
import Mathlib.GroupTheory.Subgroup.Basic
open QuotientGroup
theorem first_isomorphism_theorem {G : Type*} [Group G] {H : Type*} [Group H] (f : G →* H) : ((G ⧸ f.ker) ≃* f.range) := by
--have h : f.ker.Normal := inferInstance -- Serve? No, perché è un'istanza di Group, non di GroupWithZero
have h : f.ker ≤ f.ker := by
rfl
set f' := QuotientGroup.lift f.ker f h with hf'
have f'_range := MonoidHom.rangeRestrict_surjective f' -- Set.rangeFactorization f'
have h' : f'.ker = ⊥ := by
sorry
rw[MonoidHom.ker_eq_bot_iff] at h'
have h'' : f'.range = f.range := by
ext y
constructor
-- sinistra -> destra
· intro hy
rcases hy with ⟨x, hx⟩
have hp' := QuotientGroup.mk'_surjective f.ker
unfold Function.Surjective at hp'
rcases hp' x with ⟨x', hx'⟩
have : f x' = f' x := by
rw[←hx']
rfl
rw[hx] at this
rw[MonoidHom.mem_range]
use x'
-- destra -> sinistra
· intro hy
rcases hy with ⟨y', hy'⟩
rw[MonoidHom.mem_range]
use y'
rw[←hy']
rfl
rw[← h'']
have f''_inj : (Function.Injective (MonoidHom.rangeRestrict f')) := MonoidHom.rangeRestrict_injective_iff.mpr h'
have f''_iso : Function.Bijective (MonoidHom.rangeRestrict f') := ⟨f''_inj, f'_range⟩
exact MulEquiv.ofBijective (MonoidHom.rangeRestrict f') f''_iso
brokkilisoup (Dec 21 2023 at 13:37):
Martin Dvořák ha scritto:
Some superficial (i.e., without understanding the proof) refactoring for you (let diff be your code review):
import Mathlib.GroupTheory.Sylow import Mathlib.GroupTheory.Perm.Cycle.Concrete import Mathlib.GroupTheory.Perm.Subgroup import Mathlib.GroupTheory.PresentedGroup import Mathlib.GroupTheory.Subgroup.Basic open QuotientGroup theorem first_isomorphism_theorem {G : Type*} [Group G] {H : Type*} [Group H] (f : G →* H) : ((G ⧸ f.ker) ≃* f.range) := by --have h : f.ker.Normal := inferInstance -- Serve? No, perché è un'istanza di Group, non di GroupWithZero have h : f.ker ≤ f.ker := by rfl set f' := QuotientGroup.lift f.ker f h with hf' have f'_range := MonoidHom.rangeRestrict_surjective f' -- Set.rangeFactorization f' have h' : f'.ker = ⊥ := by sorry rw[MonoidHom.ker_eq_bot_iff] at h' have h'' : f'.range = f.range := by ext y constructor -- sinistra -> destra · intro hy rcases hy with ⟨x, hx⟩ have hp' := QuotientGroup.mk'_surjective f.ker unfold Function.Surjective at hp' rcases hp' x with ⟨x', hx'⟩ have : f x' = f' x := by rw[←hx'] rfl rw[hx] at this rw[MonoidHom.mem_range] use x' -- destra -> sinistra · intro hy rcases hy with ⟨y', hy'⟩ rw[MonoidHom.mem_range] use y' rw[←hy'] rfl rw[← h''] have f''_inj : (Function.Injective (MonoidHom.rangeRestrict f')) := MonoidHom.rangeRestrict_injective_iff.mpr h' have f''_iso : Function.Bijective (MonoidHom.rangeRestrict f') := ⟨f''_inj, f'_range⟩ exact MulEquiv.ofBijective (MonoidHom.rangeRestrict f') f''_iso
Thanks, however I was asking whether I could skip "lift" usage and defining f' myself, showing that is well defined
Eric Wieser (Dec 21 2023 at 23:46):
If you want to do it "from the basics" for pedagogical reasons, you can use Quotient.lift
instead of QuotientGroup.lift
Last updated: May 02 2025 at 03:31 UTC