l3lab/ntp-mathlib huggingface dataset:
/-- The Kleisli category on a monad `T`.
    cf Definition 5.2.9 in [Riehl][riehl2017]. -/
instance Kleisli.category : Category (Kleisli T) where
  Hom := fun X Y : C => X ⟶ (T : C ⥤ C).obj Y
  id X := T.η.app X
  comp {X} {Y} {Z} f g := f ≫ (T : C ⥤ C).map g ≫ T.μ.app Z
  id_comp {X} {Y} f := by
    dsimp -- Porting note: unfold comp
    rw [← T.η.naturality_assoc f, T.left_unit]
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
T : Monad C
X Y : Kleisli T
f : X ⟶ Y
⊢ (𝟭 C).map f ≫ 𝟙 (T.obj Y) = f

Next tactic:
apply Category.comp_id
/-- The Kleisli category on a monad `T`.
    cf Definition 5.2.9 in [Riehl][riehl2017]. -/
instance Kleisli.category : Category (Kleisli T) where
  Hom := fun X Y : C => X ⟶ (T : C ⥤ C).obj Y
  id X := T.η.app X
  comp {X} {Y} {Z} f g := f ≫ (T : C ⥤ C).map g ≫ T.μ.app Z
  id_comp {X} {Y} f := by
    dsimp -- Porting note: unfold comp
    rw [← T.η.naturality_assoc f, T.left_unit]
    apply Category.comp_id
  assoc f g h := by
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
T : Monad C
W✝ X✝ Y✝ Z✝ : Kleisli T
f : W✝ ⟶ X✝
g : X✝ ⟶ Y✝
h : Y✝ ⟶ Z✝
⊢ (f ≫ g) ≫ h = f ≫ g ≫ h

Next tactic:
simp only [Functor.map_comp, Category.assoc, Monad.assoc]
/-- The Kleisli category on a monad `T`.
    cf Definition 5.2.9 in [Riehl][riehl2017]. -/
instance Kleisli.category : Category (Kleisli T) where
  Hom := fun X Y : C => X ⟶ (T : C ⥤ C).obj Y
  id X := T.η.app X
  comp {X} {Y} {Z} f g := f ≫ (T : C ⥤ C).map g ≫ T.μ.app Z
  id_comp {X} {Y} f := by
    dsimp -- Porting note: unfold comp
    rw [← T.η.naturality_assoc f, T.left_unit]
    apply Category.comp_id
  assoc f g h := by
    simp only [Functor.map_comp, Category.assoc, Monad.assoc]
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
T : Monad C
W✝ X✝ Y✝ Z✝ : Kleisli T
f : W✝ ⟶ X✝
g : X✝ ⟶ Y✝
h : Y✝ ⟶ Z✝
⊢ f ≫ T.map g ≫ (Monad.μ T).app Y✝ ≫ T.map h ≫ (Monad.μ T).app Z✝ =
    f ≫ T.map g ≫ T.map (T.map h) ≫ (Monad.μ T).app (T.obj Z✝) ≫ (Monad.μ T).app Z✝

Next tactic:
erw [T.μ.naturality_assoc]
/-- The left adjoint of the adjunction which induces the monad `(T, η_ T, μ_ T)`. -/
@[simps]
def toKleisli : C ⥤ Kleisli T where
  obj X := (X : Kleisli T)
  map {X} {Y} f := (f ≫ T.η.app Y : X ⟶ T.obj Y)
  map_comp {X} {Y} {Z} f g := by
    -- Porting note: hack for missing unfold_projs tactic
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
T : Monad C
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
⊢ { obj := fun X => X, map := fun {X Y} f => f ≫ (Monad.η T).app Y }.map (f ≫ g) =
    { obj := fun X => X, map := fun {X Y} f => f ≫ (Monad.η T).app Y }.map f ≫
      { obj := fun X => X, map := fun {X Y} f => f ≫ (Monad.η T).app Y }.map g

