l3lab/ntp-mathlib huggingface dataset:
theorem mem_closure_iff {s : Set R} {x} :
    x ∈ closure s ↔ x ∈ AddSubgroup.closure (Subsemigroup.closure s : Set R) :=
  ⟨fun h =>
    closure_induction h (fun x hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx)
      (AddSubgroup.zero_mem _) (fun x y hx hy => AddSubgroup.add_mem _ hx hy)
      (fun x hx => AddSubgroup.neg_mem _ hx) fun x y hx hy =>
      AddSubgroup.closure_induction hy
        (fun q hq =>
          AddSubgroup.closure_induction hx
            (fun p hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq))
            (by rw [zero_mul q]; 

Proof state:
F : Type w
R : Type u
S : Type v
T : Type u_1
inst✝³ : NonUnitalNonAssocRing R
inst✝² : NonUnitalNonAssocRing S
inst✝¹ : NonUnitalNonAssocRing T
inst✝ : NonUnitalRingHomClass F R S
g : S →ₙ+* T
f : R →ₙ+* S
s : Set R
x✝ : R
h : x✝ ∈ closure s
x y : R
hx : x ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
hy : y ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
q : R
hq : q ∈ ↑(Subsemigroup.closure s)
⊢ 0 ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)

Next tactic:
apply AddSubgroup.zero_mem _
theorem mem_closure_iff {s : Set R} {x} :
    x ∈ closure s ↔ x ∈ AddSubgroup.closure (Subsemigroup.closure s : Set R) :=
  ⟨fun h =>
    closure_induction h (fun x hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx)
      (AddSubgroup.zero_mem _) (fun x y hx hy => AddSubgroup.add_mem _ hx hy)
      (fun x hx => AddSubgroup.neg_mem _ hx) fun x y hx hy =>
      AddSubgroup.closure_induction hy
        (fun q hq =>
          AddSubgroup.closure_induction hx
            (fun p hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq))
            (by rw [zero_mul q]; apply AddSubgroup.zero_mem _)
            (fun p₁ p₂ ihp₁ ihp₂ => by 

Proof state:
F : Type w
R : Type u
S : Type v
T : Type u_1
inst✝³ : NonUnitalNonAssocRing R
inst✝² : NonUnitalNonAssocRing S
inst✝¹ : NonUnitalNonAssocRing T
inst✝ : NonUnitalRingHomClass F R S
g : S →ₙ+* T
f : R →ₙ+* S
s : Set R
x✝ : R
h : x✝ ∈ closure s
x y : R
hx : x ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
hy : y ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
q : R
hq : q ∈ ↑(Subsemigroup.closure s)
p₁ p₂ : R
ihp₁ : p₁ * q ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
ihp₂ : p₂ * q ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
⊢ (p₁ + p₂) * q ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)

Next tactic:
rw [add_mul p₁ p₂ q]
theorem mem_closure_iff {s : Set R} {x} :
    x ∈ closure s ↔ x ∈ AddSubgroup.closure (Subsemigroup.closure s : Set R) :=
  ⟨fun h =>
    closure_induction h (fun x hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx)
      (AddSubgroup.zero_mem _) (fun x y hx hy => AddSubgroup.add_mem _ hx hy)
      (fun x hx => AddSubgroup.neg_mem _ hx) fun x y hx hy =>
      AddSubgroup.closure_induction hy
        (fun q hq =>
          AddSubgroup.closure_induction hx
            (fun p hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq))
            (by rw [zero_mul q]; apply AddSubgroup.zero_mem _)
            (fun p₁ p₂ ihp₁ ihp₂ => by rw [add_mul p₁ p₂ q]; 

Proof state:
F : Type w
R : Type u
S : Type v
T : Type u_1
inst✝³ : NonUnitalNonAssocRing R
inst✝² : NonUnitalNonAssocRing S
inst✝¹ : NonUnitalNonAssocRing T
inst✝ : NonUnitalRingHomClass F R S
g : S →ₙ+* T
f : R →ₙ+* S
s : Set R
x✝ : R
h : x✝ ∈ closure s
x y : R
hx : x ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
hy : y ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
q : R
hq : q ∈ ↑(Subsemigroup.closure s)
p₁ p₂ : R
ihp₁ : p₁ * q ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
ihp₂ : p₂ * q ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
⊢ p₁ * q + p₂ * q ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)

