l3lab/ntp-mathlib huggingface dataset:
theorem coe_eq_zero_iff {x : s} : (x : R) = 0 ↔ x = 0 := by
  

Proof state:
R : Type u
S : Type v
T : Type w
inst✝² : NonUnitalNonAssocRing R
inst✝¹ : NonUnitalNonAssocRing S
inst✝ : NonUnitalNonAssocRing T
s : NonUnitalSubring R
x : ↥s
⊢ ↑x = 0 ↔ x = 0

Next tactic:
simp
theorem range_eq_map (f : R →ₙ+* S) : f.range = NonUnitalSubring.map f ⊤ := by 

Proof state:
R : Type u
S : Type v
T : Type u_1
inst✝² : NonUnitalNonAssocRing R
inst✝¹ : NonUnitalNonAssocRing S
inst✝ : NonUnitalNonAssocRing T
g : S →ₙ+* T
f✝ f : R →ₙ+* S
⊢ range f = NonUnitalSubring.map f ⊤

Next tactic:
ext
theorem range_eq_map (f : R →ₙ+* S) : f.range = NonUnitalSubring.map f ⊤ := by ext; 

Proof state:
case h
R : Type u
S : Type v
T : Type u_1
inst✝² : NonUnitalNonAssocRing R
inst✝¹ : NonUnitalNonAssocRing S
inst✝ : NonUnitalNonAssocRing T
g : S →ₙ+* T
f✝ f : R →ₙ+* S
x✝ : S
⊢ x✝ ∈ range f ↔ x✝ ∈ NonUnitalSubring.map f ⊤

Next tactic:
simp
theorem map_range : f.range.map g = (g.comp f).range := by
  

Proof state:
R : Type u
S : Type v
T : Type u_1
inst✝² : NonUnitalNonAssocRing R
inst✝¹ : NonUnitalNonAssocRing S
inst✝ : NonUnitalNonAssocRing T
g : S →ₙ+* T
f : R →ₙ+* S
⊢ NonUnitalSubring.map g (range f) = range (comp g f)

Next tactic:
simpa only [range_eq_map] using (⊤ : NonUnitalSubring R).map_map g f
theorem mem_bot {x : R} : x ∈ (⊥ : NonUnitalSubring R) ↔ x = 0 :=
  show x ∈ ((⊥ : NonUnitalSubring R) : Set R) ↔ x = 0 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
x : R
⊢ x ∈ ↑⊥ ↔ x = 0