Next tactic:
change _ = (f ≫ (Monad.η T).app Y) ≫ T.map (g ≫ (Monad.η T).app Z) ≫ T.μ.app Z
/-- The left adjoint of the adjunction which induces the monad `(T, η_ T, μ_ T)`. -/
@[simps]
def toKleisli : C ⥤ Kleisli T where
  obj X := (X : Kleisli T)
  map {X} {Y} f := (f ≫ T.η.app Y : X ⟶ T.obj Y)
  map_comp {X} {Y} {Z} f g := by
    -- Porting note: hack for missing unfold_projs tactic
    change _ = (f ≫ (Monad.η T).app Y) ≫ T.map (g ≫ (Monad.η T).app Z) ≫ T.μ.app Z
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
T : Monad C
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
⊢ { obj := fun X => X, map := fun {X Y} f => f ≫ (Monad.η T).app Y }.map (f ≫ g) =
    (f ≫ (Monad.η T).app Y) ≫ T.map (g ≫ (Monad.η T).app Z) ≫ (Monad.μ T).app Z

Next tactic:
simp [← T.η.naturality g]
/-- The right adjoint of the adjunction which induces the monad `(T, η_ T, μ_ T)`. -/
@[simps]
def fromKleisli : Kleisli T ⥤ C where
  obj X := T.obj X
  map {_} {Y} f := T.map f ≫ T.μ.app Y
  map_id X := T.right_unit _
  map_comp {X} {Y} {Z} f g := by
    -- Porting note: hack for missing unfold_projs tactic
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
T : Monad C
X Y Z : Kleisli T
f : X ⟶ Y
g : Y ⟶ Z
⊢ { obj := fun X => T.obj X, map := fun {x Y} f => T.map f ≫ (Monad.μ T).app Y }.map (f ≫ g) =
    { obj := fun X => T.obj X, map := fun {x Y} f => T.map f ≫ (Monad.μ T).app Y }.map f ≫
      { obj := fun X => T.obj X, map := fun {x Y} f => T.map f ≫ (Monad.μ T).app Y }.map g

Next tactic:
change T.map (f ≫ T.map g ≫ T.μ.app Z) ≫ T.μ.app Z = _
/-- The right adjoint of the adjunction which induces the monad `(T, η_ T, μ_ T)`. -/
@[simps]
def fromKleisli : Kleisli T ⥤ C where
  obj X := T.obj X
  map {_} {Y} f := T.map f ≫ T.μ.app Y
  map_id X := T.right_unit _
  map_comp {X} {Y} {Z} f g := by
    -- Porting note: hack for missing unfold_projs tactic
    change T.map (f ≫ T.map g ≫ T.μ.app Z) ≫ T.μ.app Z = _
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
T : Monad C
X Y Z : Kleisli T
f : X ⟶ Y
g : Y ⟶ Z
⊢ T.map (f ≫ T.map g ≫ (Monad.μ T).app Z) ≫ (Monad.μ T).app Z =
    { obj := fun X => T.obj X, map := fun {x Y} f => T.map f ≫ (Monad.μ T).app Y }.map f ≫
      { obj := fun X => T.obj X, map := fun {x Y} f => T.map f ≫ (Monad.μ T).app Y }.map g

Next tactic:
simp only [Functor.map_comp, Category.assoc]
/-- The right adjoint of the adjunction which induces the monad `(T, η_ T, μ_ T)`. -/
@[simps]
def fromKleisli : Kleisli T ⥤ C where
  obj X := T.obj X
  map {_} {Y} f := T.map f ≫ T.μ.app Y
  map_id X := T.right_unit _
  map_comp {X} {Y} {Z} f g := by
    -- Porting note: hack for missing unfold_projs tactic
    change T.map (f ≫ T.map g ≫ T.μ.app Z) ≫ T.μ.app Z = _
    simp only [Functor.map_comp, Category.assoc]
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
T : Monad C
X Y Z : Kleisli T
f : X ⟶ Y
g : Y ⟶ Z
⊢ T.map f ≫ T.map (T.map g) ≫ T.map ((Monad.μ T).app Z) ≫ (Monad.μ T).app Z =
    T.map f ≫ (Monad.μ T).app Y ≫ T.map g ≫ (Monad.μ T).app Z

Next tactic:
erw [← T.μ.naturality_assoc g, T.assoc]
/-- The right adjoint of the adjunction which induces the monad `(T, η_ T, μ_ T)`. -/
@[simps]
def fromKleisli : Kleisli T ⥤ C where
  obj X := T.obj X
  map {_} {Y} f := T.map f ≫ T.μ.app Y
  map_id X := T.right_unit _
  map_comp {X} {Y} {Z} f g := by
    -- Porting note: hack for missing unfold_projs tactic
    change T.map (f ≫ T.map g ≫ T.μ.app Z) ≫ T.μ.app Z = _
    simp only [Functor.map_comp, Category.assoc]
    erw [← T.μ.naturality_assoc g, T.assoc]
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
T : Monad C
X Y Z : Kleisli T
f : X ⟶ Y
g : Y ⟶ Z
⊢ T.map f ≫ T.map (T.map g) ≫ (Monad.μ T).app (T.obj Z) ≫ (Monad.μ T).app Z =
    T.map f ≫ (T.toFunctor ⋙ T.toFunctor).map g ≫ (Monad.μ T).app (T.obj Z) ≫ (Monad.μ T).app Z