Next tactic:
apply AddSubgroup.add_mem _ ihp₁ ihp₂
theorem mem_closure_iff {s : Set R} {x} :
    x ∈ closure s ↔ x ∈ AddSubgroup.closure (Subsemigroup.closure s : Set R) :=
  ⟨fun h =>
    closure_induction h (fun x hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx)
      (AddSubgroup.zero_mem _) (fun x y hx hy => AddSubgroup.add_mem _ hx hy)
      (fun x hx => AddSubgroup.neg_mem _ hx) fun x y hx hy =>
      AddSubgroup.closure_induction hy
        (fun q hq =>
          AddSubgroup.closure_induction hx
            (fun p hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq))
            (by rw [zero_mul q]; apply AddSubgroup.zero_mem _)
            (fun p₁ p₂ ihp₁ ihp₂ => by rw [add_mul p₁ p₂ q]; apply AddSubgroup.add_mem _ ihp₁ ihp₂)
            fun x hx => by
            

Proof state:
F : Type w
R : Type u
S : Type v
T : Type u_1
inst✝³ : NonUnitalNonAssocRing R
inst✝² : NonUnitalNonAssocRing S
inst✝¹ : NonUnitalNonAssocRing T
inst✝ : NonUnitalRingHomClass F R S
g : S →ₙ+* T
f : R →ₙ+* S
s : Set R
x✝¹ : R
h : x✝¹ ∈ closure s
x✝ y : R
hx✝ : x✝ ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
hy : y ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
q : R
hq : q ∈ ↑(Subsemigroup.closure s)
x : R
hx : x * q ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
⊢ -x * q ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)

Next tactic:
have f : -x * q = -(x * q) := by simp
theorem mem_closure_iff {s : Set R} {x} :
    x ∈ closure s ↔ x ∈ AddSubgroup.closure (Subsemigroup.closure s : Set R) :=
  ⟨fun h =>
    closure_induction h (fun x hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx)
      (AddSubgroup.zero_mem _) (fun x y hx hy => AddSubgroup.add_mem _ hx hy)
      (fun x hx => AddSubgroup.neg_mem _ hx) fun x y hx hy =>
      AddSubgroup.closure_induction hy
        (fun q hq =>
          AddSubgroup.closure_induction hx
            (fun p hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq))
            (by rw [zero_mul q]; apply AddSubgroup.zero_mem _)
            (fun p₁ p₂ ihp₁ ihp₂ => by rw [add_mul p₁ p₂ q]; apply AddSubgroup.add_mem _ ihp₁ ihp₂)
            fun x hx => by
            have f : -x * q = -(x * q) := by 

Proof state:
F : Type w
R : Type u
S : Type v
T : Type u_1
inst✝³ : NonUnitalNonAssocRing R
inst✝² : NonUnitalNonAssocRing S
inst✝¹ : NonUnitalNonAssocRing T
inst✝ : NonUnitalRingHomClass F R S
g : S →ₙ+* T
f : R →ₙ+* S
s : Set R
x✝¹ : R
h : x✝¹ ∈ closure s
x✝ y : R
hx✝ : x✝ ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
hy : y ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
q : R
hq : q ∈ ↑(Subsemigroup.closure s)
x : R
hx : x * q ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
⊢ -x * q = -(x * q)