Next tactic:
rw [coe_bot, Set.mem_singleton_iff]
instance : InfSet (NonUnitalSubring R) :=
  ⟨fun s =>
    NonUnitalSubring.mk' (⋂ t ∈ s, ↑t) (⨅ t ∈ s, NonUnitalSubring.toSubsemigroup t)
      (⨅ t ∈ s, NonUnitalSubring.toAddSubgroup t) (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 (NonUnitalSubring R)
⊢ ↑(⨅ t ∈ s, toSubsemigroup t) = ⋂ t ∈ s, ↑t

Next tactic:
simp
instance : InfSet (NonUnitalSubring R) :=
  ⟨fun s =>
    NonUnitalSubring.mk' (⋂ t ∈ s, ↑t) (⨅ t ∈ s, NonUnitalSubring.toSubsemigroup t)
      (⨅ t ∈ s, NonUnitalSubring.toAddSubgroup t) (by simp) (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 (NonUnitalSubring R)
⊢ ↑(⨅ t ∈ s, toAddSubgroup t) = ⋂ t ∈ s, ↑t

Next tactic:
simp
@[simp, norm_cast]
theorem coe_iInf {ι : Sort*} {S : ι → NonUnitalSubring R} : (↑(⨅ i, S i) : Set R) = ⋂ i, S i := 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✝
ι : Sort u_2
S : ι → NonUnitalSubring R
⊢ ↑(⨅ i, S i) = ⋂ i, ↑(S i)

Next tactic:
simp only [iInf, coe_sInf, Set.biInter_range]
theorem mem_iInf {ι : Sort*} {S : ι → NonUnitalSubring R} {x : R} :
    (x ∈ ⨅ i, S i) ↔ ∀ i, x ∈ S i := 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✝
ι : Sort u_2
S : ι → NonUnitalSubring R
x : R
⊢ x ∈ ⨅ i, S i ↔ ∀ (i : ι), x ∈ S i

Next tactic:
simp only [iInf, mem_sInf, Set.forall_range_iff]
/-- The difference with `NonUnitalSubring.closure_induction` is that this acts on the
subtype. -/
@[elab_as_elim]
theorem closure_induction' {s : Set R} {p : closure s → Prop} (a : closure s)
    (Hs : ∀ (x) (hx : x ∈ s), p ⟨x, subset_closure hx⟩) (H0 : p 0)
    (Hadd : ∀ x y, p x → p y → p (x + y)) (Hneg : ∀ x, p x → p (-x))
    (Hmul : ∀ x y, p x → p y → p (x * y)) : p a :=
  Subtype.recOn a fun b hb => 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
p : ↥(closure s) → Prop
a : ↥(closure s)
Hs : ∀ (x : R) (hx : x ∈ s), p { val := x, property := (_ : x ∈ ↑(closure s)) }
H0 : p 0
Hadd : ∀ (x y : ↥(closure s)), p x → p y → p (x + y)
Hneg : ∀ (x : ↥(closure s)), p x → p (-x)
Hmul : ∀ (x y : ↥(closure s)), p x → p y → p (x * y)
b : R
hb : b ∈ closure s
⊢ p { val := b, property := hb }

Next tactic:
refine' Exists.elim _ fun (hb : b ∈ closure s) (hc : p ⟨b, hb⟩) => hc
/-- The difference with `NonUnitalSubring.closure_induction` is that this acts on the
subtype. -/
@[elab_as_elim]
theorem closure_induction' {s : Set R} {p : closure s → Prop} (a : closure s)
    (Hs : ∀ (x) (hx : x ∈ s), p ⟨x, subset_closure hx⟩) (H0 : p 0)
    (Hadd : ∀ x y, p x → p y → p (x + y)) (Hneg : ∀ x, p x → p (-x))
    (Hmul : ∀ x y, p x → p y → p (x * y)) : p a :=
  Subtype.recOn a fun b hb => by
    refine' Exists.elim _ fun (hb : b ∈ closure s) (hc : p ⟨b, hb⟩) => hc
    

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
p : ↥(closure s) → Prop
a : ↥(closure s)
Hs : ∀ (x : R) (hx : x ∈ s), p { val := x, property := (_ : x ∈ ↑(closure s)) }
H0 : p 0
Hadd : ∀ (x y : ↥(closure s)), p x → p y → p (x + y)
Hneg : ∀ (x : ↥(closure s)), p x → p (-x)
Hmul : ∀ (x y : ↥(closure s)), p x → p y → p (x * y)
b : R
hb : b ∈ closure s
⊢ ∃ (x : b ∈ closure s), p { val := b, property := x }

Next tactic:
refine'
      closure_induction hb (fun x hx => ⟨subset_closure hx, Hs x hx⟩) ⟨zero_mem (closure s), H0⟩ _ _
        _
/-- The difference with `NonUnitalSubring.closure_induction` is that this acts on the
subtype. -/
@[elab_as_elim]
theorem closure_induction' {s : Set R} {p : closure s → Prop} (a : closure s)
    (Hs : ∀ (x) (hx : x ∈ s), p ⟨x, subset_closure hx⟩) (H0 : p 0)
    (Hadd : ∀ x y, p x → p y → p (x + y)) (Hneg : ∀ x, p x → p (-x))
    (Hmul : ∀ x y, p x → p y → p (x * y)) : p a :=
  Subtype.recOn a fun b hb => by
    refine' Exists.elim _ fun (hb : b ∈ closure s) (hc : p ⟨b, hb⟩) => hc
    refine'
      closure_induction hb (fun x hx => ⟨subset_closure hx, Hs x hx⟩) ⟨zero_mem (closure s), H0⟩ _ _
        _
    · 

Proof state:
case refine'_1
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
p : ↥(closure s) → Prop
a : ↥(closure s)
Hs : ∀ (x : R) (hx : x ∈ s), p { val := x, property := (_ : x ∈ ↑(closure s)) }
H0 : p 0
Hadd : ∀ (x y : ↥(closure s)), p x → p y → p (x + y)
Hneg : ∀ (x : ↥(closure s)), p x → p (-x)
Hmul : ∀ (x y : ↥(closure s)), p x → p y → p (x * y)
b : R
hb : b ∈ closure s
⊢ ∀ (x y : R),
    (∃ (x_1 : x ∈ closure s), p { val := x, property := x_1 }) →
      (∃ (x : y ∈ closure s), p { val := y, property := x }) →
        ∃ (x_1 : x + y ∈ closure s), p { val := x + y, property := x_1 }

Next tactic:
rintro x y ⟨hx, hpx⟩ ⟨hy, hpy⟩
/-- The difference with `NonUnitalSubring.closure_induction` is that this acts on the
subtype. -/
@[elab_as_elim]
theorem closure_induction' {s : Set R} {p : closure s → Prop} (a : closure s)
    (Hs : ∀ (x) (hx : x ∈ s), p ⟨x, subset_closure hx⟩) (H0 : p 0)
    (Hadd : ∀ x y, p x → p y → p (x + y)) (Hneg : ∀ x, p x → p (-x))
    (Hmul : ∀ x y, p x → p y → p (x * y)) : p a :=
  Subtype.recOn a fun b hb => by
    refine' Exists.elim _ fun (hb : b ∈ closure s) (hc : p ⟨b, hb⟩) => hc
    refine'
      closure_induction hb (fun x hx => ⟨subset_closure hx, Hs x hx⟩) ⟨zero_mem (closure s), H0⟩ _ _
        _
    · rintro x y ⟨hx, hpx⟩ ⟨hy, hpy⟩
      

Proof state:
case refine'_1.intro.intro
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
p : ↥(closure s) → Prop
a : ↥(closure s)
Hs : ∀ (x : R) (hx : x ∈ s), p { val := x, property := (_ : x ∈ ↑(closure s)) }
H0 : p 0
Hadd : ∀ (x y : ↥(closure s)), p x → p y → p (x + y)
Hneg : ∀ (x : ↥(closure s)), p x → p (-x)
Hmul : ∀ (x y : ↥(closure s)), p x → p y → p (x * y)
b : R
hb : b ∈ closure s
x y : R
hx : x ∈ closure s
hpx : p { val := x, property := hx }
hy : y ∈ closure s
hpy : p { val := y, property := hy }
⊢ ∃ (x_1 : x + y ∈ closure s), p { val := x + y, property := x_1 }

Next tactic:
exact ⟨add_mem hx hy, Hadd _ _ hpx hpy⟩
/-- The difference with `NonUnitalSubring.closure_induction` is that this acts on the
subtype. -/
@[elab_as_elim]
theorem closure_induction' {s : Set R} {p : closure s → Prop} (a : closure s)
    (Hs : ∀ (x) (hx : x ∈ s), p ⟨x, subset_closure hx⟩) (H0 : p 0)
    (Hadd : ∀ x y, p x → p y → p (x + y)) (Hneg : ∀ x, p x → p (-x))
    (Hmul : ∀ x y, p x → p y → p (x * y)) : p a :=
  Subtype.recOn a fun b hb => by
    refine' Exists.elim _ fun (hb : b ∈ closure s) (hc : p ⟨b, hb⟩) => hc
    refine'
      closure_induction hb (fun x hx => ⟨subset_closure hx, Hs x hx⟩) ⟨zero_mem (closure s), H0⟩ _ _
        _
    · rintro x y ⟨hx, hpx⟩ ⟨hy, hpy⟩
      exact ⟨add_mem hx hy, Hadd _ _ hpx hpy⟩
    · 

Proof state:
case refine'_2
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
p : ↥(closure s) → Prop
a : ↥(closure s)
Hs : ∀ (x : R) (hx : x ∈ s), p { val := x, property := (_ : x ∈ ↑(closure s)) }
H0 : p 0
Hadd : ∀ (x y : ↥(closure s)), p x → p y → p (x + y)
Hneg : ∀ (x : ↥(closure s)), p x → p (-x)
Hmul : ∀ (x y : ↥(closure s)), p x → p y → p (x * y)
b : R
hb : b ∈ closure s
⊢ ∀ (x : R),
    (∃ (x_1 : x ∈ closure s), p { val := x, property := x_1 }) →
      ∃ (x_1 : -x ∈ closure s), p { val := -x, property := x_1 }

Next tactic:
rintro x ⟨hx, hpx⟩
/-- The difference with `NonUnitalSubring.closure_induction` is that this acts on the
subtype. -/
@[elab_as_elim]
theorem closure_induction' {s : Set R} {p : closure s → Prop} (a : closure s)
    (Hs : ∀ (x) (hx : x ∈ s), p ⟨x, subset_closure hx⟩) (H0 : p 0)
    (Hadd : ∀ x y, p x → p y → p (x + y)) (Hneg : ∀ x, p x → p (-x))
    (Hmul : ∀ x y, p x → p y → p (x * y)) : p a :=
  Subtype.recOn a fun b hb => by
    refine' Exists.elim _ fun (hb : b ∈ closure s) (hc : p ⟨b, hb⟩) => hc
    refine'
      closure_induction hb (fun x hx => ⟨subset_closure hx, Hs x hx⟩) ⟨zero_mem (closure s), H0⟩ _ _
        _
    · rintro x y ⟨hx, hpx⟩ ⟨hy, hpy⟩
      exact ⟨add_mem hx hy, Hadd _ _ hpx hpy⟩
    · rintro x ⟨hx, hpx⟩
      

Proof state:
case refine'_2.intro
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
p : ↥(closure s) → Prop
a : ↥(closure s)
Hs : ∀ (x : R) (hx : x ∈ s), p { val := x, property := (_ : x ∈ ↑(closure s)) }
H0 : p 0
Hadd : ∀ (x y : ↥(closure s)), p x → p y → p (x + y)
Hneg : ∀ (x : ↥(closure s)), p x → p (-x)
Hmul : ∀ (x y : ↥(closure s)), p x → p y → p (x * y)
b : R
hb : b ∈ closure s
x : R
hx : x ∈ closure s
hpx : p { val := x, property := hx }
⊢ ∃ (x_1 : -x ∈ closure s), p { val := -x, property := x_1 }

Next tactic:
exact ⟨neg_mem hx, Hneg _ hpx⟩
/-- The difference with `NonUnitalSubring.closure_induction` is that this acts on the
subtype. -/
@[elab_as_elim]
theorem closure_induction' {s : Set R} {p : closure s → Prop} (a : closure s)
    (Hs : ∀ (x) (hx : x ∈ s), p ⟨x, subset_closure hx⟩) (H0 : p 0)
    (Hadd : ∀ x y, p x → p y → p (x + y)) (Hneg : ∀ x, p x → p (-x))
    (Hmul : ∀ x y, p x → p y → p (x * y)) : p a :=
  Subtype.recOn a fun b hb => by
    refine' Exists.elim _ fun (hb : b ∈ closure s) (hc : p ⟨b, hb⟩) => hc
    refine'
      closure_induction hb (fun x hx => ⟨subset_closure hx, Hs x hx⟩) ⟨zero_mem (closure s), H0⟩ _ _
        _
    · rintro x y ⟨hx, hpx⟩ ⟨hy, hpy⟩
      exact ⟨add_mem hx hy, Hadd _ _ hpx hpy⟩
    · rintro x ⟨hx, hpx⟩
      exact ⟨neg_mem hx, Hneg _ hpx⟩
    · 

Proof state:
case refine'_3
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
p : ↥(closure s) → Prop
a : ↥(closure s)
Hs : ∀ (x : R) (hx : x ∈ s), p { val := x, property := (_ : x ∈ ↑(closure s)) }
H0 : p 0
Hadd : ∀ (x y : ↥(closure s)), p x → p y → p (x + y)
Hneg : ∀ (x : ↥(closure s)), p x → p (-x)
Hmul : ∀ (x y : ↥(closure s)), p x → p y → p (x * y)
b : R
hb : b ∈ closure s
⊢ ∀ (x y : R),
    (∃ (x_1 : x ∈ closure s), p { val := x, property := x_1 }) →
      (∃ (x : y ∈ closure s), p { val := y, property := x }) →
        ∃ (x_1 : x * y ∈ closure s), p { val := x * y, property := x_1 }

Next tactic:
rintro x y ⟨hx, hpx⟩ ⟨hy, hpy⟩
/-- The difference with `NonUnitalSubring.closure_induction` is that this acts on the
subtype. -/
@[elab_as_elim]
theorem closure_induction' {s : Set R} {p : closure s → Prop} (a : closure s)
    (Hs : ∀ (x) (hx : x ∈ s), p ⟨x, subset_closure hx⟩) (H0 : p 0)
    (Hadd : ∀ x y, p x → p y → p (x + y)) (Hneg : ∀ x, p x → p (-x))
    (Hmul : ∀ x y, p x → p y → p (x * y)) : p a :=
  Subtype.recOn a fun b hb => by
    refine' Exists.elim _ fun (hb : b ∈ closure s) (hc : p ⟨b, hb⟩) => hc
    refine'
      closure_induction hb (fun x hx => ⟨subset_closure hx, Hs x hx⟩) ⟨zero_mem (closure s), H0⟩ _ _
        _
    · rintro x y ⟨hx, hpx⟩ ⟨hy, hpy⟩
      exact ⟨add_mem hx hy, Hadd _ _ hpx hpy⟩
    · rintro x ⟨hx, hpx⟩
      exact ⟨neg_mem hx, Hneg _ hpx⟩
    · rintro x y ⟨hx, hpx⟩ ⟨hy, hpy⟩
      

Proof state:
case refine'_3.intro.intro
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
p : ↥(closure s) → Prop
a : ↥(closure s)
Hs : ∀ (x : R) (hx : x ∈ s), p { val := x, property := (_ : x ∈ ↑(closure s)) }
H0 : p 0
Hadd : ∀ (x y : ↥(closure s)), p x → p y → p (x + y)
Hneg : ∀ (x : ↥(closure s)), p x → p (-x)
Hmul : ∀ (x y : ↥(closure s)), p x → p y → p (x * y)
b : R
hb : b ∈ closure s
x y : R
hx : x ∈ closure s
hpx : p { val := x, property := hx }
hy : y ∈ closure s
hpy : p { val := y, property := hy }
⊢ ∃ (x_1 : x * y ∈ closure s), p { val := x * y, property := x_1 }

Next tactic:
exact ⟨mul_mem hx hy, Hmul _ _ hpx hpy⟩
/-- An induction principle for closure membership, for predicates with two arguments. -/
@[elab_as_elim]
theorem closure_induction₂ {s : Set R} {p : R → R → Prop} {a b : R} (ha : a ∈ closure s)
    (hb : b ∈ closure s) (Hs : ∀ x ∈ s, ∀ y ∈ s, p x y) (H0_left : ∀ x, p 0 x)
    (H0_right : ∀ x, p x 0) (Hneg_left : ∀ x y, p x y → p (-x) y)
    (Hneg_right : ∀ x y, p x y → p x (-y)) (Hadd_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ + x₂) y)
    (Hadd_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ + y₂))
    (Hmul_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ * x₂) y)
    (Hmul_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ * y₂)) : p a b := 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
