l3lab/ntp-mathlib huggingface dataset:
/-- If `D` is a monoidal category and we have a function `C → D`, then we have a functor from the
    free monoidal category over `C` to the category `D`. -/
def project : MonoidalFunctor (F C) D where
  obj := projectObj f
  map := projectMap f _ _
  -- Porting note: `map_comp` and `μ_natural` were proved in mathlib3 by tidy, using induction.
  -- We probably don't expect `aesop_cat` to handle this yet, see https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/Aesop.20and.20cases
  -- In any case I don't understand why we need to specify `using Quotient.recOn`.
  map_comp := by rintro _ _ _ ⟨_⟩ ⟨_⟩; rfl
  ε := 𝟙 _
  μ X Y := 𝟙 _
  μ_natural := @fun _ _ _ _ f g => by
    induction' f using Quotient.recOn
    · induction' g using Quotient.recOn
      · dsimp
        simp
        rfl
      · 

Proof state:
case f.h
C : Type u
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : MonoidalCategory D
f : C → D
x✝³ x✝² x✝¹ x✝ : F C
g : x✝¹ ⟶ x✝
a✝¹ : x✝³ ⟶ᵐ x✝²
a✝ b✝ : x✝¹ ⟶ᵐ x✝
p✝ : a✝ ≈ b✝
⊢ (_ :
      ((Functor.mk { obj := projectObj f, map := fun {X Y} => projectMap f X Y }).map ⟦a✝¹⟧ ⊗
            (Functor.mk { obj := projectObj f, map := fun {X Y} => projectMap f X Y }).map ⟦b✝⟧) ≫
          (fun X Y =>
              𝟙
                ((Functor.mk { obj := projectObj f, map := fun {X Y} => projectMap f X Y }).obj X ⊗
                  (Functor.mk { obj := projectObj f, map := fun {X Y} => projectMap f X Y }).obj Y))
            x✝² x✝ =
        (fun X Y =>
              𝟙
                ((Functor.mk { obj := projectObj f, map := fun {X Y} => projectMap f X Y }).obj X ⊗
                  (Functor.mk { obj := projectObj f, map := fun {X Y} => projectMap f X Y }).obj Y))
            x✝³ x✝¹ ≫
          (Functor.mk { obj := projectObj f, map := fun {X Y} => projectMap f X Y }).map (⟦a✝¹⟧ ⊗ ⟦b✝⟧)) =
    (_ :
      ((Functor.mk { obj := projectObj f, map := fun {X Y} => projectMap f X Y }).map ⟦a✝¹⟧ ⊗
            (Functor.mk { obj := projectObj f, map := fun {X Y} => projectMap f X Y }).map ⟦b✝⟧) ≫
          (fun X Y =>
              𝟙
                ((Functor.mk { obj := projectObj f, map := fun {X Y} => projectMap f X Y }).obj X ⊗
                  (Functor.mk { obj := projectObj f, map := fun {X Y} => projectMap f X Y }).obj Y))
            x✝² x✝ =
        (fun X Y =>
              𝟙
                ((Functor.mk { obj := projectObj f, map := fun {X Y} => projectMap f X Y }).obj X ⊗
                  (Functor.mk { obj := projectObj f, map := fun {X Y} => projectMap f X Y }).obj Y))
            x✝³ x✝¹ ≫
          (Functor.mk { obj := projectObj f, map := fun {X Y} => projectMap f X Y }).map (⟦a✝¹⟧ ⊗ ⟦b✝⟧))

Next tactic:
rfl
/-- If `D` is a monoidal category and we have a function `C → D`, then we have a functor from the
    free monoidal category over `C` to the category `D`. -/
def project : MonoidalFunctor (F C) D where
  obj := projectObj f
  map := projectMap f _ _
  -- Porting note: `map_comp` and `μ_natural` were proved in mathlib3 by tidy, using induction.
  -- We probably don't expect `aesop_cat` to handle this yet, see https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/Aesop.20and.20cases
  -- In any case I don't understand why we need to specify `using Quotient.recOn`.
  map_comp := by rintro _ _ _ ⟨_⟩ ⟨_⟩; rfl
  ε := 𝟙 _
  μ X Y := 𝟙 _
  μ_natural := @fun _ _ _ _ f g => by
    induction' f using Quotient.recOn
    · induction' g using Quotient.recOn
      · dsimp
        simp
        rfl
      · rfl
    · 

