l3lab/ntp-mathlib huggingface dataset:
/-- The free-forgetful adjunction for groups.
-/
def adj : free ⊣ forget GroupCat.{u} :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X G => FreeGroup.lift.symm
      -- Porting note: used to be just `by intros; ext1; rfl`.
      homEquiv_naturality_left_symm := by
        intros
        ext1
        

Proof state:
case w
X'✝ X✝ : Type u
Y✝ : GroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget GroupCat).obj Y✝
x✝ : ↑(free.obj X'✝)
⊢ (((fun X G => FreeGroup.lift.symm) X'✝ Y✝).symm (f✝ ≫ g✝)) x✝ =
    (free.map f✝ ≫ ((fun X G => FreeGroup.lift.symm) X✝ Y✝).symm g✝) x✝

Next tactic:
simp only [Equiv.symm_symm]
/-- The free-forgetful adjunction for groups.
-/
def adj : free ⊣ forget GroupCat.{u} :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X G => FreeGroup.lift.symm
      -- Porting note: used to be just `by intros; ext1; rfl`.
      homEquiv_naturality_left_symm := by
        intros
        ext1
        simp only [Equiv.symm_symm]
        

Proof state:
case w
X'✝ X✝ : Type u
Y✝ : GroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget GroupCat).obj Y✝
x✝ : ↑(free.obj X'✝)
⊢ (FreeGroup.lift (f✝ ≫ g✝)) x✝ = (free.map f✝ ≫ FreeGroup.lift g✝) x✝

Next tactic:
apply Eq.symm
/-- The free-forgetful adjunction for groups.
-/
def adj : free ⊣ forget GroupCat.{u} :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X G => FreeGroup.lift.symm
      -- Porting note: used to be just `by intros; ext1; rfl`.
      homEquiv_naturality_left_symm := by
        intros
        ext1
        simp only [Equiv.symm_symm]
        apply Eq.symm
        

Proof state:
case w.h
X'✝ X✝ : Type u
Y✝ : GroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget GroupCat).obj Y✝
x✝ : ↑(free.obj X'✝)
⊢ (free.map f✝ ≫ FreeGroup.lift g✝) x✝ = (FreeGroup.lift (f✝ ≫ g✝)) x✝

Next tactic:
apply FreeGroup.lift.unique
/-- The free-forgetful adjunction for groups.
-/
def adj : free ⊣ forget GroupCat.{u} :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X G => FreeGroup.lift.symm
      -- Porting note: used to be just `by intros; ext1; rfl`.
      homEquiv_naturality_left_symm := by
        intros
        ext1
        simp only [Equiv.symm_symm]
        apply Eq.symm
        apply FreeGroup.lift.unique
        

Proof state:
case w.h.hg
X'✝ X✝ : Type u
Y✝ : GroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget GroupCat).obj Y✝
x✝ : ↑(free.obj X'✝)
⊢ ∀ (x : X'✝), (free.map f✝ ≫ FreeGroup.lift g✝) (FreeGroup.of x) = (f✝ ≫ g✝) x

Next tactic:
intros
/-- The free-forgetful adjunction for groups.
-/
def adj : free ⊣ forget GroupCat.{u} :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X G => FreeGroup.lift.symm
      -- Porting note: used to be just `by intros; ext1; rfl`.
      homEquiv_naturality_left_symm := by
        intros
        ext1
        simp only [Equiv.symm_symm]
        apply Eq.symm
        apply FreeGroup.lift.unique
        intros
        

Proof state:
case w.h.hg
X'✝ X✝ : Type u
Y✝ : GroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget GroupCat).obj Y✝
x✝¹ : ↑(free.obj X'✝)
x✝ : X'✝
⊢ (free.map f✝ ≫ FreeGroup.lift g✝) (FreeGroup.of x✝) = (f✝ ≫ g✝) x✝

Next tactic:
apply FreeGroup.lift.of
/-- The abelianization functor `Group ⥤ CommGroup` sending a group `G` to its abelianization `Gᵃᵇ`.
 -/
def abelianize : GroupCat.{u} ⥤ CommGroupCat.{u} where
  obj G :=
    { α := Abelianization G
      str := by 

Proof state:
G : GroupCat
⊢ CommGroup (Abelianization ↑G)

Next tactic:
infer_instance
/-- The abelianization functor `Group ⥤ CommGroup` sending a group `G` to its abelianization `Gᵃᵇ`.
 -/
def abelianize : GroupCat.{u} ⥤ CommGroupCat.{u} where
  obj G :=
    { α := Abelianization G
      str := by infer_instance }
  map f :=
    Abelianization.lift
      { toFun := fun x => Abelianization.of (f x)
        map_one' := by 

Proof state:
X✝ Y✝ : GroupCat
f : X✝ ⟶ Y✝
⊢ (fun x => Abelianization.of (f x)) 1 = 1

Next tactic:
simp
/-- The abelianization functor `Group ⥤ CommGroup` sending a group `G` to its abelianization `Gᵃᵇ`.
 -/
def abelianize : GroupCat.{u} ⥤ CommGroupCat.{u} where
  obj G :=
    { α := Abelianization G
      str := by infer_instance }
  map f :=
    Abelianization.lift
      { toFun := fun x => Abelianization.of (f x)
        map_one' := by simp
        map_mul' := by 

Proof state:
X✝ Y✝ : GroupCat
f : X✝ ⟶ Y✝
⊢ ∀ (x y : ↑X✝),
    OneHom.toFun { toFun := fun x => Abelianization.of (f x), map_one' := (_ : Abelianization.of (f 1) = 1) } (x * y) =
      OneHom.toFun { toFun := fun x => Abelianization.of (f x), map_one' := (_ : Abelianization.of (f 1) = 1) } x *
        OneHom.toFun { toFun := fun x => Abelianization.of (f x), map_one' := (_ : Abelianization.of (f 1) = 1) } y

Next tactic:
simp
/-- The abelianization functor `Group ⥤ CommGroup` sending a group `G` to its abelianization `Gᵃᵇ`.
 -/
def abelianize : GroupCat.{u} ⥤ CommGroupCat.{u} where
  obj G :=
    { α := Abelianization G
      str := by infer_instance }
  map f :=
    Abelianization.lift
      { toFun := fun x => Abelianization.of (f x)
        map_one' := by simp
        map_mul' := by simp }
  map_id := by
    

Proof state:
⊢ ∀ (X : GroupCat),
    { obj := fun G => Bundled.mk (Abelianization ↑G),
            map := fun {X Y} f =>
              Abelianization.lift
                {
                  toOneHom :=
                    { toFun := fun x => Abelianization.of (f x), map_one' := (_ : Abelianization.of (f 1) = 1) },
                  map_mul' :=
                    (_ :
                      ∀ (a a_1 : ↑X),
                        Abelianization.of (f (a * a_1)) = Abelianization.of (f a) * Abelianization.of (f a_1)) } }.map
        (𝟙 X) =
      𝟙
        ({ obj := fun G => Bundled.mk (Abelianization ↑G),
              map := fun {X Y} f =>
                Abelianization.lift
                  {
                    toOneHom :=
                      { toFun := fun x => Abelianization.of (f x), map_one' := (_ : Abelianization.of (f 1) = 1) },
                    map_mul' :=
                      (_ :
                        ∀ (a a_1 : ↑X),
                          Abelianization.of (f (a * a_1)) = Abelianization.of (f a) * Abelianization.of (f a_1)) } }.obj
          X)

Next tactic:
intros
/-- The abelianization functor `Group ⥤ CommGroup` sending a group `G` to its abelianization `Gᵃᵇ`.
 -/
def abelianize : GroupCat.{u} ⥤ CommGroupCat.{u} where
  obj G :=
    { α := Abelianization G
      str := by infer_instance }
  map f :=
    Abelianization.lift
      { toFun := fun x => Abelianization.of (f x)
        map_one' := by simp
        map_mul' := by simp }
  map_id := by
    intros; 

Proof state:
X✝ : GroupCat
⊢ { obj := fun G => Bundled.mk (Abelianization ↑G),
          map := fun {X Y} f =>
            Abelianization.lift
              {
                toOneHom :=
                  { toFun := fun x => Abelianization.of (f x), map_one' := (_ : Abelianization.of (f 1) = 1) },
                map_mul' :=
                  (_ :
                    ∀ (a a_1 : ↑X),
                      Abelianization.of (f (a * a_1)) = Abelianization.of (f a) * Abelianization.of (f a_1)) } }.map
      (𝟙 X✝) =
    𝟙
      ({ obj := fun G => Bundled.mk (Abelianization ↑G),
            map := fun {X Y} f =>
              Abelianization.lift
                {
                  toOneHom :=
                    { toFun := fun x => Abelianization.of (f x), map_one' := (_ : Abelianization.of (f 1) = 1) },
                  map_mul' :=
                    (_ :
                      ∀ (a a_1 : ↑X),
                        Abelianization.of (f (a * a_1)) = Abelianization.of (f a) * Abelianization.of (f a_1)) } }.obj
        X✝)

Next tactic:
simp only [MonoidHom.mk_coe, coe_id]
/-- The abelianization functor `Group ⥤ CommGroup` sending a group `G` to its abelianization `Gᵃᵇ`.
 -/
def abelianize : GroupCat.{u} ⥤ CommGroupCat.{u} where
  obj G :=
    { α := Abelianization G
      str := by infer_instance }
  map f :=
    Abelianization.lift
      { toFun := fun x => Abelianization.of (f x)
        map_one' := by simp
        map_mul' := by simp }
  map_id := by
    intros; simp only [MonoidHom.mk_coe, coe_id]
    

Proof state:
X✝ : GroupCat
⊢ Abelianization.lift
      {
        toOneHom :=
          { toFun := fun x => Abelianization.of ((𝟙 X✝) x), map_one' := (_ : Abelianization.of ((𝟙 X✝) 1) = 1) },
        map_mul' :=
          (_ :
            ∀ (a a_1 : ↑X✝),
              Abelianization.of ((𝟙 X✝) (a * a_1)) = Abelianization.of ((𝟙 X✝) a) * Abelianization.of ((𝟙 X✝) a_1)) } =
    𝟙 (Bundled.mk (Abelianization ↑X✝))

Next tactic:
apply (Equiv.apply_eq_iff_eq_symm_apply Abelianization.lift).mpr
/-- The abelianization functor `Group ⥤ CommGroup` sending a group `G` to its abelianization `Gᵃᵇ`.
 -/
def abelianize : GroupCat.{u} ⥤ CommGroupCat.{u} where
  obj G :=
    { α := Abelianization G
      str := by infer_instance }
  map f :=
    Abelianization.lift
      { toFun := fun x => Abelianization.of (f x)
        map_one' := by simp
        map_mul' := by simp }
  map_id := by
    intros; simp only [MonoidHom.mk_coe, coe_id]
    apply (Equiv.apply_eq_iff_eq_symm_apply Abelianization.lift).mpr; 

Proof state:
X✝ : GroupCat
⊢ { toOneHom := { toFun := fun x => Abelianization.of ((𝟙 X✝) x), map_one' := (_ : Abelianization.of ((𝟙 X✝) 1) = 1) },
      map_mul' :=
        (_ :
          ∀ (a a_1 : ↑X✝),
            Abelianization.of ((𝟙 X✝) (a * a_1)) = Abelianization.of ((𝟙 X✝) a) * Abelianization.of ((𝟙 X✝) a_1)) } =
    Abelianization.lift.symm (𝟙 (Bundled.mk (Abelianization ↑X✝)))

Next tactic:
rfl
/-- The abelianization functor `Group ⥤ CommGroup` sending a group `G` to its abelianization `Gᵃᵇ`.
 -/
def abelianize : GroupCat.{u} ⥤ CommGroupCat.{u} where
  obj G :=
    { α := Abelianization G
      str := by infer_instance }
  map f :=
    Abelianization.lift
      { toFun := fun x => Abelianization.of (f x)
        map_one' := by simp
        map_mul' := by simp }
  map_id := by
    intros; simp only [MonoidHom.mk_coe, coe_id]
    apply (Equiv.apply_eq_iff_eq_symm_apply Abelianization.lift).mpr; rfl
  map_comp := by
    

Proof state:
⊢ ∀ {X Y Z : GroupCat} (f : X ⟶ Y) (g : Y ⟶ Z),
    { obj := fun G => Bundled.mk (Abelianization ↑G),
            map := fun {X Y} f =>
              Abelianization.lift
                {
                  toOneHom :=
                    { toFun := fun x => Abelianization.of (f x), map_one' := (_ : Abelianization.of (f 1) = 1) },
                  map_mul' :=
                    (_ :
                      ∀ (a a_1 : ↑X),
                        Abelianization.of (f (a * a_1)) = Abelianization.of (f a) * Abelianization.of (f a_1)) } }.map
        (f ≫ g) =
      { obj := fun G => Bundled.mk (Abelianization ↑G),
              map := fun {X Y} f =>
                Abelianization.lift
                  {
                    toOneHom :=
                      { toFun := fun x => Abelianization.of (f x), map_one' := (_ : Abelianization.of (f 1) = 1) },
                    map_mul' :=
                      (_ :
                        ∀ (a a_1 : ↑X),
                          Abelianization.of (f (a * a_1)) = Abelianization.of (f a) * Abelianization.of (f a_1)) } }.map
          f ≫
        { obj := fun G => Bundled.mk (Abelianization ↑G),
              map := fun {X Y} f =>
                Abelianization.lift
                  {
                    toOneHom :=
                      { toFun := fun x => Abelianization.of (f x), map_one' := (_ : Abelianization.of (f 1) = 1) },
                    map_mul' :=
                      (_ :
                        ∀ (a a_1 : ↑X),
                          Abelianization.of (f (a * a_1)) = Abelianization.of (f a) * Abelianization.of (f a_1)) } }.map
          g

Next tactic:
intros
/-- The abelianization functor `Group ⥤ CommGroup` sending a group `G` to its abelianization `Gᵃᵇ`.
 -/
def abelianize : GroupCat.{u} ⥤ CommGroupCat.{u} where
  obj G :=
    { α := Abelianization G
      str := by infer_instance }
  map f :=
    Abelianization.lift
      { toFun := fun x => Abelianization.of (f x)
        map_one' := by simp
        map_mul' := by simp }
  map_id := by
    intros; simp only [MonoidHom.mk_coe, coe_id]
    apply (Equiv.apply_eq_iff_eq_symm_apply Abelianization.lift).mpr; rfl
  map_comp := by
    intros; 

Proof state:
X✝ Y✝ Z✝ : GroupCat
f✝ : X✝ ⟶ Y✝
g✝ : Y✝ ⟶ Z✝
⊢ { obj := fun G => Bundled.mk (Abelianization ↑G),
          map := fun {X Y} f =>
            Abelianization.lift
              {
                toOneHom :=
                  { toFun := fun x => Abelianization.of (f x), map_one' := (_ : Abelianization.of (f 1) = 1) },
                map_mul' :=
                  (_ :
                    ∀ (a a_1 : ↑X),
                      Abelianization.of (f (a * a_1)) = Abelianization.of (f a) * Abelianization.of (f a_1)) } }.map
      (f✝ ≫ g✝) =
    { obj := fun G => Bundled.mk (Abelianization ↑G),
            map := fun {X Y} f =>
              Abelianization.lift
                {
                  toOneHom :=
                    { toFun := fun x => Abelianization.of (f x), map_one' := (_ : Abelianization.of (f 1) = 1) },
                  map_mul' :=
                    (_ :
                      ∀ (a a_1 : ↑X),
                        Abelianization.of (f (a * a_1)) = Abelianization.of (f a) * Abelianization.of (f a_1)) } }.map
        f✝ ≫
      { obj := fun G => Bundled.mk (Abelianization ↑G),
            map := fun {X Y} f =>
              Abelianization.lift
                {
                  toOneHom :=
                    { toFun := fun x => Abelianization.of (f x), map_one' := (_ : Abelianization.of (f 1) = 1) },
                  map_mul' :=
                    (_ :
                      ∀ (a a_1 : ↑X),
                        Abelianization.of (f (a * a_1)) = Abelianization.of (f a) * Abelianization.of (f a_1)) } }.map
        g✝

Next tactic:
simp only [coe_comp]
/-- The abelianization functor `Group ⥤ CommGroup` sending a group `G` to its abelianization `Gᵃᵇ`.
 -/
def abelianize : GroupCat.{u} ⥤ CommGroupCat.{u} where
  obj G :=
    { α := Abelianization G
      str := by infer_instance }
  map f :=
    Abelianization.lift
      { toFun := fun x => Abelianization.of (f x)
        map_one' := by simp
        map_mul' := by simp }
  map_id := by
    intros; simp only [MonoidHom.mk_coe, coe_id]
    apply (Equiv.apply_eq_iff_eq_symm_apply Abelianization.lift).mpr; rfl
  map_comp := by
    intros; simp only [coe_comp];
    

Proof state:
X✝ Y✝ Z✝ : GroupCat
f✝ : X✝ ⟶ Y✝
g✝ : Y✝ ⟶ Z✝
⊢ Abelianization.lift
      {
        toOneHom :=
          { toFun := fun x => Abelianization.of ((f✝ ≫ g✝) x), map_one' := (_ : Abelianization.of ((f✝ ≫ g✝) 1) = 1) },
        map_mul' :=
          (_ :
            ∀ (a a_1 : ↑X✝),
              Abelianization.of ((f✝ ≫ g✝) (a * a_1)) =
                Abelianization.of ((f✝ ≫ g✝) a) * Abelianization.of ((f✝ ≫ g✝) a_1)) } =
    Abelianization.lift
        { toOneHom := { toFun := fun x => Abelianization.of (f✝ x), map_one' := (_ : Abelianization.of (f✝ 1) = 1) },
          map_mul' :=
            (_ :
              ∀ (a a_1 : ↑X✝),
                Abelianization.of (f✝ (a * a_1)) = Abelianization.of (f✝ a) * Abelianization.of (f✝ a_1)) } ≫
      Abelianization.lift
        { toOneHom := { toFun := fun x => Abelianization.of (g✝ x), map_one' := (_ : Abelianization.of (g✝ 1) = 1) },
          map_mul' :=
            (_ :
              ∀ (a a_1 : ↑Y✝),
                Abelianization.of (g✝ (a * a_1)) = Abelianization.of (g✝ a) * Abelianization.of (g✝ a_1)) }

Next tactic:
apply (Equiv.apply_eq_iff_eq_symm_apply Abelianization.lift).mpr
/-- The abelianization functor `Group ⥤ CommGroup` sending a group `G` to its abelianization `Gᵃᵇ`.
 -/
def abelianize : GroupCat.{u} ⥤ CommGroupCat.{u} where
  obj G :=
    { α := Abelianization G
      str := by infer_instance }
  map f :=
    Abelianization.lift
      { toFun := fun x => Abelianization.of (f x)
        map_one' := by simp
        map_mul' := by simp }
  map_id := by
    intros; simp only [MonoidHom.mk_coe, coe_id]
    apply (Equiv.apply_eq_iff_eq_symm_apply Abelianization.lift).mpr; rfl
  map_comp := by
    intros; simp only [coe_comp];
    apply (Equiv.apply_eq_iff_eq_symm_apply Abelianization.lift).mpr; 

Proof state:
X✝ Y✝ Z✝ : GroupCat
f✝ : X✝ ⟶ Y✝
g✝ : Y✝ ⟶ Z✝
⊢ {
      toOneHom :=
        { toFun := fun x => Abelianization.of ((f✝ ≫ g✝) x), map_one' := (_ : Abelianization.of ((f✝ ≫ g✝) 1) = 1) },
      map_mul' :=
        (_ :
          ∀ (a a_1 : ↑X✝),
            Abelianization.of ((f✝ ≫ g✝) (a * a_1)) =
              Abelianization.of ((f✝ ≫ g✝) a) * Abelianization.of ((f✝ ≫ g✝) a_1)) } =
    Abelianization.lift.symm
      (Abelianization.lift
          { toOneHom := { toFun := fun x => Abelianization.of (f✝ x), map_one' := (_ : Abelianization.of (f✝ 1) = 1) },
            map_mul' :=
              (_ :
                ∀ (a a_1 : ↑X✝),
                  Abelianization.of (f✝ (a * a_1)) = Abelianization.of (f✝ a) * Abelianization.of (f✝ a_1)) } ≫
        Abelianization.lift
          { toOneHom := { toFun := fun x => Abelianization.of (g✝ x), map_one' := (_ : Abelianization.of (g✝ 1) = 1) },
            map_mul' :=
              (_ :
                ∀ (a a_1 : ↑Y✝),
                  Abelianization.of (g✝ (a * a_1)) = Abelianization.of (g✝ a) * Abelianization.of (g✝ a_1)) })

Next tactic:
rfl
/-- The abelianization-forgetful adjuction from `Group` to `CommGroup`.-/
def abelianizeAdj : abelianize ⊣ forget₂ CommGroupCat.{u} GroupCat.{u} :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun G A => Abelianization.lift.symm
      -- Porting note: used to be just `by intros; ext1; rfl`.
      homEquiv_naturality_left_symm := by
        

Proof state:
⊢ ∀ {X' X : GroupCat} {Y : CommGroupCat} (f : X' ⟶ X) (g : X ⟶ (forget₂ CommGroupCat GroupCat).obj Y),
    ((fun G A => Abelianization.lift.symm) X' Y).symm (f ≫ g) =
      abelianize.map f ≫ ((fun G A => Abelianization.lift.symm) X Y).symm g

Next tactic:
intros
/-- The abelianization-forgetful adjuction from `Group` to `CommGroup`.-/
def abelianizeAdj : abelianize ⊣ forget₂ CommGroupCat.{u} GroupCat.{u} :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun G A => Abelianization.lift.symm
      -- Porting note: used to be just `by intros; ext1; rfl`.
      homEquiv_naturality_left_symm := by
        intros
        

Proof state:
X'✝ X✝ : GroupCat
Y✝ : CommGroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget₂ CommGroupCat GroupCat).obj Y✝
⊢ ((fun G A => Abelianization.lift.symm) X'✝ Y✝).symm (f✝ ≫ g✝) =
    abelianize.map f✝ ≫ ((fun G A => Abelianization.lift.symm) X✝ Y✝).symm g✝

Next tactic:
ext1
/-- The abelianization-forgetful adjuction from `Group` to `CommGroup`.-/
def abelianizeAdj : abelianize ⊣ forget₂ CommGroupCat.{u} GroupCat.{u} :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun G A => Abelianization.lift.symm
      -- Porting note: used to be just `by intros; ext1; rfl`.
      homEquiv_naturality_left_symm := by
        intros
        ext1
        

Proof state:
case w
X'✝ X✝ : GroupCat
Y✝ : CommGroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget₂ CommGroupCat GroupCat).obj Y✝
x✝ : ↑(abelianize.obj X'✝)
⊢ (((fun G A => Abelianization.lift.symm) X'✝ Y✝).symm (f✝ ≫ g✝)) x✝ =
    (abelianize.map f✝ ≫ ((fun G A => Abelianization.lift.symm) X✝ Y✝).symm g✝) x✝

Next tactic:
simp only [Equiv.symm_symm]
/-- The abelianization-forgetful adjuction from `Group` to `CommGroup`.-/
def abelianizeAdj : abelianize ⊣ forget₂ CommGroupCat.{u} GroupCat.{u} :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun G A => Abelianization.lift.symm
      -- Porting note: used to be just `by intros; ext1; rfl`.
      homEquiv_naturality_left_symm := by
        intros
        ext1
        simp only [Equiv.symm_symm]
        

Proof state:
case w
X'✝ X✝ : GroupCat
Y✝ : CommGroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget₂ CommGroupCat GroupCat).obj Y✝
x✝ : ↑(abelianize.obj X'✝)
⊢ (Abelianization.lift (f✝ ≫ g✝)) x✝ = (abelianize.map f✝ ≫ Abelianization.lift g✝) x✝

Next tactic:
apply Eq.symm
/-- The abelianization-forgetful adjuction from `Group` to `CommGroup`.-/
def abelianizeAdj : abelianize ⊣ forget₂ CommGroupCat.{u} GroupCat.{u} :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun G A => Abelianization.lift.symm
      -- Porting note: used to be just `by intros; ext1; rfl`.
      homEquiv_naturality_left_symm := by
        intros
        ext1
        simp only [Equiv.symm_symm]
        apply Eq.symm
        

Proof state:
case w.h
X'✝ X✝ : GroupCat
Y✝ : CommGroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget₂ CommGroupCat GroupCat).obj Y✝
x✝ : ↑(abelianize.obj X'✝)
⊢ (abelianize.map f✝ ≫ Abelianization.lift g✝) x✝ = (Abelianization.lift (f✝ ≫ g✝)) x✝

Next tactic:
apply Abelianization.lift.unique
/-- The abelianization-forgetful adjuction from `Group` to `CommGroup`.-/
def abelianizeAdj : abelianize ⊣ forget₂ CommGroupCat.{u} GroupCat.{u} :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun G A => Abelianization.lift.symm
      -- Porting note: used to be just `by intros; ext1; rfl`.
      homEquiv_naturality_left_symm := by
        intros
        ext1
        simp only [Equiv.symm_symm]
        apply Eq.symm
        apply Abelianization.lift.unique
        

Proof state:
case w.h.hφ
X'✝ X✝ : GroupCat
Y✝ : CommGroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget₂ CommGroupCat GroupCat).obj Y✝
x✝ : ↑(abelianize.obj X'✝)
⊢ ∀ (x : ↑X'✝), (abelianize.map f✝ ≫ Abelianization.lift g✝) (Abelianization.of x) = (f✝ ≫ g✝) x

Next tactic:
intros
/-- The abelianization-forgetful adjuction from `Group` to `CommGroup`.-/
def abelianizeAdj : abelianize ⊣ forget₂ CommGroupCat.{u} GroupCat.{u} :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun G A => Abelianization.lift.symm
      -- Porting note: used to be just `by intros; ext1; rfl`.
      homEquiv_naturality_left_symm := by
        intros
        ext1
        simp only [Equiv.symm_symm]
        apply Eq.symm
        apply Abelianization.lift.unique
        intros
        

Proof state:
case w.h.hφ
X'✝ X✝ : GroupCat
Y✝ : CommGroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget₂ CommGroupCat GroupCat).obj Y✝
x✝¹ : ↑(abelianize.obj X'✝)
x✝ : ↑X'✝
⊢ (abelianize.map f✝ ≫ Abelianization.lift g✝) (Abelianization.of x✝) = (f✝ ≫ g✝) x✝

Next tactic:
apply Abelianization.lift.of
/-- The forgetful-units adjunction between `Group` and `Mon`. -/
def GroupCat.forget₂MonAdj : forget₂ GroupCat MonCat ⊣ MonCat.units.{u} where
  homEquiv X Y :=
    { toFun := fun f => MonoidHom.toHomUnits f
      invFun := fun f => (Units.coeHom Y).comp f
      left_inv := fun f => MonoidHom.ext fun _ => rfl
      right_inv := fun f => MonoidHom.ext fun _ => Units.ext rfl }
  unit :=
    { app := fun X => { (@toUnits X _).toMonoidHom with }
      naturality := fun X Y f => MonoidHom.ext fun x => Units.ext rfl }
  counit :=
    { app := fun X => Units.coeHom X
      naturality := by 

Proof state:
⊢ ∀ ⦃X Y : MonCat⦄ (f : X ⟶ Y),
    (MonCat.units ⋙ forget₂ GroupCat MonCat).map f ≫ (fun X => Units.coeHom ↑X) Y =
      (fun X => Units.coeHom ↑X) X ≫ (𝟭 MonCat).map f

Next tactic:
intros
/-- The forgetful-units adjunction between `Group` and `Mon`. -/
def GroupCat.forget₂MonAdj : forget₂ GroupCat MonCat ⊣ MonCat.units.{u} where
  homEquiv X Y :=
    { toFun := fun f => MonoidHom.toHomUnits f
      invFun := fun f => (Units.coeHom Y).comp f
      left_inv := fun f => MonoidHom.ext fun _ => rfl
      right_inv := fun f => MonoidHom.ext fun _ => Units.ext rfl }
  unit :=
    { app := fun X => { (@toUnits X _).toMonoidHom with }
      naturality := fun X Y f => MonoidHom.ext fun x => Units.ext rfl }
  counit :=
    { app := fun X => Units.coeHom X
      naturality := by intros; 

Proof state:
X✝ Y✝ : MonCat
f✝ : X✝ ⟶ Y✝
⊢ (MonCat.units ⋙ forget₂ GroupCat MonCat).map f✝ ≫ (fun X => Units.coeHom ↑X) Y✝ =
    (fun X => Units.coeHom ↑X) X✝ ≫ (𝟭 MonCat).map f✝

Next tactic:
exact MonoidHom.ext fun x => rfl