Next tactic:
simp
theorem mem_closure_iff {s : Set R} {x} :
    x ∈ closure s ↔ x ∈ AddSubgroup.closure (Subsemigroup.closure s : Set R) :=
  ⟨fun h =>
    closure_induction h (fun x hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx)
      (AddSubgroup.zero_mem _) (fun x y hx hy => AddSubgroup.add_mem _ hx hy)
      (fun x hx => AddSubgroup.neg_mem _ hx) fun x y hx hy =>
      AddSubgroup.closure_induction hy
        (fun q hq =>
          AddSubgroup.closure_induction hx
            (fun p hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq))
            (by rw [zero_mul q]; apply AddSubgroup.zero_mem _)
            (fun p₁ p₂ ihp₁ ihp₂ => by rw [add_mul p₁ p₂ q]; apply AddSubgroup.add_mem _ ihp₁ ihp₂)
            fun x hx => by
            have f : -x * q = -(x * q) := by simp
            

Proof state:
F : Type w
R : Type u
S : Type v
T : Type u_1
inst✝³ : NonUnitalNonAssocRing R
inst✝² : NonUnitalNonAssocRing S
inst✝¹ : NonUnitalNonAssocRing T
inst✝ : NonUnitalRingHomClass F R S
g : S →ₙ+* T
f✝ : R →ₙ+* S
s : Set R
x✝¹ : R
h : x✝¹ ∈ closure s
x✝ y : R
hx✝ : x✝ ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
hy : y ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
q : R
hq : q ∈ ↑(Subsemigroup.closure s)
x : R
hx : x * q ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
f : -x * q = -(x * q)
⊢ -x * q ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)

Next tactic:
rw [f]
theorem mem_closure_iff {s : Set R} {x} :
    x ∈ closure s ↔ x ∈ AddSubgroup.closure (Subsemigroup.closure s : Set R) :=
  ⟨fun h =>
    closure_induction h (fun x hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx)
      (AddSubgroup.zero_mem _) (fun x y hx hy => AddSubgroup.add_mem _ hx hy)
      (fun x hx => AddSubgroup.neg_mem _ hx) fun x y hx hy =>
      AddSubgroup.closure_induction hy
        (fun q hq =>
          AddSubgroup.closure_induction hx
            (fun p hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq))
            (by rw [zero_mul q]; apply AddSubgroup.zero_mem _)
            (fun p₁ p₂ ihp₁ ihp₂ => by rw [add_mul p₁ p₂ q]; apply AddSubgroup.add_mem _ ihp₁ ihp₂)
            fun x hx => by
            have f : -x * q = -(x * q) := by simp
            rw [f]; 

Proof state:
F : Type w
R : Type u
S : Type v
T : Type u_1
inst✝³ : NonUnitalNonAssocRing R
inst✝² : NonUnitalNonAssocRing S
inst✝¹ : NonUnitalNonAssocRing T
inst✝ : NonUnitalRingHomClass F R S
g : S →ₙ+* T
f✝ : R →ₙ+* S
s : Set R
x✝¹ : R
h : x✝¹ ∈ closure s
x✝ y : R
hx✝ : x✝ ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
hy : y ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
q : R
hq : q ∈ ↑(Subsemigroup.closure s)
x : R
hx : x * q ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
f : -x * q = -(x * q)
⊢ -(x * q) ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)

Next tactic:
apply AddSubgroup.neg_mem _ hx
theorem mem_closure_iff {s : Set R} {x} :
    x ∈ closure s ↔ x ∈ AddSubgroup.closure (Subsemigroup.closure s : Set R) :=
  ⟨fun h =>
    closure_induction h (fun x hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx)
      (AddSubgroup.zero_mem _) (fun x y hx hy => AddSubgroup.add_mem _ hx hy)
      (fun x hx => AddSubgroup.neg_mem _ hx) fun x y hx hy =>
      AddSubgroup.closure_induction hy
        (fun q hq =>
          AddSubgroup.closure_induction hx
            (fun p hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq))
            (by rw [zero_mul q]; apply AddSubgroup.zero_mem _)
            (fun p₁ p₂ ihp₁ ihp₂ => by rw [add_mul p₁ p₂ q]; apply AddSubgroup.add_mem _ ihp₁ ihp₂)
            fun x hx => by
            have f : -x * q = -(x * q) := by simp
            rw [f]; apply AddSubgroup.neg_mem _ hx)
        (by 

Proof state:
F : Type w
R : Type u
S : Type v
T : Type u_1
inst✝³ : NonUnitalNonAssocRing R
inst✝² : NonUnitalNonAssocRing S
inst✝¹ : NonUnitalNonAssocRing T
inst✝ : NonUnitalRingHomClass F R S
g : S →ₙ+* T
f : R →ₙ+* S
s : Set R
x✝ : R
h : x✝ ∈ closure s
x y : R
hx : x ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
hy : y ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
⊢ x * 0 ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)