Proof state:
case h
C : Type u
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : MonoidalCategory D
f✝ : C → D
x✝³ x✝² x✝¹ x✝ : F C
f : x✝³ ⟶ x✝²
g : x✝¹ ⟶ x✝
a✝ b✝ : x✝³ ⟶ᵐ x✝²
p✝ : a✝ ≈ b✝
⊢ (_ :
      ((Functor.mk { obj := projectObj f✝, map := fun {X Y} => projectMap f✝ X Y }).map ⟦b✝⟧ ⊗
            (Functor.mk { obj := projectObj f✝, map := fun {X Y} => projectMap f✝ X Y }).map g) ≫
          (fun X Y =>
              𝟙
                ((Functor.mk { obj := projectObj f✝, map := fun {X Y} => projectMap f✝ X Y }).obj X ⊗
                  (Functor.mk { obj := projectObj f✝, map := fun {X Y} => projectMap f✝ X Y }).obj Y))
            x✝² x✝ =
        (fun X Y =>
              𝟙
                ((Functor.mk { obj := projectObj f✝, map := fun {X Y} => projectMap f✝ X Y }).obj X ⊗
                  (Functor.mk { obj := projectObj f✝, map := fun {X Y} => projectMap f✝ X Y }).obj Y))
            x✝³ x✝¹ ≫
          (Functor.mk { obj := projectObj f✝, map := fun {X Y} => projectMap f✝ X Y }).map (⟦b✝⟧ ⊗ g)) =
    (_ :
      ((Functor.mk { obj := projectObj f✝, map := fun {X Y} => projectMap f✝ X Y }).map ⟦b✝⟧ ⊗
            (Functor.mk { obj := projectObj f✝, map := fun {X Y} => projectMap f✝ X Y }).map g) ≫
          (fun X Y =>
              𝟙
                ((Functor.mk { obj := projectObj f✝, map := fun {X Y} => projectMap f✝ X Y }).obj X ⊗
                  (Functor.mk { obj := projectObj f✝, map := fun {X Y} => projectMap f✝ X Y }).obj Y))
            x✝² x✝ =
        (fun X Y =>
              𝟙
                ((Functor.mk { obj := projectObj f✝, map := fun {X Y} => projectMap f✝ X Y }).obj X ⊗
                  (Functor.mk { obj := projectObj f✝, map := fun {X Y} => projectMap f✝ X Y }).obj Y))
            x✝³ x✝¹ ≫
          (Functor.mk { obj := projectObj f✝, map := fun {X Y} => projectMap f✝ X Y }).map (⟦b✝⟧ ⊗ g))