Next tactic:
rfl
/-- The Kleisli adjunction which gives rise to the monad `(T, η_ T, μ_ T)`.
    cf Lemma 5.2.11 of [Riehl][riehl2017]. -/
def adj : toKleisli T ⊣ fromKleisli T :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y => Equiv.refl (X ⟶ T.obj Y)
      homEquiv_naturality_left_symm := fun {X} {Y} {Z} f g => by
        -- Porting note: used to be unfold_projs; dsimp
        

Proof state:
C : Type u
inst✝ : Category.{v, u} C
T : Monad C
X Y : C
Z : Kleisli T
f : X ⟶ Y
g : Y ⟶ (fromKleisli T).obj Z
⊢ ((fun X Y => Equiv.refl (X ⟶ T.obj Y)) X Z).symm (f ≫ g) =
    (toKleisli T).map f ≫ ((fun X Y => Equiv.refl (X ⟶ T.obj Y)) Y Z).symm g

Next tactic:
change f ≫ g = (f ≫ T.η.app Y) ≫ T.map g ≫ T.μ.app Z
/-- The Kleisli adjunction which gives rise to the monad `(T, η_ T, μ_ T)`.
    cf Lemma 5.2.11 of [Riehl][riehl2017]. -/
def adj : toKleisli T ⊣ fromKleisli T :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y => Equiv.refl (X ⟶ T.obj Y)
      homEquiv_naturality_left_symm := fun {X} {Y} {Z} f g => by
        -- Porting note: used to be unfold_projs; dsimp
        change f ≫ g = (f ≫ T.η.app Y) ≫ T.map g ≫ T.μ.app Z
        

Proof state:
C : Type u
inst✝ : Category.{v, u} C
T : Monad C
X Y : C
Z : Kleisli T
f : X ⟶ Y
g : Y ⟶ (fromKleisli T).obj Z
⊢ f ≫ g = (f ≫ (Monad.η T).app Y) ≫ T.map g ≫ (Monad.μ T).app Z

Next tactic:
rw [Category.assoc, ← T.η.naturality_assoc g, Functor.id_map]
/-- The Kleisli adjunction which gives rise to the monad `(T, η_ T, μ_ T)`.
    cf Lemma 5.2.11 of [Riehl][riehl2017]. -/
def adj : toKleisli T ⊣ fromKleisli T :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y => Equiv.refl (X ⟶ T.obj Y)
      homEquiv_naturality_left_symm := fun {X} {Y} {Z} f g => by
        -- Porting note: used to be unfold_projs; dsimp
        change f ≫ g = (f ≫ T.η.app Y) ≫ T.map g ≫ T.μ.app Z
        rw [Category.assoc, ← T.η.naturality_assoc g, Functor.id_map]
        

Proof state:
C : Type u
inst✝ : Category.{v, u} C
T : Monad C
X Y : C
Z : Kleisli T
f : X ⟶ Y
g : Y ⟶ (fromKleisli T).obj Z
⊢ f ≫ g = f ≫ g ≫ (Monad.η T).app ((fromKleisli T).obj Z) ≫ (Monad.μ T).app Z

Next tactic:
dsimp
/-- The Kleisli adjunction which gives rise to the monad `(T, η_ T, μ_ T)`.
    cf Lemma 5.2.11 of [Riehl][riehl2017]. -/
def adj : toKleisli T ⊣ fromKleisli T :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y => Equiv.refl (X ⟶ T.obj Y)
      homEquiv_naturality_left_symm := fun {X} {Y} {Z} f g => by
        -- Porting note: used to be unfold_projs; dsimp
        change f ≫ g = (f ≫ T.η.app Y) ≫ T.map g ≫ T.μ.app Z
        rw [Category.assoc, ← T.η.naturality_assoc g, Functor.id_map]
        dsimp
        