Next tactic:
rw [mul_zero x]
theorem mem_closure_iff {s : Set R} {x} :
    x ∈ closure s ↔ x ∈ AddSubgroup.closure (Subsemigroup.closure s : Set R) :=
  ⟨fun h =>
    closure_induction h (fun x hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx)
      (AddSubgroup.zero_mem _) (fun x y hx hy => AddSubgroup.add_mem _ hx hy)
      (fun x hx => AddSubgroup.neg_mem _ hx) fun x y hx hy =>
      AddSubgroup.closure_induction hy
        (fun q hq =>
          AddSubgroup.closure_induction hx
            (fun p hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq))
            (by rw [zero_mul q]; apply AddSubgroup.zero_mem _)
            (fun p₁ p₂ ihp₁ ihp₂ => by rw [add_mul p₁ p₂ q]; apply AddSubgroup.add_mem _ ihp₁ ihp₂)
            fun x hx => by
            have f : -x * q = -(x * q) := by simp
            rw [f]; apply AddSubgroup.neg_mem _ hx)
        (by rw [mul_zero x]; 

Proof state:
F : Type w
R : Type u
S : Type v
T : Type u_1
inst✝³ : NonUnitalNonAssocRing R
inst✝² : NonUnitalNonAssocRing S
inst✝¹ : NonUnitalNonAssocRing T
inst✝ : NonUnitalRingHomClass F R S
g : S →ₙ+* T
f : R →ₙ+* S
s : Set R
x✝ : R
h : x✝ ∈ closure s
x y : R
hx : x ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
hy : y ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
⊢ 0 ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)

Next tactic:
apply AddSubgroup.zero_mem _
theorem mem_closure_iff {s : Set R} {x} :
    x ∈ closure s ↔ x ∈ AddSubgroup.closure (Subsemigroup.closure s : Set R) :=
  ⟨fun h =>
    closure_induction h (fun x hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx)
      (AddSubgroup.zero_mem _) (fun x y hx hy => AddSubgroup.add_mem _ hx hy)
      (fun x hx => AddSubgroup.neg_mem _ hx) fun x y hx hy =>
      AddSubgroup.closure_induction hy
        (fun q hq =>
          AddSubgroup.closure_induction hx
            (fun p hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq))
            (by rw [zero_mul q]; apply AddSubgroup.zero_mem _)
            (fun p₁ p₂ ihp₁ ihp₂ => by rw [add_mul p₁ p₂ q]; apply AddSubgroup.add_mem _ ihp₁ ihp₂)
            fun x hx => by
            have f : -x * q = -(x * q) := by simp
            rw [f]; apply AddSubgroup.neg_mem _ hx)
        (by rw [mul_zero x]; apply AddSubgroup.zero_mem _)
        (fun q₁ q₂ ihq₁ ihq₂ => by 

Proof state:
F : Type w
R : Type u
S : Type v
T : Type u_1
inst✝³ : NonUnitalNonAssocRing R
inst✝² : NonUnitalNonAssocRing S
inst✝¹ : NonUnitalNonAssocRing T
inst✝ : NonUnitalRingHomClass F R S
g : S →ₙ+* T
f : R →ₙ+* S
s : Set R
x✝ : R
h : x✝ ∈ closure s
x y : R
hx : x ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
hy : y ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
q₁ q₂ : R
ihq₁ : x * q₁ ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
ihq₂ : x * q₂ ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
⊢ x * (q₁ + q₂) ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)