p : R → R → Prop
a b : R
ha : a ∈ closure s
hb : b ∈ closure s
Hs : ∀ x ∈ s, ∀ y ∈ s, p x y
H0_left : ∀ (x : R), p 0 x
H0_right : ∀ (x : R), p x 0
Hneg_left : ∀ (x y : R), p x y → p (-x) y
Hneg_right : ∀ (x y : R), p x y → p x (-y)
Hadd_left : ∀ (x₁ x₂ y : R), p x₁ y → p x₂ y → p (x₁ + x₂) y
Hadd_right : ∀ (x y₁ y₂ : R), p x y₁ → p x y₂ → p x (y₁ + y₂)
Hmul_left : ∀ (x₁ x₂ y : R), p x₁ y → p x₂ y → p (x₁ * x₂) y
Hmul_right : ∀ (x y₁ y₂ : R), p x y₁ → p x y₂ → p x (y₁ * y₂)
⊢ p a b

Next tactic:
refine' closure_induction hb _ (H0_right _) (Hadd_right a) (Hneg_right a) (Hmul_right a)
/-- An induction principle for closure membership, for predicates with two arguments. -/
@[elab_as_elim]
theorem closure_induction₂ {s : Set R} {p : R → R → Prop} {a b : R} (ha : a ∈ closure s)
    (hb : b ∈ closure s) (Hs : ∀ x ∈ s, ∀ y ∈ s, p x y) (H0_left : ∀ x, p 0 x)
    (H0_right : ∀ x, p x 0) (Hneg_left : ∀ x y, p x y → p (-x) y)
    (Hneg_right : ∀ x y, p x y → p x (-y)) (Hadd_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ + x₂) y)
    (Hadd_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ + y₂))
    (Hmul_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ * x₂) y)
    (Hmul_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ * y₂)) : p a b := by
  refine' closure_induction hb _ (H0_right _) (Hadd_right a) (Hneg_right a) (Hmul_right a)
  

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
p : R → R → Prop
a b : R
ha : a ∈ closure s
hb : b ∈ closure s
Hs : ∀ x ∈ s, ∀ y ∈ s, p x y
H0_left : ∀ (x : R), p 0 x
H0_right : ∀ (x : R), p x 0
Hneg_left : ∀ (x y : R), p x y → p (-x) y
Hneg_right : ∀ (x y : R), p x y → p x (-y)
Hadd_left : ∀ (x₁ x₂ y : R), p x₁ y → p x₂ y → p (x₁ + x₂) y
Hadd_right : ∀ (x y₁ y₂ : R), p x y₁ → p x y₂ → p x (y₁ + y₂)
Hmul_left : ∀ (x₁ x₂ y : R), p x₁ y → p x₂ y → p (x₁ * x₂) y
Hmul_right : ∀ (x y₁ y₂ : R), p x y₁ → p x y₂ → p x (y₁ * y₂)
⊢ ∀ x ∈ s, p a x