Proof state:
C : Type u
inst✝ : Category.{v, u} C
T : Monad C
X Y : C
Z : Kleisli T
f : X ⟶ Y
g : Y ⟶ (fromKleisli T).obj Z
⊢ f ≫ g = f ≫ g ≫ (Monad.η T).app (T.obj Z) ≫ (Monad.μ T).app Z

Next tactic:
simp [Monad.left_unit]
/-- The co-Kleisli category on a comonad `U`.-/
instance Cokleisli.category : Category (Cokleisli U) where
  Hom := fun X Y : C => (U : C ⥤ C).obj X ⟶ Y
  id X := U.ε.app X
  comp {X} {Y} {Z} f g := U.δ.app X ≫ (U : C ⥤ C).map f ≫ g
  id_comp f := by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
U : Comonad C
X✝ Y✝ : Cokleisli U
f : X✝ ⟶ Y✝
⊢ 𝟙 X✝ ≫ f = f

Next tactic:
dsimp
/-- The co-Kleisli category on a comonad `U`.-/
instance Cokleisli.category : Category (Cokleisli U) where
  Hom := fun X Y : C => (U : C ⥤ C).obj X ⟶ Y
  id X := U.ε.app X
  comp {X} {Y} {Z} f g := U.δ.app X ≫ (U : C ⥤ C).map f ≫ g
  id_comp f := by dsimp; 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
U : Comonad C
X✝ Y✝ : Cokleisli U
f : X✝ ⟶ Y✝
⊢ (Comonad.δ U).app X✝ ≫ U.map ((Comonad.ε U).app X✝) ≫ f = f

Next tactic:
rw [U.right_counit_assoc]
/-- The co-Kleisli category on a comonad `U`.-/
instance Cokleisli.category : Category (Cokleisli U) where
  Hom := fun X Y : C => (U : C ⥤ C).obj X ⟶ Y
  id X := U.ε.app X
  comp {X} {Y} {Z} f g := U.δ.app X ≫ (U : C ⥤ C).map f ≫ g
  id_comp f := by dsimp; rw [U.right_counit_assoc]
  assoc {X} {Y} {Z} {W} f g h := by
    -- Porting note: working around lack of unfold_projs
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
U : Comonad C
X Y Z W : Cokleisli U
f : X ⟶ Y
g : Y ⟶ Z
h : Z ⟶ W
⊢ (f ≫ g) ≫ h = f ≫ g ≫ h

Next tactic:
change U.δ.app X ≫ U.map (U.δ.app X ≫ U.map f ≫ g) ≫ h =
      U.δ.app X ≫ U.map f ≫ (U.δ.app Y ≫ U.map g ≫ h)
/-- The co-Kleisli category on a comonad `U`.-/
instance Cokleisli.category : Category (Cokleisli U) where
  Hom := fun X Y : C => (U : C ⥤ C).obj X ⟶ Y
  id X := U.ε.app X
  comp {X} {Y} {Z} f g := U.δ.app X ≫ (U : C ⥤ C).map f ≫ g
  id_comp f := by dsimp; rw [U.right_counit_assoc]
  assoc {X} {Y} {Z} {W} f g h := by
    -- Porting note: working around lack of unfold_projs
    change U.δ.app X ≫ U.map (U.δ.app X ≫ U.map f ≫ g) ≫ h =
      U.δ.app X ≫ U.map f ≫ (U.δ.app Y ≫ U.map g ≫ h)
    -- Porting note: something was broken here and was easier just to redo from scratch
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
U : Comonad C
X Y Z W : Cokleisli U
f : X ⟶ Y
g : Y ⟶ Z
h : Z ⟶ W
⊢ (Comonad.δ U).app X ≫ U.map ((Comonad.δ U).app X ≫ U.map f ≫ g) ≫ h =
    (Comonad.δ U).app X ≫ U.map f ≫ (Comonad.δ U).app Y ≫ U.map g ≫ h