Next tactic:
rw [mul_add x q₁ q₂]
theorem mem_closure_iff {s : Set R} {x} :
    x ∈ closure s ↔ x ∈ AddSubgroup.closure (Subsemigroup.closure s : Set R) :=
  ⟨fun h =>
    closure_induction h (fun x hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx)
      (AddSubgroup.zero_mem _) (fun x y hx hy => AddSubgroup.add_mem _ hx hy)
      (fun x hx => AddSubgroup.neg_mem _ hx) fun x y hx hy =>
      AddSubgroup.closure_induction hy
        (fun q hq =>
          AddSubgroup.closure_induction hx
            (fun p hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq))
            (by rw [zero_mul q]; apply AddSubgroup.zero_mem _)
            (fun p₁ p₂ ihp₁ ihp₂ => by rw [add_mul p₁ p₂ q]; apply AddSubgroup.add_mem _ ihp₁ ihp₂)
            fun x hx => by
            have f : -x * q = -(x * q) := by simp
            rw [f]; apply AddSubgroup.neg_mem _ hx)
        (by rw [mul_zero x]; apply AddSubgroup.zero_mem _)
        (fun q₁ q₂ ihq₁ ihq₂ => by rw [mul_add x q₁ q₂]; 

Proof state:
F : Type w
R : Type u
S : Type v
T : Type u_1
inst✝³ : NonUnitalNonAssocRing R
inst✝² : NonUnitalNonAssocRing S
inst✝¹ : NonUnitalNonAssocRing T
inst✝ : NonUnitalRingHomClass F R S
g : S →ₙ+* T
f : R →ₙ+* S
s : Set R
x✝ : R
h : x✝ ∈ closure s
x y : R
hx : x ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
hy : y ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
q₁ q₂ : R
ihq₁ : x * q₁ ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
ihq₂ : x * q₂ ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
⊢ x * q₁ + x * q₂ ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)

Next tactic:
apply AddSubgroup.add_mem _ ihq₁ ihq₂
theorem mem_closure_iff {s : Set R} {x} :
    x ∈ closure s ↔ x ∈ AddSubgroup.closure (Subsemigroup.closure s : Set R) :=
  ⟨fun h =>
    closure_induction h (fun x hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx)
      (AddSubgroup.zero_mem _) (fun x y hx hy => AddSubgroup.add_mem _ hx hy)
      (fun x hx => AddSubgroup.neg_mem _ hx) fun x y hx hy =>
      AddSubgroup.closure_induction hy
        (fun q hq =>
          AddSubgroup.closure_induction hx
            (fun p hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq))
            (by rw [zero_mul q]; apply AddSubgroup.zero_mem _)
            (fun p₁ p₂ ihp₁ ihp₂ => by rw [add_mul p₁ p₂ q]; apply AddSubgroup.add_mem _ ihp₁ ihp₂)
            fun x hx => by
            have f : -x * q = -(x * q) := by simp
            rw [f]; apply AddSubgroup.neg_mem _ hx)
        (by rw [mul_zero x]; apply AddSubgroup.zero_mem _)
        (fun q₁ q₂ ihq₁ ihq₂ => by rw [mul_add x q₁ q₂]; apply AddSubgroup.add_mem _ ihq₁ ihq₂)
        fun z hz => by
        

Proof state:
F : Type w
R : Type u
S : Type v
T : Type u_1
inst✝³ : NonUnitalNonAssocRing R
inst✝² : NonUnitalNonAssocRing S
inst✝¹ : NonUnitalNonAssocRing T
inst✝ : NonUnitalRingHomClass F R S
g : S →ₙ+* T
f : R →ₙ+* S
s : Set R
x✝ : R
h : x✝ ∈ closure s
x y : R
hx : x ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
hy : y ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
z : R
hz : x * z ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
⊢ x * -z ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)

