l3lab/ntp-mathlib huggingface dataset:
theorem coe_mul_of_apply_of_not_le (r : ⨁ i, A i) {i : ι} (r' : A i) (n : ι) (h : ¬i ≤ n) :
    ((r * of (fun i => A i) i r') n : R) = 0 := by
  classical
    rw [coe_mul_apply_eq_dfinsupp_sum, DFinsupp.sum_comm]
    apply (DFinsupp.sum_single_index _).trans
    swap
    · simp_rw [ZeroMemClass.coe_zero, mul_zero, ite_self]
      exact DFinsupp.sum_zero
    · 

Proof state:
ι : Type u_1
σ : Type u_2
S : Type u_3
R : Type u_4
inst✝⁵ : DecidableEq ι
inst✝⁴ : Semiring R
inst✝³ : SetLike σ R
inst✝² : AddSubmonoidClass σ R
A : ι → σ
inst✝¹ : CanonicallyOrderedAddCommMonoid ι
inst✝ : SetLike.GradedMonoid A
r : ⨁ (i : ι), ↥(A i)
i : ι
r' : ↥(A i)
n : ι
h : ¬i ≤ n
⊢ (DFinsupp.sum r fun i₁ x₁ => if i₁ + i = n then ↑x₁ * ↑r' else 0) = 0

Next tactic:
rw [DFinsupp.sum, Finset.sum_ite_of_false _ _ fun x _ H => _, Finset.sum_const_zero]
theorem coe_mul_of_apply_of_not_le (r : ⨁ i, A i) {i : ι} (r' : A i) (n : ι) (h : ¬i ≤ n) :
    ((r * of (fun i => A i) i r') n : R) = 0 := by
  classical
    rw [coe_mul_apply_eq_dfinsupp_sum, DFinsupp.sum_comm]
    apply (DFinsupp.sum_single_index _).trans
    swap
    · simp_rw [ZeroMemClass.coe_zero, mul_zero, ite_self]
      exact DFinsupp.sum_zero
    · rw [DFinsupp.sum, Finset.sum_ite_of_false _ _ fun x _ H => _, Finset.sum_const_zero]
      

Proof state:
ι : Type u_1
σ : Type u_2
S : Type u_3
R : Type u_4
inst✝⁵ : DecidableEq ι
inst✝⁴ : Semiring R
inst✝³ : SetLike σ R
inst✝² : AddSubmonoidClass σ R
A : ι → σ
inst✝¹ : CanonicallyOrderedAddCommMonoid ι
inst✝ : SetLike.GradedMonoid A
r : ⨁ (i : ι), ↥(A i)
i : ι
r' : ↥(A i)
n : ι
h : ¬i ≤ n
⊢ ∀ x ∈ DFinsupp.support r, x + i = n → False

Next tactic:
exact fun x _ H => h ((self_le_add_left i x).trans_eq H)
theorem coe_of_mul_apply_of_le {i : ι} (r : A i) (r' : ⨁ i, A i) (n : ι) (h : i ≤ n) :
    ((of (fun i => A i) i r * r') n : R) = r * r' (n - i) :=
  coe_of_mul_apply_aux _ _ _ fun x => by 

Proof state:
ι : Type u_1
σ : Type u_2
S : Type u_3
R : Type u_4
inst✝⁸ : DecidableEq ι
inst✝⁷ : Semiring R
inst✝⁶ : SetLike σ R
inst✝⁵ : AddSubmonoidClass σ R
A : ι → σ
inst✝⁴ : CanonicallyOrderedAddCommMonoid ι
inst✝³ : SetLike.GradedMonoid A
inst✝² : Sub ι
inst✝¹ : OrderedSub ι
inst✝ : ContravariantClass ι ι (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
i : ι
r : ↥(A i)
r' : ⨁ (i : ι), ↥(A i)
n : ι
h : i ≤ n
x : ι
⊢ i + x = n ↔ x = n - i

Next tactic:
rw [eq_tsub_iff_add_eq_of_le h, add_comm]
theorem coe_mul_of_apply (r : ⨁ i, A i) {i : ι} (r' : A i) (n : ι) [Decidable (i ≤ n)] :
    ((r * of (fun i => A i) i r') n : R) = if i ≤ n then (r (n - i) : R) * r' else 0 := by
  

Proof state:
ι : Type u_1
σ : Type u_2
S : Type u_3
R : Type u_4
inst✝⁹ : DecidableEq ι
inst✝⁸ : Semiring R
inst✝⁷ : SetLike σ R
inst✝⁶ : AddSubmonoidClass σ R
A : ι → σ
inst✝⁵ : CanonicallyOrderedAddCommMonoid ι
inst✝⁴ : SetLike.GradedMonoid A
inst✝³ : Sub ι
inst✝² : OrderedSub ι
inst✝¹ : ContravariantClass ι ι (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
r : ⨁ (i : ι), ↥(A i)
i : ι
r' : ↥(A i)
n : ι
inst✝ : Decidable (i ≤ n)
⊢ ↑((r * (of (fun i => ↥(A i)) i) r') n) = if i ≤ n then ↑(r (n - i)) * ↑r' else 0

Next tactic:
split_ifs with h
theorem coe_mul_of_apply (r : ⨁ i, A i) {i : ι} (r' : A i) (n : ι) [Decidable (i ≤ n)] :
    ((r * of (fun i => A i) i r') n : R) = if i ≤ n then (r (n - i) : R) * r' else 0 := by
  split_ifs with h
  

Proof state:
case pos
ι : Type u_1
σ : Type u_2
S : Type u_3
R : Type u_4
inst✝⁹ : DecidableEq ι
inst✝⁸ : Semiring R
inst✝⁷ : SetLike σ R
inst✝⁶ : AddSubmonoidClass σ R
A : ι → σ
inst✝⁵ : CanonicallyOrderedAddCommMonoid ι
inst✝⁴ : SetLike.GradedMonoid A
inst✝³ : Sub ι
inst✝² : OrderedSub ι
inst✝¹ : ContravariantClass ι ι (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
r : ⨁ (i : ι), ↥(A i)
i : ι
r' : ↥(A i)
n : ι
inst✝ : Decidable (i ≤ n)
h : i ≤ n
⊢ ↑((r * (of (fun i => ↥(A i)) i) r') n) = ↑(r (n - i)) * ↑r'
case neg
ι : Type u_1
σ : Type u_2
S : Type u_3
R : Type u_4
inst✝⁹ : DecidableEq ι
inst✝⁸ : Semiring R
inst✝⁷ : SetLike σ R
inst✝⁶ : AddSubmonoidClass σ R
A : ι → σ
inst✝⁵ : CanonicallyOrderedAddCommMonoid ι
inst✝⁴ : SetLike.GradedMonoid A
inst✝³ : Sub ι
inst✝² : OrderedSub ι
inst✝¹ : ContravariantClass ι ι (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
r : ⨁ (i : ι), ↥(A i)
i : ι
r' : ↥(A i)
n : ι
inst✝ : Decidable (i ≤ n)
h : ¬i ≤ n
⊢ ↑((r * (of (fun i => ↥(A i)) i) r') n) = 0

Next tactic:
exacts [coe_mul_of_apply_of_le _ _ _ n h, coe_mul_of_apply_of_not_le _ _ _ n h]
theorem coe_of_mul_apply {i : ι} (r : A i) (r' : ⨁ i, A i) (n : ι) [Decidable (i ≤ n)] :
    ((of (fun i => A i) i r * r') n : R) = if i ≤ n then (r * r' (n - i) : R) else 0 := by
  

Proof state:
ι : Type u_1
σ : Type u_2
S : Type u_3
R : Type u_4
inst✝⁹ : DecidableEq ι
inst✝⁸ : Semiring R
inst✝⁷ : SetLike σ R
inst✝⁶ : AddSubmonoidClass σ R
A : ι → σ
inst✝⁵ : CanonicallyOrderedAddCommMonoid ι
inst✝⁴ : SetLike.GradedMonoid A
inst✝³ : Sub ι
inst✝² : OrderedSub ι
inst✝¹ : ContravariantClass ι ι (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
i : ι
r : ↥(A i)
r' : ⨁ (i : ι), ↥(A i)
n : ι
inst✝ : Decidable (i ≤ n)
⊢ ↑(((of (fun i => ↥(A i)) i) r * r') n) = if i ≤ n then ↑r * ↑(r' (n - i)) else 0

Next tactic:
split_ifs with h
theorem coe_of_mul_apply {i : ι} (r : A i) (r' : ⨁ i, A i) (n : ι) [Decidable (i ≤ n)] :
    ((of (fun i => A i) i r * r') n : R) = if i ≤ n then (r * r' (n - i) : R) else 0 := by
  split_ifs with h
  

Proof state:
case pos
ι : Type u_1
σ : Type u_2
S : Type u_3
R : Type u_4
inst✝⁹ : DecidableEq ι
inst✝⁸ : Semiring R
inst✝⁷ : SetLike σ R
inst✝⁶ : AddSubmonoidClass σ R
A : ι → σ
inst✝⁵ : CanonicallyOrderedAddCommMonoid ι
inst✝⁴ : SetLike.GradedMonoid A
inst✝³ : Sub ι
inst✝² : OrderedSub ι
inst✝¹ : ContravariantClass ι ι (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
i : ι
r : ↥(A i)
r' : ⨁ (i : ι), ↥(A i)
n : ι
inst✝ : Decidable (i ≤ n)
h : i ≤ n
⊢ ↑(((of (fun i => ↥(A i)) i) r * r') n) = ↑r * ↑(r' (n - i))
case neg
ι : Type u_1
σ : Type u_2
S : Type u_3
R : Type u_4
inst✝⁹ : DecidableEq ι
inst✝⁸ : Semiring R
inst✝⁷ : SetLike σ R
inst✝⁶ : AddSubmonoidClass σ R
A : ι → σ
inst✝⁵ : CanonicallyOrderedAddCommMonoid ι
inst✝⁴ : SetLike.GradedMonoid A
inst✝³ : Sub ι
inst✝² : OrderedSub ι
inst✝¹ : ContravariantClass ι ι (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
i : ι
r : ↥(A i)
r' : ⨁ (i : ι), ↥(A i)
n : ι
inst✝ : Decidable (i ≤ n)
h : ¬i ≤ n
⊢ ↑(((of (fun i => ↥(A i)) i) r * r') n) = 0

Next tactic:
exacts [coe_of_mul_apply_of_le _ _ _ n h, coe_of_mul_apply_of_not_le _ _ _ n h]
/-- A direct sum of powers of a submodule of an algebra has a multiplicative structure. -/
instance nat_power_gradedMonoid [CommSemiring S] [Semiring R] [Algebra S R] (p : Submodule S R) :
    SetLike.GradedMonoid fun i : ℕ => p ^ i where
  one_mem := by
    

Proof state:
ι : Type u_1
σ : Type u_2
S : Type u_3
R : Type u_4
inst✝³ : DecidableEq ι
inst✝² : CommSemiring S
inst✝¹ : Semiring R
inst✝ : Algebra S R
p : Submodule S R
⊢ 1 ∈ p ^ 0

Next tactic:
rw [← one_le, pow_zero]
/-- A direct sum of powers of a submodule of an algebra has a multiplicative structure. -/
instance nat_power_gradedMonoid [CommSemiring S] [Semiring R] [Algebra S R] (p : Submodule S R) :
    SetLike.GradedMonoid fun i : ℕ => p ^ i where
  one_mem := by
    rw [← one_le, pow_zero]
  mul_mem i j p q hp hq := by
    

Proof state:
ι : Type u_1
σ : Type u_2
S : Type u_3
R : Type u_4
inst✝³ : DecidableEq ι
inst✝² : CommSemiring S
inst✝¹ : Semiring R
inst✝ : Algebra S R
p✝ : Submodule S R
i j : ℕ
p q : R
hp : p ∈ p✝ ^ i
hq : q ∈ p✝ ^ j
⊢ p * q ∈ p✝ ^ (i + j)

Next tactic:
rw [pow_add]
/-- A direct sum of powers of a submodule of an algebra has a multiplicative structure. -/
instance nat_power_gradedMonoid [CommSemiring S] [Semiring R] [Algebra S R] (p : Submodule S R) :
    SetLike.GradedMonoid fun i : ℕ => p ^ i where
  one_mem := by
    rw [← one_le, pow_zero]
  mul_mem i j p q hp hq := by
    rw [pow_add]
    

Proof state:
ι : Type u_1
σ : Type u_2
S : Type u_3
R : Type u_4
inst✝³ : DecidableEq ι
inst✝² : CommSemiring S
inst✝¹ : Semiring R
inst✝ : Algebra S R
p✝ : Submodule S R
i j : ℕ
p q : R
hp : p ∈ p✝ ^ i
hq : q ∈ p✝ ^ j
⊢ p * q ∈ p✝ ^ i * p✝ ^ j

Next tactic:
exact Submodule.mul_mem_mul hp hq
@[simp]
theorem DirectSum.coeAlgHom_of [AddMonoid ι] [CommSemiring S] [Semiring R] [Algebra S R]
    (A : ι → Submodule S R) [SetLike.GradedMonoid A] (i : ι) (x : A i) :
    DirectSum.coeAlgHom A (DirectSum.of (fun i => A i) i x) = x :=
  DirectSum.toSemiring_of _ (by 

Proof state:
ι : Type u_1
σ : Type u_2
S : Type u_3
R : Type u_4
inst✝⁵ : DecidableEq ι
inst✝⁴ : AddMonoid ι
inst✝³ : CommSemiring S
inst✝² : Semiring R
inst✝¹ : Algebra S R
A : ι → Submodule S R
inst✝ : SetLike.GradedMonoid A
i : ι
x : ↥(A i)
⊢ ((fun i => LinearMap.toAddMonoidHom ((fun i => Submodule.subtype (A i)) i)) 0) GradedMonoid.GOne.one = 1

Next tactic:
rfl
@[simp]
theorem DirectSum.coeAlgHom_of [AddMonoid ι] [CommSemiring S] [Semiring R] [Algebra S R]
    (A : ι → Submodule S R) [SetLike.GradedMonoid A] (i : ι) (x : A i) :
    DirectSum.coeAlgHom A (DirectSum.of (fun i => A i) i x) = x :=
  DirectSum.toSemiring_of _ (by rfl) (fun _ _ => (by 

Proof state:
ι : Type u_1
σ : Type u_2
S : Type u_3
R : Type u_4
inst✝⁵ : DecidableEq ι
inst✝⁴ : AddMonoid ι
inst✝³ : CommSemiring S
inst✝² : Semiring R
inst✝¹ : Algebra S R
A : ι → Submodule S R
inst✝ : SetLike.GradedMonoid A
i : ι
x : ↥(A i)
i✝ j✝ : ι
x✝¹ : ↥(A i✝)
x✝ : ↥(A j✝)
⊢ ((fun i => LinearMap.toAddMonoidHom ((fun i => Submodule.subtype (A i)) i)) (i✝ + j✝))
      (GradedMonoid.GMul.mul x✝¹ x✝) =
    ((fun i => LinearMap.toAddMonoidHom ((fun i => Submodule.subtype (A i)) i)) i✝) x✝¹ *
      ((fun i => LinearMap.toAddMonoidHom ((fun i => Submodule.subtype (A i)) i)) j✝) x✝

Next tactic:
rfl
instance {J : Type} [SmallCategory J] (K : J ⥤ FintypeCat.{u}) (j : J) :
    Finite ((K ⋙ FintypeCat.incl.{u}).obj j) := by
  

Proof state:
J : Type
inst✝ : SmallCategory J
K : J ⥤ FintypeCat
j : J
⊢ Finite ((K ⋙ FintypeCat.incl).obj j)

Next tactic:
simp only [comp_obj, FintypeCat.incl_obj]
instance {J : Type} [SmallCategory J] (K : J ⥤ FintypeCat.{u}) (j : J) :
    Finite ((K ⋙ FintypeCat.incl.{u}).obj j) := by
  simp only [comp_obj, FintypeCat.incl_obj]
  

Proof state:
J : Type
inst✝ : SmallCategory J
K : J ⥤ FintypeCat
j : J
⊢ Finite ↑(K.obj j)

Next tactic:
infer_instance
/-- Any functor from a finite category to Types that only involves finite objects,
has a finite limit. -/
noncomputable instance finiteLimitOfFiniteDiagram {J : Type} [SmallCategory J] [FinCategory J]
    (K : J ⥤ Type*) [∀ j, Finite (K.obj j)] : Fintype (limit K) := by
  

Proof state:
J : Type
inst✝² : SmallCategory J
inst✝¹ : FinCategory J
K : J ⥤ Type u_1
inst✝ : ∀ (j : J), Finite (K.obj j)
⊢ Fintype (limit K)

Next tactic:
have : Fintype (sections K) := Fintype.ofFinite (sections K)
/-- Any functor from a finite category to Types that only involves finite objects,
has a finite limit. -/
noncomputable instance finiteLimitOfFiniteDiagram {J : Type} [SmallCategory J] [FinCategory J]
    (K : J ⥤ Type*) [∀ j, Finite (K.obj j)] : Fintype (limit K) := by
  have : Fintype (sections K) := Fintype.ofFinite (sections K)
  

Proof state:
J : Type
inst✝² : SmallCategory J
inst✝¹ : FinCategory J
K : J ⥤ Type u_1
inst✝ : ∀ (j : J), Finite (K.obj j)
this : Fintype ↑(sections K)
⊢ Fintype (limit K)

Next tactic:
exact Fintype.ofEquiv (sections K) (Types.limitEquivSections K).symm
/-- Any functor from a finite category to Types that only involves finite objects,
has a finite colimit. -/
noncomputable instance finiteColimitOfFiniteDiagram {J : Type} [SmallCategory J] [FinCategory J]
    (K : J ⥤ Type*) [∀ j, Finite (K.obj j)] : Fintype (colimit K) := by
  

Proof state:
J : Type
inst✝² : SmallCategory J
inst✝¹ : FinCategory J
K : J ⥤ Type u_1
inst✝ : ∀ (j : J), Finite (K.obj j)
⊢ Fintype (colimit K)

Next tactic:
have : Finite (Types.Quot K) := Quot.finite (Types.Quot.Rel K)
/-- Any functor from a finite category to Types that only involves finite objects,
has a finite colimit. -/
noncomputable instance finiteColimitOfFiniteDiagram {J : Type} [SmallCategory J] [FinCategory J]
    (K : J ⥤ Type*) [∀ j, Finite (K.obj j)] : Fintype (colimit K) := by
  have : Finite (Types.Quot K) := Quot.finite (Types.Quot.Rel K)
  

Proof state:
J : Type
inst✝² : SmallCategory J
inst✝¹ : FinCategory J
K : J ⥤ Type u_1
inst✝ : ∀ (j : J), Finite (K.obj j)
this : Finite (Types.Quot K)
⊢ Fintype (colimit K)

Next tactic:
have : Fintype (Types.Quot K) := Fintype.ofFinite (Types.Quot K)
/-- Any functor from a finite category to Types that only involves finite objects,
has a finite colimit. -/
noncomputable instance finiteColimitOfFiniteDiagram {J : Type} [SmallCategory J] [FinCategory J]
    (K : J ⥤ Type*) [∀ j, Finite (K.obj j)] : Fintype (colimit K) := by
  have : Finite (Types.Quot K) := Quot.finite (Types.Quot.Rel K)
  have : Fintype (Types.Quot K) := Fintype.ofFinite (Types.Quot K)
  

Proof state:
J : Type
inst✝² : SmallCategory J
inst✝¹ : FinCategory J
K : J ⥤ Type u_1
inst✝ : ∀ (j : J), Finite (K.obj j)
this✝ : Finite (Types.Quot K)
this : Fintype (Types.Quot K)
⊢ Fintype (colimit K)

Next tactic:
exact Fintype.ofEquiv (Types.Quot K) (Types.colimitEquivQuot K).symm
/-- Submonoids of monoid `M` are isomorphic to additive submonoids of `Additive M`. -/
@[simps]
def Submonoid.toAddSubmonoid : Submonoid M ≃o AddSubmonoid (Additive M) where
  toFun S :=
    { carrier := Additive.toMul ⁻¹' S
      zero_mem' := S.one_mem'
      add_mem' := fun ha hb => S.mul_mem' ha hb }
  invFun S :=
    { carrier := Additive.ofMul ⁻¹' S
      one_mem' := S.zero_mem'
      mul_mem' := fun ha hb => S.add_mem' ha hb}
  left_inv x := by 

Proof state:
M : Type u_1
N : Type u_2
P : Type u_3
inst✝² : MulOneClass M
inst✝¹ : MulOneClass N
inst✝ : MulOneClass P
S x : Submonoid M
⊢ (fun S =>
        {
          toSubsemigroup :=
            { carrier := ⇑Additive.ofMul ⁻¹' ↑S,
              mul_mem' :=
                (_ : ∀ {a b : M}, a ∈ ⇑Additive.ofMul ⁻¹' ↑S → b ∈ ⇑Additive.ofMul ⁻¹' ↑S → a + b ∈ S.carrier) },
          one_mem' := (_ : 0 ∈ S.carrier) })
      ((fun S =>
          {
            toAddSubsemigroup :=
              { carrier := ⇑Additive.toMul ⁻¹' ↑S,
                add_mem' :=
                  (_ :
                    ∀ {a b : Additive M},
                      a ∈ ⇑Additive.toMul ⁻¹' ↑S →
                        b ∈ ⇑Additive.toMul ⁻¹' ↑S → Additive.toMul a * Additive.toMul b ∈ S.carrier) },
            zero_mem' := (_ : 1 ∈ S.carrier) })
        x) =
    x

Next tactic:
cases x
/-- Submonoids of monoid `M` are isomorphic to additive submonoids of `Additive M`. -/
@[simps]
def Submonoid.toAddSubmonoid : Submonoid M ≃o AddSubmonoid (Additive M) where
  toFun S :=
    { carrier := Additive.toMul ⁻¹' S
      zero_mem' := S.one_mem'
      add_mem' := fun ha hb => S.mul_mem' ha hb }
  invFun S :=
    { carrier := Additive.ofMul ⁻¹' S
      one_mem' := S.zero_mem'
      mul_mem' := fun ha hb => S.add_mem' ha hb}
  left_inv x := by cases x; 

Proof state:
case mk
M : Type u_1
N : Type u_2
P : Type u_3
inst✝² : MulOneClass M
inst✝¹ : MulOneClass N
inst✝ : MulOneClass P
S : Submonoid M
toSubsemigroup✝ : Subsemigroup M
one_mem'✝ : 1 ∈ toSubsemigroup✝.carrier
⊢ (fun S =>
        {
          toSubsemigroup :=
            { carrier := ⇑Additive.ofMul ⁻¹' ↑S,
              mul_mem' :=
                (_ : ∀ {a b : M}, a ∈ ⇑Additive.ofMul ⁻¹' ↑S → b ∈ ⇑Additive.ofMul ⁻¹' ↑S → a + b ∈ S.carrier) },
          one_mem' := (_ : 0 ∈ S.carrier) })
      ((fun S =>
          {
            toAddSubsemigroup :=
              { carrier := ⇑Additive.toMul ⁻¹' ↑S,
                add_mem' :=
                  (_ :
                    ∀ {a b : Additive M},
                      a ∈ ⇑Additive.toMul ⁻¹' ↑S →
                        b ∈ ⇑Additive.toMul ⁻¹' ↑S → Additive.toMul a * Additive.toMul b ∈ S.carrier) },
            zero_mem' := (_ : 1 ∈ S.carrier) })
        { toSubsemigroup := toSubsemigroup✝, one_mem' := one_mem'✝ }) =
    { toSubsemigroup := toSubsemigroup✝, one_mem' := one_mem'✝ }

Next tactic:
rfl
/-- Submonoids of monoid `M` are isomorphic to additive submonoids of `Additive M`. -/
@[simps]
def Submonoid.toAddSubmonoid : Submonoid M ≃o AddSubmonoid (Additive M) where
  toFun S :=
    { carrier := Additive.toMul ⁻¹' S
      zero_mem' := S.one_mem'
      add_mem' := fun ha hb => S.mul_mem' ha hb }
  invFun S :=
    { carrier := Additive.ofMul ⁻¹' S
      one_mem' := S.zero_mem'
      mul_mem' := fun ha hb => S.add_mem' ha hb}
  left_inv x := by cases x; rfl
  right_inv x := by 

Proof state:
M : Type u_1
N : Type u_2
P : Type u_3
inst✝² : MulOneClass M
inst✝¹ : MulOneClass N
inst✝ : MulOneClass P
S : Submonoid M
x : AddSubmonoid (Additive M)
⊢ (fun S =>
        {
          toAddSubsemigroup :=
            { carrier := ⇑Additive.toMul ⁻¹' ↑S,
              add_mem' :=
                (_ :
                  ∀ {a b : Additive M},
                    a ∈ ⇑Additive.toMul ⁻¹' ↑S →
                      b ∈ ⇑Additive.toMul ⁻¹' ↑S → Additive.toMul a * Additive.toMul b ∈ S.carrier) },
          zero_mem' := (_ : 1 ∈ S.carrier) })
      ((fun S =>
          {
            toSubsemigroup :=
              { carrier := ⇑Additive.ofMul ⁻¹' ↑S,
                mul_mem' :=
                  (_ : ∀ {a b : M}, a ∈ ⇑Additive.ofMul ⁻¹' ↑S → b ∈ ⇑Additive.ofMul ⁻¹' ↑S → a + b ∈ S.carrier) },
            one_mem' := (_ : 0 ∈ S.carrier) })
        x) =
    x

Next tactic:
cases x
/-- Submonoids of monoid `M` are isomorphic to additive submonoids of `Additive M`. -/
@[simps]
def Submonoid.toAddSubmonoid : Submonoid M ≃o AddSubmonoid (Additive M) where
  toFun S :=
    { carrier := Additive.toMul ⁻¹' S
      zero_mem' := S.one_mem'
      add_mem' := fun ha hb => S.mul_mem' ha hb }
  invFun S :=
    { carrier := Additive.ofMul ⁻¹' S
      one_mem' := S.zero_mem'
      mul_mem' := fun ha hb => S.add_mem' ha hb}
  left_inv x := by cases x; rfl
  right_inv x := by cases x; 

Proof state:
case mk
M : Type u_1
N : Type u_2
P : Type u_3
inst✝² : MulOneClass M
inst✝¹ : MulOneClass N
inst✝ : MulOneClass P
S : Submonoid M
toAddSubsemigroup✝ : AddSubsemigroup (Additive M)
zero_mem'✝ : 0 ∈ toAddSubsemigroup✝.carrier
⊢ (fun S =>
        {
          toAddSubsemigroup :=
            { carrier := ⇑Additive.toMul ⁻¹' ↑S,
              add_mem' :=
                (_ :
                  ∀ {a b : Additive M},
                    a ∈ ⇑Additive.toMul ⁻¹' ↑S →
                      b ∈ ⇑Additive.toMul ⁻¹' ↑S → Additive.toMul a * Additive.toMul b ∈ S.carrier) },
          zero_mem' := (_ : 1 ∈ S.carrier) })
      ((fun S =>
          {
            toSubsemigroup :=
              { carrier := ⇑Additive.ofMul ⁻¹' ↑S,
                mul_mem' :=
                  (_ : ∀ {a b : M}, a ∈ ⇑Additive.ofMul ⁻¹' ↑S → b ∈ ⇑Additive.ofMul ⁻¹' ↑S → a + b ∈ S.carrier) },
            one_mem' := (_ : 0 ∈ S.carrier) })
        { toAddSubsemigroup := toAddSubsemigroup✝, zero_mem' := zero_mem'✝ }) =
    { toAddSubsemigroup := toAddSubsemigroup✝, zero_mem' := zero_mem'✝ }

Next tactic:
rfl
/-- Additive submonoids of an additive monoid `A` are isomorphic to
multiplicative submonoids of `Multiplicative A`. -/
@[simps]
def AddSubmonoid.toSubmonoid : AddSubmonoid A ≃o Submonoid (Multiplicative A) where
  toFun S :=
    { carrier := Multiplicative.toAdd ⁻¹' S
      one_mem' := S.zero_mem'
      mul_mem' := fun ha hb => S.add_mem' ha hb }
  invFun S :=
    { carrier := Multiplicative.ofAdd ⁻¹' S
      zero_mem' := S.one_mem'
      add_mem' := fun ha hb => S.mul_mem' ha hb}
  left_inv x := by 

Proof state:
M : Type u_1
N : Type u_2
P : Type u_3
inst✝³ : MulOneClass M
inst✝² : MulOneClass N
inst✝¹ : MulOneClass P
S : Submonoid M
A : Type u_4
inst✝ : AddZeroClass A
x : AddSubmonoid A
⊢ (fun S =>
        {
          toAddSubsemigroup :=
            { carrier := ⇑Multiplicative.ofAdd ⁻¹' ↑S,
              add_mem' :=
                (_ :
                  ∀ {a b : A},
                    a ∈ ⇑Multiplicative.ofAdd ⁻¹' ↑S → b ∈ ⇑Multiplicative.ofAdd ⁻¹' ↑S → a * b ∈ S.carrier) },
          zero_mem' := (_ : 1 ∈ S.carrier) })
      ((fun S =>
          {
            toSubsemigroup :=
              { carrier := ⇑Multiplicative.toAdd ⁻¹' ↑S,
                mul_mem' :=
                  (_ :
                    ∀ {a b : Multiplicative A},
                      a ∈ ⇑Multiplicative.toAdd ⁻¹' ↑S →
                        b ∈ ⇑Multiplicative.toAdd ⁻¹' ↑S →
                          Multiplicative.toAdd a + Multiplicative.toAdd b ∈ S.carrier) },
            one_mem' := (_ : 0 ∈ S.carrier) })
        x) =
    x

Next tactic:
cases x
/-- Additive submonoids of an additive monoid `A` are isomorphic to
multiplicative submonoids of `Multiplicative A`. -/
@[simps]
def AddSubmonoid.toSubmonoid : AddSubmonoid A ≃o Submonoid (Multiplicative A) where
  toFun S :=
    { carrier := Multiplicative.toAdd ⁻¹' S
      one_mem' := S.zero_mem'
      mul_mem' := fun ha hb => S.add_mem' ha hb }
  invFun S :=
    { carrier := Multiplicative.ofAdd ⁻¹' S
      zero_mem' := S.one_mem'
      add_mem' := fun ha hb => S.mul_mem' ha hb}
  left_inv x := by cases x; 

Proof state:
case mk
M : Type u_1
N : Type u_2
P : Type u_3
inst✝³ : MulOneClass M
inst✝² : MulOneClass N
inst✝¹ : MulOneClass P
S : Submonoid M
A : Type u_4
inst✝ : AddZeroClass A
toAddSubsemigroup✝ : AddSubsemigroup A
zero_mem'✝ : 0 ∈ toAddSubsemigroup✝.carrier
⊢ (fun S =>
        {
          toAddSubsemigroup :=
            { carrier := ⇑Multiplicative.ofAdd ⁻¹' ↑S,
              add_mem' :=
                (_ :
                  ∀ {a b : A},
                    a ∈ ⇑Multiplicative.ofAdd ⁻¹' ↑S → b ∈ ⇑Multiplicative.ofAdd ⁻¹' ↑S → a * b ∈ S.carrier) },
          zero_mem' := (_ : 1 ∈ S.carrier) })
      ((fun S =>
          {
            toSubsemigroup :=
              { carrier := ⇑Multiplicative.toAdd ⁻¹' ↑S,
                mul_mem' :=
                  (_ :
                    ∀ {a b : Multiplicative A},
                      a ∈ ⇑Multiplicative.toAdd ⁻¹' ↑S →
                        b ∈ ⇑Multiplicative.toAdd ⁻¹' ↑S →
                          Multiplicative.toAdd a + Multiplicative.toAdd b ∈ S.carrier) },
            one_mem' := (_ : 0 ∈ S.carrier) })
        { toAddSubsemigroup := toAddSubsemigroup✝, zero_mem' := zero_mem'✝ }) =
    { toAddSubsemigroup := toAddSubsemigroup✝, zero_mem' := zero_mem'✝ }

Next tactic:
rfl
/-- Additive submonoids of an additive monoid `A` are isomorphic to
multiplicative submonoids of `Multiplicative A`. -/
@[simps]
def AddSubmonoid.toSubmonoid : AddSubmonoid A ≃o Submonoid (Multiplicative A) where
  toFun S :=
    { carrier := Multiplicative.toAdd ⁻¹' S
      one_mem' := S.zero_mem'
      mul_mem' := fun ha hb => S.add_mem' ha hb }
  invFun S :=
    { carrier := Multiplicative.ofAdd ⁻¹' S
      zero_mem' := S.one_mem'
      add_mem' := fun ha hb => S.mul_mem' ha hb}
  left_inv x := by cases x; rfl
  right_inv x := by 

Proof state:
M : Type u_1
N : Type u_2
P : Type u_3
inst✝³ : MulOneClass M
inst✝² : MulOneClass N
inst✝¹ : MulOneClass P
S : Submonoid M
A : Type u_4
inst✝ : AddZeroClass A
x : Submonoid (Multiplicative A)
⊢ (fun S =>
        {
          toSubsemigroup :=
            { carrier := ⇑Multiplicative.toAdd ⁻¹' ↑S,
              mul_mem' :=
                (_ :
                  ∀ {a b : Multiplicative A},
                    a ∈ ⇑Multiplicative.toAdd ⁻¹' ↑S →
                      b ∈ ⇑Multiplicative.toAdd ⁻¹' ↑S → Multiplicative.toAdd a + Multiplicative.toAdd b ∈ S.carrier) },
          one_mem' := (_ : 0 ∈ S.carrier) })
      ((fun S =>
          {
            toAddSubsemigroup :=
              { carrier := ⇑Multiplicative.ofAdd ⁻¹' ↑S,
                add_mem' :=
                  (_ :
                    ∀ {a b : A},
                      a ∈ ⇑Multiplicative.ofAdd ⁻¹' ↑S → b ∈ ⇑Multiplicative.ofAdd ⁻¹' ↑S → a * b ∈ S.carrier) },
            zero_mem' := (_ : 1 ∈ S.carrier) })
        x) =
    x

Next tactic:
cases x