Next tactic:
refine' closure_induction ha Hs (fun x _ => H0_left x) _ _ _
/-- An induction principle for closure membership, for predicates with two arguments. -/
@[elab_as_elim]
theorem closure_induction₂ {s : Set R} {p : R → R → Prop} {a b : R} (ha : a ∈ closure s)
    (hb : b ∈ closure s) (Hs : ∀ x ∈ s, ∀ y ∈ s, p x y) (H0_left : ∀ x, p 0 x)
    (H0_right : ∀ x, p x 0) (Hneg_left : ∀ x y, p x y → p (-x) y)
    (Hneg_right : ∀ x y, p x y → p x (-y)) (Hadd_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ + x₂) y)
    (Hadd_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ + y₂))
    (Hmul_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ * x₂) y)
    (Hmul_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ * y₂)) : p a b := by
  refine' closure_induction hb _ (H0_right _) (Hadd_right a) (Hneg_right a) (Hmul_right a)
  refine' closure_induction ha Hs (fun x _ => H0_left x) _ _ _
  · 

Proof state:
case refine'_1
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
p : R → R → Prop
a b : R
ha : a ∈ closure s
hb : b ∈ closure s
Hs : ∀ x ∈ s, ∀ y ∈ s, p x y
H0_left : ∀ (x : R), p 0 x
H0_right : ∀ (x : R), p x 0
Hneg_left : ∀ (x y : R), p x y → p (-x) y
Hneg_right : ∀ (x y : R), p x y → p x (-y)
Hadd_left : ∀ (x₁ x₂ y : R), p x₁ y → p x₂ y → p (x₁ + x₂) y
Hadd_right : ∀ (x y₁ y₂ : R), p x y₁ → p x y₂ → p x (y₁ + y₂)
Hmul_left : ∀ (x₁ x₂ y : R), p x₁ y → p x₂ y → p (x₁ * x₂) y
Hmul_right : ∀ (x y₁ y₂ : R), p x y₁ → p x y₂ → p x (y₁ * y₂)
⊢ ∀ (x y : R), (∀ x_1 ∈ s, p x x_1) → (∀ x ∈ s, p y x) → ∀ x_1 ∈ s, p (x + y) x_1