Next tactic:
have f : x * -z = -(x * z) := by simp
theorem mem_closure_iff {s : Set R} {x} :
    x ∈ closure s ↔ x ∈ AddSubgroup.closure (Subsemigroup.closure s : Set R) :=
  ⟨fun h =>
    closure_induction h (fun x hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx)
      (AddSubgroup.zero_mem _) (fun x y hx hy => AddSubgroup.add_mem _ hx hy)
      (fun x hx => AddSubgroup.neg_mem _ hx) fun x y hx hy =>
      AddSubgroup.closure_induction hy
        (fun q hq =>
          AddSubgroup.closure_induction hx
            (fun p hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq))
            (by rw [zero_mul q]; apply AddSubgroup.zero_mem _)
            (fun p₁ p₂ ihp₁ ihp₂ => by rw [add_mul p₁ p₂ q]; apply AddSubgroup.add_mem _ ihp₁ ihp₂)
            fun x hx => by
            have f : -x * q = -(x * q) := by simp
            rw [f]; apply AddSubgroup.neg_mem _ hx)
        (by rw [mul_zero x]; apply AddSubgroup.zero_mem _)
        (fun q₁ q₂ ihq₁ ihq₂ => by rw [mul_add x q₁ q₂]; apply AddSubgroup.add_mem _ ihq₁ ihq₂)
        fun z hz => by
        have f : x * -z = -(x * z) := by 

Proof state:
F : Type w
R : Type u
S : Type v
T : Type u_1
inst✝³ : NonUnitalNonAssocRing R
inst✝² : NonUnitalNonAssocRing S
inst✝¹ : NonUnitalNonAssocRing T
inst✝ : NonUnitalRingHomClass F R S
g : S →ₙ+* T
f : R →ₙ+* S
s : Set R
x✝ : R
h : x✝ ∈ closure s
x y : R
hx : x ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
hy : y ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
z : R
hz : x * z ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
⊢ x * -z = -(x * z)

Next tactic:
simp
theorem mem_closure_iff {s : Set R} {x} :
    x ∈ closure s ↔ x ∈ AddSubgroup.closure (Subsemigroup.closure s : Set R) :=
  ⟨fun h =>
    closure_induction h (fun x hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx)
      (AddSubgroup.zero_mem _) (fun x y hx hy => AddSubgroup.add_mem _ hx hy)
      (fun x hx => AddSubgroup.neg_mem _ hx) fun x y hx hy =>
      AddSubgroup.closure_induction hy
        (fun q hq =>
          AddSubgroup.closure_induction hx
            (fun p hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq))
            (by rw [zero_mul q]; apply AddSubgroup.zero_mem _)
            (fun p₁ p₂ ihp₁ ihp₂ => by rw [add_mul p₁ p₂ q]; apply AddSubgroup.add_mem _ ihp₁ ihp₂)
            fun x hx => by
            have f : -x * q = -(x * q) := by simp
            rw [f]; apply AddSubgroup.neg_mem _ hx)
        (by rw [mul_zero x]; apply AddSubgroup.zero_mem _)
        (fun q₁ q₂ ihq₁ ihq₂ => by rw [mul_add x q₁ q₂]; apply AddSubgroup.add_mem _ ihq₁ ihq₂)
        fun z hz => by
        have f : x * -z = -(x * z) := by simp
        

Proof state:
F : Type w
R : Type u
S : Type v
T : Type u_1
inst✝³ : NonUnitalNonAssocRing R
inst✝² : NonUnitalNonAssocRing S
inst✝¹ : NonUnitalNonAssocRing T
inst✝ : NonUnitalRingHomClass F R S
g : S →ₙ+* T
f✝ : R →ₙ+* S
s : Set R
x✝ : R
h : x✝ ∈ closure s
x y : R
hx : x ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
hy : y ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
z : R
hz : x * z ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
f : x * -z = -(x * z)
⊢ x * -z ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)