Next tactic:
simp only [Functor.map_comp, ← Category.assoc, eq_whisker]
/-- The co-Kleisli category on a comonad `U`.-/
instance Cokleisli.category : Category (Cokleisli U) where
  Hom := fun X Y : C => (U : C ⥤ C).obj X ⟶ Y
  id X := U.ε.app X
  comp {X} {Y} {Z} f g := U.δ.app X ≫ (U : C ⥤ C).map f ≫ g
  id_comp f := by dsimp; rw [U.right_counit_assoc]
  assoc {X} {Y} {Z} {W} f g h := by
    -- Porting note: working around lack of unfold_projs
    change U.δ.app X ≫ U.map (U.δ.app X ≫ U.map f ≫ g) ≫ h =
      U.δ.app X ≫ U.map f ≫ (U.δ.app Y ≫ U.map g ≫ h)
    -- Porting note: something was broken here and was easier just to redo from scratch
    simp only [Functor.map_comp, ← Category.assoc, eq_whisker]
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
U : Comonad C
X Y Z W : Cokleisli U
f : X ⟶ Y
g : Y ⟶ Z
h : Z ⟶ W
⊢ ((((Comonad.δ U).app X ≫ U.map ((Comonad.δ U).app X)) ≫ U.map (U.map f)) ≫ U.map g) ≫ h =
    ((((Comonad.δ U).app X ≫ U.map f) ≫ (Comonad.δ U).app Y) ≫ U.map g) ≫ h

Next tactic:
simp only [Category.assoc, U.δ.naturality, Functor.comp_map, U.coassoc_assoc]
/-- The right adjoint of the adjunction which induces the comonad `(U, ε_ U, δ_ U)`. -/
@[simps]
def toCokleisli : C ⥤ Cokleisli U where
  obj X := (X : Cokleisli U)
  map {X} {_} f := (U.ε.app X ≫ f : _)
  map_comp {X} {Y} {_} f g := by
    -- Porting note: working around lack of unfold_projs
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
U : Comonad C
X Y x✝ : C
f : X ⟶ Y
g : Y ⟶ x✝
⊢ { obj := fun X => X, map := fun {X x} f => (Comonad.ε U).app X ≫ f }.map (f ≫ g) =
    { obj := fun X => X, map := fun {X x} f => (Comonad.ε U).app X ≫ f }.map f ≫
      { obj := fun X => X, map := fun {X x} f => (Comonad.ε U).app X ≫ f }.map g

Next tactic:
change U.ε.app X ≫ f ≫ g = U.δ.app X ≫ U.map (U.ε.app X ≫ f) ≫ U.ε.app Y ≫ g
/-- The right adjoint of the adjunction which induces the comonad `(U, ε_ U, δ_ U)`. -/
@[simps]
def toCokleisli : C ⥤ Cokleisli U where
  obj X := (X : Cokleisli U)
  map {X} {_} f := (U.ε.app X ≫ f : _)
  map_comp {X} {Y} {_} f g := by
    -- Porting note: working around lack of unfold_projs
    change U.ε.app X ≫ f ≫ g = U.δ.app X ≫ U.map (U.ε.app X ≫ f) ≫ U.ε.app Y ≫ g
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
U : Comonad C
X Y x✝ : C
f : X ⟶ Y
g : Y ⟶ x✝
⊢ (Comonad.ε U).app X ≫ f ≫ g = (Comonad.δ U).app X ≫ U.map ((Comonad.ε U).app X ≫ f) ≫ (Comonad.ε U).app Y ≫ g

Next tactic:
simp [← U.ε.naturality g]
/-- The left adjoint of the adjunction which induces the comonad `(U, ε_ U, δ_ U)`. -/
@[simps]
def fromCokleisli : Cokleisli U ⥤ C where
  obj X := U.obj X
  map {X} {_} f := U.δ.app X ≫ U.map f
  map_id X := U.right_counit _
  map_comp {X} {Y} {_} f g := by
    -- Porting note: working around lack of unfold_projs
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
U : Comonad C
X Y x✝ : Cokleisli U
f : X ⟶ Y
g : Y ⟶ x✝
⊢ { obj := fun X => U.obj X, map := fun {X x} f => (Comonad.δ U).app X ≫ U.map f }.map (f ≫ g) =
    { obj := fun X => U.obj X, map := fun {X x} f => (Comonad.δ U).app X ≫ U.map f }.map f ≫
      { obj := fun X => U.obj X, map := fun {X x} f => (Comonad.δ U).app X ≫ U.map f }.map g

Next tactic:
change U.δ.app X ≫ U.map (U.δ.app X ≫ U.map f ≫ g) =
      (U.δ.app X ≫ U.map f) ≫ (U.δ.app Y ≫ U.map g)