Next tactic:
exact fun x y H₁ H₂ z zs => Hadd_left x y z (H₁ z zs) (H₂ z zs)
/-- An induction principle for closure membership, for predicates with two arguments. -/
@[elab_as_elim]
theorem closure_induction₂ {s : Set R} {p : R → R → Prop} {a b : R} (ha : a ∈ closure s)
    (hb : b ∈ closure s) (Hs : ∀ x ∈ s, ∀ y ∈ s, p x y) (H0_left : ∀ x, p 0 x)
    (H0_right : ∀ x, p x 0) (Hneg_left : ∀ x y, p x y → p (-x) y)
    (Hneg_right : ∀ x y, p x y → p x (-y)) (Hadd_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ + x₂) y)
    (Hadd_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ + y₂))
    (Hmul_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ * x₂) y)
    (Hmul_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ * y₂)) : p a b := by
  refine' closure_induction hb _ (H0_right _) (Hadd_right a) (Hneg_right a) (Hmul_right a)
  refine' closure_induction ha Hs (fun x _ => H0_left x) _ _ _
  · exact fun x y H₁ H₂ z zs => Hadd_left x y z (H₁ z zs) (H₂ z zs)
  · 

Proof state:
case refine'_2
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
p : R → R → Prop
a b : R
ha : a ∈ closure s
hb : b ∈ closure s
Hs : ∀ x ∈ s, ∀ y ∈ s, p x y
H0_left : ∀ (x : R), p 0 x
H0_right : ∀ (x : R), p x 0
Hneg_left : ∀ (x y : R), p x y → p (-x) y
Hneg_right : ∀ (x y : R), p x y → p x (-y)
Hadd_left : ∀ (x₁ x₂ y : R), p x₁ y → p x₂ y → p (x₁ + x₂) y
Hadd_right : ∀ (x y₁ y₂ : R), p x y₁ → p x y₂ → p x (y₁ + y₂)
Hmul_left : ∀ (x₁ x₂ y : R), p x₁ y → p x₂ y → p (x₁ * x₂) y
Hmul_right : ∀ (x y₁ y₂ : R), p x y₁ → p x y₂ → p x (y₁ * y₂)
⊢ ∀ (x : R), (∀ x_1 ∈ s, p x x_1) → ∀ x_1 ∈ s, p (-x) x_1