Next tactic:
rw [f]
theorem mem_closure_iff {s : Set R} {x} :
    x ∈ closure s ↔ x ∈ AddSubgroup.closure (Subsemigroup.closure s : Set R) :=
  ⟨fun h =>
    closure_induction h (fun x hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx)
      (AddSubgroup.zero_mem _) (fun x y hx hy => AddSubgroup.add_mem _ hx hy)
      (fun x hx => AddSubgroup.neg_mem _ hx) fun x y hx hy =>
      AddSubgroup.closure_induction hy
        (fun q hq =>
          AddSubgroup.closure_induction hx
            (fun p hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq))
            (by rw [zero_mul q]; apply AddSubgroup.zero_mem _)
            (fun p₁ p₂ ihp₁ ihp₂ => by rw [add_mul p₁ p₂ q]; apply AddSubgroup.add_mem _ ihp₁ ihp₂)
            fun x hx => by
            have f : -x * q = -(x * q) := by simp
            rw [f]; apply AddSubgroup.neg_mem _ hx)
        (by rw [mul_zero x]; apply AddSubgroup.zero_mem _)
        (fun q₁ q₂ ihq₁ ihq₂ => by rw [mul_add x q₁ q₂]; apply AddSubgroup.add_mem _ ihq₁ ihq₂)
        fun z hz => by
        have f : x * -z = -(x * z) := by simp
        rw [f]; 

Proof state:
F : Type w
R : Type u
S : Type v
T : Type u_1
inst✝³ : NonUnitalNonAssocRing R
inst✝² : NonUnitalNonAssocRing S
inst✝¹ : NonUnitalNonAssocRing T
inst✝ : NonUnitalRingHomClass F R S
g : S →ₙ+* T
f✝ : R →ₙ+* S
s : Set R
x✝ : R
h : x✝ ∈ closure s
x y : R
hx : x ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
hy : y ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
z : R
hz : x * z ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)
f : x * -z = -(x * z)
⊢ -(x * z) ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)

Next tactic:
apply AddSubgroup.neg_mem _ hz
/-- If all elements of `s : Set A` commute pairwise, then `closure s` is a commutative ring.  -/
def closureNonUnitalCommRingOfComm {R : Type u} [NonUnitalRing R] {s : Set R}
    (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) : NonUnitalCommRing (closure s) :=
  { (closure s).toNonUnitalRing with
    mul_comm := fun x y => by
      

Proof state:
F : Type w
R✝ : Type u
S : Type v
T : Type u_1
inst✝⁴ : NonUnitalNonAssocRing R✝
inst✝³ : NonUnitalNonAssocRing S
inst✝² : NonUnitalNonAssocRing T
inst✝¹ : NonUnitalRingHomClass F R✝ S
g : S →ₙ+* T
f : R✝ →ₙ+* S
R : Type u
inst✝ : NonUnitalRing R
s : Set R
hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a
src✝ : NonUnitalRing ↥(closure s) := toNonUnitalRing (closure s)
x y : ↥(closure s)
⊢ x * y = y * x

Next tactic:
ext
/-- If all elements of `s : Set A` commute pairwise, then `closure s` is a commutative ring.  -/
def closureNonUnitalCommRingOfComm {R : Type u} [NonUnitalRing R] {s : Set R}
    (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) : NonUnitalCommRing (closure s) :=
  { (closure s).toNonUnitalRing with
    mul_comm := fun x y => by
      ext
      

Proof state:
case a
F : Type w
R✝ : Type u
S : Type v
T : Type u_1
inst✝⁴ : NonUnitalNonAssocRing R✝
inst✝³ : NonUnitalNonAssocRing S
inst✝² : NonUnitalNonAssocRing T
inst✝¹ : NonUnitalRingHomClass F R✝ S
g : S →ₙ+* T
f : R✝ →ₙ+* S
R : Type u
inst✝ : NonUnitalRing R
s : Set R
hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a
src✝ : NonUnitalRing ↥(closure s) := toNonUnitalRing (closure s)
x y : ↥(closure s)
⊢ ↑(x * y) = ↑(y * x)

Next tactic:
simp only [NonUnitalSubring.val_mul]