/-- The left adjoint of the adjunction which induces the comonad `(U, ε_ U, δ_ U)`. -/
@[simps]
def fromCokleisli : Cokleisli U ⥤ C where
  obj X := U.obj X
  map {X} {_} f := U.δ.app X ≫ U.map f
  map_id X := U.right_counit _
  map_comp {X} {Y} {_} f g := by
    -- Porting note: working around lack of unfold_projs
    change U.δ.app X ≫ U.map (U.δ.app X ≫ U.map f ≫ g) =
      (U.δ.app X ≫ U.map f) ≫ (U.δ.app Y ≫ U.map g)
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
U : Comonad C
X Y x✝ : Cokleisli U
f : X ⟶ Y
g : Y ⟶ x✝
⊢ (Comonad.δ U).app X ≫ U.map ((Comonad.δ U).app X ≫ U.map f ≫ g) =
    ((Comonad.δ U).app X ≫ U.map f) ≫ (Comonad.δ U).app Y ≫ U.map g

Next tactic:
simp only [Functor.map_comp, ← Category.assoc]
/-- The left adjoint of the adjunction which induces the comonad `(U, ε_ U, δ_ U)`. -/
@[simps]
def fromCokleisli : Cokleisli U ⥤ C where
  obj X := U.obj X
  map {X} {_} f := U.δ.app X ≫ U.map f
  map_id X := U.right_counit _
  map_comp {X} {Y} {_} f g := by
    -- Porting note: working around lack of unfold_projs
    change U.δ.app X ≫ U.map (U.δ.app X ≫ U.map f ≫ g) =
      (U.δ.app X ≫ U.map f) ≫ (U.δ.app Y ≫ U.map g)
    simp only [Functor.map_comp, ← Category.assoc]
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
U : Comonad C
X Y x✝ : Cokleisli U
f : X ⟶ Y
g : Y ⟶ x✝
⊢ (((Comonad.δ U).app X ≫ U.map ((Comonad.δ U).app X)) ≫ U.map (U.map f)) ≫ U.map g =
    (((Comonad.δ U).app X ≫ U.map f) ≫ (Comonad.δ U).app Y) ≫ U.map g

Next tactic:
rw [Comonad.coassoc]
/-- The left adjoint of the adjunction which induces the comonad `(U, ε_ U, δ_ U)`. -/
@[simps]
def fromCokleisli : Cokleisli U ⥤ C where
  obj X := U.obj X
  map {X} {_} f := U.δ.app X ≫ U.map f
  map_id X := U.right_counit _
  map_comp {X} {Y} {_} f g := by
    -- Porting note: working around lack of unfold_projs
    change U.δ.app X ≫ U.map (U.δ.app X ≫ U.map f ≫ g) =
      (U.δ.app X ≫ U.map f) ≫ (U.δ.app Y ≫ U.map g)
    simp only [Functor.map_comp, ← Category.assoc]
    rw [Comonad.coassoc]
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
U : Comonad C
X Y x✝ : Cokleisli U
f : X ⟶ Y
g : Y ⟶ x✝
⊢ (((Comonad.δ U).app X ≫ (Comonad.δ U).app (U.obj X)) ≫ U.map (U.map f)) ≫ U.map g =
    (((Comonad.δ U).app X ≫ U.map f) ≫ (Comonad.δ U).app Y) ≫ U.map g

Next tactic:
simp only [Category.assoc, NatTrans.naturality, Functor.comp_map]
/-- The co-Kleisli adjunction which gives rise to the monad `(U, ε_ U, δ_ U)`. -/
def adj : fromCokleisli U ⊣ toCokleisli U :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y => Equiv.refl (U.obj X ⟶ Y)
      homEquiv_naturality_right := fun {X} {Y} {_} f g => by
        -- Porting note: working around lack of unfold_projs
        

Proof state:
C : Type u
inst✝ : Category.{v, u} C
U : Comonad C
X : Cokleisli U
Y x✝ : C
f : (fromCokleisli U).obj X ⟶ Y
g : Y ⟶ x✝
⊢ ((fun X Y => Equiv.refl (U.obj X ⟶ Y)) X x✝) (f ≫ g) =
    ((fun X Y => Equiv.refl (U.obj X ⟶ Y)) X Y) f ≫ (toCokleisli U).map g

Next tactic:
change f ≫ g = U.δ.app X ≫ U.map f ≫ U.ε.app Y ≫ g
/-- The co-Kleisli adjunction which gives rise to the monad `(U, ε_ U, δ_ U)`. -/
def adj : fromCokleisli U ⊣ toCokleisli U :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y => Equiv.refl (U.obj X ⟶ Y)
      homEquiv_naturality_right := fun {X} {Y} {_} f g => by
        -- Porting note: working around lack of unfold_projs
        change f ≫ g = U.δ.app X ≫ U.map f ≫ U.ε.app Y ≫ g
        