Next tactic:
rfl
/-- Reinterpret `G ≃+ H` as `Multiplicative G ≃* Multiplicative H`. -/
@[simps]
def AddEquiv.toMultiplicative [AddZeroClass G] [AddZeroClass H] :
    G ≃+ H ≃ (Multiplicative G ≃* Multiplicative H) where
  toFun f :=
  { toFun := AddMonoidHom.toMultiplicative f.toAddMonoidHom
    invFun := AddMonoidHom.toMultiplicative f.symm.toAddMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_mul' := f.map_add }
  invFun f :=
  { toFun := AddMonoidHom.toMultiplicative.symm f.toMonoidHom
    invFun := AddMonoidHom.toMultiplicative.symm f.symm.toMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_add' := f.map_mul }
  left_inv x := by 

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : AddZeroClass G
inst✝ : AddZeroClass H
x : G ≃+ H
⊢ (fun f =>
        {
          toEquiv :=
            { toFun := ⇑(AddMonoidHom.toMultiplicative.symm (MulEquiv.toMonoidHom f)),
              invFun := ⇑(AddMonoidHom.toMultiplicative.symm (MulEquiv.toMonoidHom (MulEquiv.symm f))),
              left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
              right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
          map_add' := (_ : ∀ (x y : Multiplicative G), f (x * y) = f x * f y) })
      ((fun f =>
          {
            toEquiv :=
              { toFun := ⇑(AddMonoidHom.toMultiplicative (toAddMonoidHom f)),
                invFun := ⇑(AddMonoidHom.toMultiplicative (toAddMonoidHom (symm f))),
                left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
            map_mul' := (_ : ∀ (x y : G), f (x + y) = f x + f y) })
        x) =
    x

Next tactic:
ext
/-- Reinterpret `G ≃+ H` as `Multiplicative G ≃* Multiplicative H`. -/
@[simps]
def AddEquiv.toMultiplicative [AddZeroClass G] [AddZeroClass H] :
    G ≃+ H ≃ (Multiplicative G ≃* Multiplicative H) where
  toFun f :=
  { toFun := AddMonoidHom.toMultiplicative f.toAddMonoidHom
    invFun := AddMonoidHom.toMultiplicative f.symm.toAddMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_mul' := f.map_add }
  invFun f :=
  { toFun := AddMonoidHom.toMultiplicative.symm f.toMonoidHom
    invFun := AddMonoidHom.toMultiplicative.symm f.symm.toMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_add' := f.map_mul }
  left_inv x := by ext; 

Proof state:
case h
G : Type u_1
H : Type u_2
inst✝¹ : AddZeroClass G
inst✝ : AddZeroClass H
x : G ≃+ H
x✝ : G
⊢ ((fun f =>
          {
            toEquiv :=
              { toFun := ⇑(AddMonoidHom.toMultiplicative.symm (MulEquiv.toMonoidHom f)),
                invFun := ⇑(AddMonoidHom.toMultiplicative.symm (MulEquiv.toMonoidHom (MulEquiv.symm f))),
                left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
            map_add' := (_ : ∀ (x y : Multiplicative G), f (x * y) = f x * f y) })
        ((fun f =>
            {
              toEquiv :=
                { toFun := ⇑(AddMonoidHom.toMultiplicative (toAddMonoidHom f)),
                  invFun := ⇑(AddMonoidHom.toMultiplicative (toAddMonoidHom (symm f))),
                  left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                  right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
              map_mul' := (_ : ∀ (x y : G), f (x + y) = f x + f y) })
          x))
      x✝ =
    x x✝

Next tactic:
rfl
/-- Reinterpret `G ≃+ H` as `Multiplicative G ≃* Multiplicative H`. -/
@[simps]
def AddEquiv.toMultiplicative [AddZeroClass G] [AddZeroClass H] :
    G ≃+ H ≃ (Multiplicative G ≃* Multiplicative H) where
  toFun f :=
  { toFun := AddMonoidHom.toMultiplicative f.toAddMonoidHom
    invFun := AddMonoidHom.toMultiplicative f.symm.toAddMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_mul' := f.map_add }
  invFun f :=
  { toFun := AddMonoidHom.toMultiplicative.symm f.toMonoidHom
    invFun := AddMonoidHom.toMultiplicative.symm f.symm.toMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_add' := f.map_mul }
  left_inv x := by ext; rfl
  right_inv x := by 

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : AddZeroClass G
inst✝ : AddZeroClass H
x : Multiplicative G ≃* Multiplicative H
⊢ (fun f =>
        {
          toEquiv :=
            { toFun := ⇑(AddMonoidHom.toMultiplicative (toAddMonoidHom f)),
              invFun := ⇑(AddMonoidHom.toMultiplicative (toAddMonoidHom (symm f))),
              left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
              right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
          map_mul' := (_ : ∀ (x y : G), f (x + y) = f x + f y) })
      ((fun f =>
          {
            toEquiv :=
              { toFun := ⇑(AddMonoidHom.toMultiplicative.symm (MulEquiv.toMonoidHom f)),
                invFun := ⇑(AddMonoidHom.toMultiplicative.symm (MulEquiv.toMonoidHom (MulEquiv.symm f))),
                left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
            map_add' := (_ : ∀ (x y : Multiplicative G), f (x * y) = f x * f y) })
        x) =
    x

Next tactic:
ext
/-- Reinterpret `G ≃+ H` as `Multiplicative G ≃* Multiplicative H`. -/
@[simps]
def AddEquiv.toMultiplicative [AddZeroClass G] [AddZeroClass H] :
    G ≃+ H ≃ (Multiplicative G ≃* Multiplicative H) where
  toFun f :=
  { toFun := AddMonoidHom.toMultiplicative f.toAddMonoidHom
    invFun := AddMonoidHom.toMultiplicative f.symm.toAddMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_mul' := f.map_add }
  invFun f :=
  { toFun := AddMonoidHom.toMultiplicative.symm f.toMonoidHom
    invFun := AddMonoidHom.toMultiplicative.symm f.symm.toMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_add' := f.map_mul }
  left_inv x := by ext; rfl
  right_inv x := by ext; 

Proof state:
case h
G : Type u_1
H : Type u_2
inst✝¹ : AddZeroClass G
inst✝ : AddZeroClass H
x : Multiplicative G ≃* Multiplicative H
x✝ : Multiplicative G
⊢ ((fun f =>
          {
            toEquiv :=
              { toFun := ⇑(AddMonoidHom.toMultiplicative (toAddMonoidHom f)),
                invFun := ⇑(AddMonoidHom.toMultiplicative (toAddMonoidHom (symm f))),
                left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
            map_mul' := (_ : ∀ (x y : G), f (x + y) = f x + f y) })
        ((fun f =>
            {
              toEquiv :=
                { toFun := ⇑(AddMonoidHom.toMultiplicative.symm (MulEquiv.toMonoidHom f)),
                  invFun := ⇑(AddMonoidHom.toMultiplicative.symm (MulEquiv.toMonoidHom (MulEquiv.symm f))),
                  left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                  right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
              map_add' := (_ : ∀ (x y : Multiplicative G), f (x * y) = f x * f y) })
          x))
      x✝ =
    x x✝

Next tactic:
rfl
/-- Reinterpret `G ≃* H` as `Additive G ≃+ Additive H`. -/
@[simps]
def MulEquiv.toAdditive [MulOneClass G] [MulOneClass H] :
    G ≃* H ≃ (Additive G ≃+ Additive H) where
  toFun f :=
  { toFun := MonoidHom.toAdditive f.toMonoidHom
    invFun := MonoidHom.toAdditive f.symm.toMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_add' := f.map_mul }
  invFun f :=
  { toFun := MonoidHom.toAdditive.symm f.toAddMonoidHom
    invFun := MonoidHom.toAdditive.symm f.symm.toAddMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_mul' := f.map_add }
  left_inv x := by 

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : MulOneClass G
inst✝ : MulOneClass H
x : G ≃* H
⊢ (fun f =>
        {
          toEquiv :=
            { toFun := ⇑(MonoidHom.toAdditive.symm (AddEquiv.toAddMonoidHom f)),
              invFun := ⇑(MonoidHom.toAdditive.symm (AddEquiv.toAddMonoidHom (AddEquiv.symm f))),
              left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
              right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
          map_mul' := (_ : ∀ (x y : Additive G), f (x + y) = f x + f y) })
      ((fun f =>
          {
            toEquiv :=
              { toFun := ⇑(MonoidHom.toAdditive (toMonoidHom f)),
                invFun := ⇑(MonoidHom.toAdditive (toMonoidHom (symm f))),
                left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
            map_add' := (_ : ∀ (x y : G), f (x * y) = f x * f y) })
        x) =
    x

Next tactic:
ext
/-- Reinterpret `G ≃* H` as `Additive G ≃+ Additive H`. -/
@[simps]
def MulEquiv.toAdditive [MulOneClass G] [MulOneClass H] :
    G ≃* H ≃ (Additive G ≃+ Additive H) where
  toFun f :=
  { toFun := MonoidHom.toAdditive f.toMonoidHom
    invFun := MonoidHom.toAdditive f.symm.toMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_add' := f.map_mul }
  invFun f :=
  { toFun := MonoidHom.toAdditive.symm f.toAddMonoidHom
    invFun := MonoidHom.toAdditive.symm f.symm.toAddMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_mul' := f.map_add }
  left_inv x := by ext; 

Proof state:
case h
G : Type u_1
H : Type u_2
inst✝¹ : MulOneClass G
inst✝ : MulOneClass H
x : G ≃* H
x✝ : G
⊢ ((fun f =>
          {
            toEquiv :=
              { toFun := ⇑(MonoidHom.toAdditive.symm (AddEquiv.toAddMonoidHom f)),
                invFun := ⇑(MonoidHom.toAdditive.symm (AddEquiv.toAddMonoidHom (AddEquiv.symm f))),
                left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
            map_mul' := (_ : ∀ (x y : Additive G), f (x + y) = f x + f y) })
        ((fun f =>
            {
              toEquiv :=
                { toFun := ⇑(MonoidHom.toAdditive (toMonoidHom f)),
                  invFun := ⇑(MonoidHom.toAdditive (toMonoidHom (symm f))),
                  left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                  right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
              map_add' := (_ : ∀ (x y : G), f (x * y) = f x * f y) })
          x))
      x✝ =
    x x✝

Next tactic:
rfl
/-- Reinterpret `G ≃* H` as `Additive G ≃+ Additive H`. -/
@[simps]
def MulEquiv.toAdditive [MulOneClass G] [MulOneClass H] :
    G ≃* H ≃ (Additive G ≃+ Additive H) where
  toFun f :=
  { toFun := MonoidHom.toAdditive f.toMonoidHom
    invFun := MonoidHom.toAdditive f.symm.toMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_add' := f.map_mul }
  invFun f :=
  { toFun := MonoidHom.toAdditive.symm f.toAddMonoidHom
    invFun := MonoidHom.toAdditive.symm f.symm.toAddMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_mul' := f.map_add }
  left_inv x := by ext; rfl
  right_inv x := by 

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : MulOneClass G
inst✝ : MulOneClass H
x : Additive G ≃+ Additive H
⊢ (fun f =>
        {
          toEquiv :=
            { toFun := ⇑(MonoidHom.toAdditive (toMonoidHom f)),
              invFun := ⇑(MonoidHom.toAdditive (toMonoidHom (symm f))),
              left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
              right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
          map_add' := (_ : ∀ (x y : G), f (x * y) = f x * f y) })
      ((fun f =>
          {
            toEquiv :=
              { toFun := ⇑(MonoidHom.toAdditive.symm (AddEquiv.toAddMonoidHom f)),
                invFun := ⇑(MonoidHom.toAdditive.symm (AddEquiv.toAddMonoidHom (AddEquiv.symm f))),
                left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
            map_mul' := (_ : ∀ (x y : Additive G), f (x + y) = f x + f y) })
        x) =
    x

Next tactic:
ext
/-- Reinterpret `G ≃* H` as `Additive G ≃+ Additive H`. -/
@[simps]
def MulEquiv.toAdditive [MulOneClass G] [MulOneClass H] :
    G ≃* H ≃ (Additive G ≃+ Additive H) where
  toFun f :=
  { toFun := MonoidHom.toAdditive f.toMonoidHom
    invFun := MonoidHom.toAdditive f.symm.toMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_add' := f.map_mul }
  invFun f :=
  { toFun := MonoidHom.toAdditive.symm f.toAddMonoidHom
    invFun := MonoidHom.toAdditive.symm f.symm.toAddMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_mul' := f.map_add }
  left_inv x := by ext; rfl
  right_inv x := by ext; 

Proof state:
case h
G : Type u_1
H : Type u_2
inst✝¹ : MulOneClass G
inst✝ : MulOneClass H
x : Additive G ≃+ Additive H
x✝ : Additive G
⊢ ((fun f =>
          {
            toEquiv :=
              { toFun := ⇑(MonoidHom.toAdditive (toMonoidHom f)),
                invFun := ⇑(MonoidHom.toAdditive (toMonoidHom (symm f))),
                left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
            map_add' := (_ : ∀ (x y : G), f (x * y) = f x * f y) })
        ((fun f =>
            {
              toEquiv :=
                { toFun := ⇑(MonoidHom.toAdditive.symm (AddEquiv.toAddMonoidHom f)),
                  invFun := ⇑(MonoidHom.toAdditive.symm (AddEquiv.toAddMonoidHom (AddEquiv.symm f))),
                  left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                  right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
              map_mul' := (_ : ∀ (x y : Additive G), f (x + y) = f x + f y) })
          x))
      x✝ =
    x x✝

Next tactic:
rfl
/-- Reinterpret `Additive G ≃+ H` as `G ≃* Multiplicative H`. -/
@[simps]
def AddEquiv.toMultiplicative' [MulOneClass G] [AddZeroClass H] :
    Additive G ≃+ H ≃ (G ≃* Multiplicative H) where
  toFun f :=
  { toFun := AddMonoidHom.toMultiplicative' f.toAddMonoidHom
    invFun := AddMonoidHom.toMultiplicative'' f.symm.toAddMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_mul' := f.map_add }
  invFun f :=
  { toFun := AddMonoidHom.toMultiplicative'.symm f.toMonoidHom
    invFun := AddMonoidHom.toMultiplicative''.symm f.symm.toMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_add' := f.map_mul }
  left_inv x := by 

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : MulOneClass G
inst✝ : AddZeroClass H
x : Additive G ≃+ H
⊢ (fun f =>
        {
          toEquiv :=
            { toFun := ⇑(AddMonoidHom.toMultiplicative'.symm (MulEquiv.toMonoidHom f)),
              invFun := ⇑(AddMonoidHom.toMultiplicative''.symm (MulEquiv.toMonoidHom (MulEquiv.symm f))),
              left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
              right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
          map_add' := (_ : ∀ (x y : G), f (x * y) = f x * f y) })
      ((fun f =>
          {
            toEquiv :=
              { toFun := ⇑(AddMonoidHom.toMultiplicative' (toAddMonoidHom f)),
                invFun := ⇑(AddMonoidHom.toMultiplicative'' (toAddMonoidHom (symm f))),
                left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
            map_mul' := (_ : ∀ (x y : Additive G), f (x + y) = f x + f y) })
        x) =
    x

Next tactic:
ext
/-- Reinterpret `Additive G ≃+ H` as `G ≃* Multiplicative H`. -/
@[simps]
def AddEquiv.toMultiplicative' [MulOneClass G] [AddZeroClass H] :
    Additive G ≃+ H ≃ (G ≃* Multiplicative H) where
  toFun f :=
  { toFun := AddMonoidHom.toMultiplicative' f.toAddMonoidHom
    invFun := AddMonoidHom.toMultiplicative'' f.symm.toAddMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_mul' := f.map_add }
  invFun f :=
  { toFun := AddMonoidHom.toMultiplicative'.symm f.toMonoidHom
    invFun := AddMonoidHom.toMultiplicative''.symm f.symm.toMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_add' := f.map_mul }
  left_inv x := by ext; 

Proof state:
case h
G : Type u_1
H : Type u_2
inst✝¹ : MulOneClass G
inst✝ : AddZeroClass H
x : Additive G ≃+ H
x✝ : Additive G
⊢ ((fun f =>
          {
            toEquiv :=
              { toFun := ⇑(AddMonoidHom.toMultiplicative'.symm (MulEquiv.toMonoidHom f)),
                invFun := ⇑(AddMonoidHom.toMultiplicative''.symm (MulEquiv.toMonoidHom (MulEquiv.symm f))),
                left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
            map_add' := (_ : ∀ (x y : G), f (x * y) = f x * f y) })
        ((fun f =>
            {
              toEquiv :=
                { toFun := ⇑(AddMonoidHom.toMultiplicative' (toAddMonoidHom f)),
                  invFun := ⇑(AddMonoidHom.toMultiplicative'' (toAddMonoidHom (symm f))),
                  left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                  right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
              map_mul' := (_ : ∀ (x y : Additive G), f (x + y) = f x + f y) })
          x))
      x✝ =
    x x✝

Next tactic:
rfl
/-- Reinterpret `Additive G ≃+ H` as `G ≃* Multiplicative H`. -/
@[simps]
def AddEquiv.toMultiplicative' [MulOneClass G] [AddZeroClass H] :
    Additive G ≃+ H ≃ (G ≃* Multiplicative H) where
  toFun f :=
  { toFun := AddMonoidHom.toMultiplicative' f.toAddMonoidHom
    invFun := AddMonoidHom.toMultiplicative'' f.symm.toAddMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_mul' := f.map_add }
  invFun f :=
  { toFun := AddMonoidHom.toMultiplicative'.symm f.toMonoidHom
    invFun := AddMonoidHom.toMultiplicative''.symm f.symm.toMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_add' := f.map_mul }
  left_inv x := by ext; rfl
  right_inv x := by 

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : MulOneClass G
inst✝ : AddZeroClass H
x : G ≃* Multiplicative H
⊢ (fun f =>
        {
          toEquiv :=
            { toFun := ⇑(AddMonoidHom.toMultiplicative' (toAddMonoidHom f)),
              invFun := ⇑(AddMonoidHom.toMultiplicative'' (toAddMonoidHom (symm f))),
              left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
              right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
          map_mul' := (_ : ∀ (x y : Additive G), f (x + y) = f x + f y) })
      ((fun f =>
          {
            toEquiv :=
              { toFun := ⇑(AddMonoidHom.toMultiplicative'.symm (MulEquiv.toMonoidHom f)),
                invFun := ⇑(AddMonoidHom.toMultiplicative''.symm (MulEquiv.toMonoidHom (MulEquiv.symm f))),
                left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
            map_add' := (_ : ∀ (x y : G), f (x * y) = f x * f y) })
        x) =
    x

Next tactic:
ext