Next tactic:
exact fun x hx z zs => Hneg_left x z (hx z zs)
/-- An induction principle for closure membership, for predicates with two arguments. -/
@[elab_as_elim]
theorem closure_induction₂ {s : Set R} {p : R → R → Prop} {a b : R} (ha : a ∈ closure s)
    (hb : b ∈ closure s) (Hs : ∀ x ∈ s, ∀ y ∈ s, p x y) (H0_left : ∀ x, p 0 x)
    (H0_right : ∀ x, p x 0) (Hneg_left : ∀ x y, p x y → p (-x) y)
    (Hneg_right : ∀ x y, p x y → p x (-y)) (Hadd_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ + x₂) y)
    (Hadd_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ + y₂))
    (Hmul_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ * x₂) y)
    (Hmul_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ * y₂)) : p a b := by
  refine' closure_induction hb _ (H0_right _) (Hadd_right a) (Hneg_right a) (Hmul_right a)
  refine' closure_induction ha Hs (fun x _ => H0_left x) _ _ _
  · exact fun x y H₁ H₂ z zs => Hadd_left x y z (H₁ z zs) (H₂ z zs)
  · exact fun x hx z zs => Hneg_left x z (hx z zs)
  · 

Proof state:
case refine'_3
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
p : R → R → Prop
a b : R
ha : a ∈ closure s
hb : b ∈ closure s
Hs : ∀ x ∈ s, ∀ y ∈ s, p x y
H0_left : ∀ (x : R), p 0 x
H0_right : ∀ (x : R), p x 0
Hneg_left : ∀ (x y : R), p x y → p (-x) y
Hneg_right : ∀ (x y : R), p x y → p x (-y)
Hadd_left : ∀ (x₁ x₂ y : R), p x₁ y → p x₂ y → p (x₁ + x₂) y
Hadd_right : ∀ (x y₁ y₂ : R), p x y₁ → p x y₂ → p x (y₁ + y₂)
Hmul_left : ∀ (x₁ x₂ y : R), p x₁ y → p x₂ y → p (x₁ * x₂) y
Hmul_right : ∀ (x y₁ y₂ : R), p x y₁ → p x y₂ → p x (y₁ * y₂)
⊢ ∀ (x y : R), (∀ x_1 ∈ s, p x x_1) → (∀ x ∈ s, p y x) → ∀ x_1 ∈ s, p (x * y) x_1

Next tactic:
exact fun x y H₁ H₂ z zs => Hmul_left x y z (H₁ z zs) (H₂ z zs)
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 

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 * q ∈ AddSubgroup.closure ↑(Subsemigroup.closure s)

Next tactic:
rw [zero_mul q]