Proof state:
C : Type u
inst✝ : Category.{v, u} C
U : Comonad C
X : Cokleisli U
Y x✝ : C
f : (fromCokleisli U).obj X ⟶ Y
g : Y ⟶ x✝
⊢ f ≫ g = (Comonad.δ U).app X ≫ U.map f ≫ (Comonad.ε U).app Y ≫ g

Next tactic:
erw [← Category.assoc (U.map f), U.ε.naturality]
/-- The co-Kleisli adjunction which gives rise to the monad `(U, ε_ U, δ_ U)`. -/
def adj : fromCokleisli U ⊣ toCokleisli U :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y => Equiv.refl (U.obj X ⟶ Y)
      homEquiv_naturality_right := fun {X} {Y} {_} f g => by
        -- Porting note: working around lack of unfold_projs
        change f ≫ g = U.δ.app X ≫ U.map f ≫ U.ε.app Y ≫ g
        erw [← Category.assoc (U.map f), U.ε.naturality]; 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
U : Comonad C
X : Cokleisli U
Y x✝ : C
f : (fromCokleisli U).obj X ⟶ Y
g : Y ⟶ x✝
⊢ f ≫ g = (Comonad.δ U).app X ≫ ((Comonad.ε U).app ((fromCokleisli U).obj X) ≫ (𝟭 C).map f) ≫ g

Next tactic:
dsimp
/-- The co-Kleisli adjunction which gives rise to the monad `(U, ε_ U, δ_ U)`. -/
def adj : fromCokleisli U ⊣ toCokleisli U :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y => Equiv.refl (U.obj X ⟶ Y)
      homEquiv_naturality_right := fun {X} {Y} {_} f g => by
        -- Porting note: working around lack of unfold_projs
        change f ≫ g = U.δ.app X ≫ U.map f ≫ U.ε.app Y ≫ g
        erw [← Category.assoc (U.map f), U.ε.naturality]; dsimp
        

Proof state:
C : Type u
inst✝ : Category.{v, u} C
U : Comonad C
X : Cokleisli U
Y x✝ : C
f : (fromCokleisli U).obj X ⟶ Y
g : Y ⟶ x✝
⊢ f ≫ g = (Comonad.δ U).app X ≫ ((Comonad.ε U).app (U.obj X) ≫ f) ≫ g

Next tactic:
simp only [← Category.assoc, Comonad.left_counit, Category.id_comp]
/-- The quotient of the transversals of an abelian normal `N` by the `diff` relation. -/
def QuotientDiff :=
  Quotient
    (Setoid.mk (fun α β => diff (MonoidHom.id H) α β = 1)
      ⟨fun α => diff_self (MonoidHom.id H) α, fun h => by 

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : IsCommutative H
inst✝ : FiniteIndex H
α β x✝ y✝ : ↑(leftTransversals ↑H)
h : diff (MonoidHom.id ↥H) x✝ y✝ = 1
⊢ diff (MonoidHom.id ↥H) y✝ x✝ = 1

Next tactic:
rw [← diff_inv, h, inv_one]
/-- The quotient of the transversals of an abelian normal `N` by the `diff` relation. -/
def QuotientDiff :=
  Quotient
    (Setoid.mk (fun α β => diff (MonoidHom.id H) α β = 1)
      ⟨fun α => diff_self (MonoidHom.id H) α, fun h => by rw [← diff_inv, h, inv_one],
        fun h h' => by 

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : IsCommutative H
inst✝ : FiniteIndex H
α β x✝ y✝ z✝ : ↑(leftTransversals ↑H)
h : diff (MonoidHom.id ↥H) x✝ y✝ = 1
h' : diff (MonoidHom.id ↥H) y✝ z✝ = 1
⊢ diff (MonoidHom.id ↥H) x✝ z✝ = 1

Next tactic:
rw [← diff_mul_diff, h, h', one_mul]
instance : Inhabited H.QuotientDiff := by
  

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : IsCommutative H
inst✝ : FiniteIndex H
α β : ↑(leftTransversals ↑H)
⊢ Inhabited (QuotientDiff H)

Next tactic:
dsimp [QuotientDiff]
instance : Inhabited H.QuotientDiff := by
  dsimp [QuotientDiff] -- porting note: Added `dsimp`
  

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : IsCommutative H
inst✝ : FiniteIndex H
α β : ↑(leftTransversals ↑H)
⊢ Inhabited
    (Quotient
      { r := fun α β => diff (MonoidHom.id ↥H) α β = 1,
        iseqv := (_ : Equivalence fun α β => diff (MonoidHom.id ↥H) α β = 1) })

Next tactic:
infer_instance
theorem smul_diff_smul' [hH : Normal H] (g : Gᵐᵒᵖ) :
    diff (MonoidHom.id H) (g • α) (g • β) =
      ⟨g.unop⁻¹ * (diff (MonoidHom.id H) α β : H) * g.unop,
        hH.mem_comm ((congr_arg (· ∈ H) (mul_inv_cancel_left _ _)).mpr (SetLike.coe_mem _))⟩ := by
  

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : IsCommutative H
inst✝ : FiniteIndex H
α β : ↑(leftTransversals ↑H)
hH : Normal H
g : Gᵐᵒᵖ
⊢ diff (MonoidHom.id ↥H) (g • α) (g • β) =
    { val := (unop g)⁻¹ * ↑(diff (MonoidHom.id ↥H) α β) * unop g,
      property := (_ : (unop g)⁻¹ * ↑(diff (MonoidHom.id ↥H) α β) * unop g ∈ H) }

Next tactic:
letI := H.fintypeQuotientOfFiniteIndex
theorem smul_diff_smul' [hH : Normal H] (g : Gᵐᵒᵖ) :
    diff (MonoidHom.id H) (g • α) (g • β) =
      ⟨g.unop⁻¹ * (diff (MonoidHom.id H) α β : H) * g.unop,
        hH.mem_comm ((congr_arg (· ∈ H) (mul_inv_cancel_left _ _)).mpr (SetLike.coe_mem _))⟩ := by
  letI := H.fintypeQuotientOfFiniteIndex
  

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : IsCommutative H
inst✝ : FiniteIndex H
α β : ↑(leftTransversals ↑H)
hH : Normal H
g : Gᵐᵒᵖ
this : Fintype (G ⧸ H) := fintypeQuotientOfFiniteIndex H
⊢ diff (MonoidHom.id ↥H) (g • α) (g • β) =
    { val := (unop g)⁻¹ * ↑(diff (MonoidHom.id ↥H) α β) * unop g,
      property := (_ : (unop g)⁻¹ * ↑(diff (MonoidHom.id ↥H) α β) * unop g ∈ H) }

Next tactic:
let ϕ : H →* H :=
    { toFun := fun h =>
        ⟨g.unop⁻¹ * h * g.unop,
          hH.mem_comm ((congr_arg (· ∈ H) (mul_inv_cancel_left _ _)).mpr (SetLike.coe_mem _))⟩
      map_one' := by rw [Subtype.ext_iff, coe_mk, coe_one, mul_one, inv_mul_self]
      map_mul' := fun h₁ h₂ => by
        simp only [Subtype.ext_iff, coe_mk, coe_mul, mul_assoc, mul_inv_cancel_left] }
theorem smul_diff_smul' [hH : Normal H] (g : Gᵐᵒᵖ) :
    diff (MonoidHom.id H) (g • α) (g • β) =
      ⟨g.unop⁻¹ * (diff (MonoidHom.id H) α β : H) * g.unop,
        hH.mem_comm ((congr_arg (· ∈ H) (mul_inv_cancel_left _ _)).mpr (SetLike.coe_mem _))⟩ := by
  letI := H.fintypeQuotientOfFiniteIndex
  let ϕ : H →* H :=
    { toFun := fun h =>
        ⟨g.unop⁻¹ * h * g.unop,
          hH.mem_comm ((congr_arg (· ∈ H) (mul_inv_cancel_left _ _)).mpr (SetLike.coe_mem _))⟩
      map_one' := by 

Proof state:
G : Type u_1
inst✝² : Group G
H : Subgroup G
inst✝¹ : IsCommutative H
inst✝ : FiniteIndex H
α β : ↑(leftTransversals ↑H)
hH : Normal H
g : Gᵐᵒᵖ
this : Fintype (G ⧸ H) := fintypeQuotientOfFiniteIndex H
⊢ (fun h => { val := (unop g)⁻¹ * ↑h * unop g, property := (_ : (unop g)⁻¹ * ↑h * unop g ∈ H) }) 1 = 1

Next tactic:
rw [Subtype.ext_iff, coe_mk, coe_one, mul_one, inv_mul_self]