l3lab/ntp-mathlib huggingface dataset:
/-- 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
      simp only [NonUnitalSubring.val_mul]
      

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:
refine'
        closure_induction₂ x.prop y.prop hcomm
          (fun x => by simp only [mul_zero, zero_mul])
          (fun x => by simp only [mul_zero, zero_mul])
          (fun x y hxy => by simp only [mul_neg, neg_mul, hxy])
          (fun x y hxy => by simp only [mul_neg, neg_mul, hxy])
          (fun x₁ x₂ y h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂])
          (fun x₁ x₂ y h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂])
          (fun x₁ x₂ y h₁ h₂ => by rw [← mul_assoc, ← h₁, mul_assoc x₁ y x₂, ← h₂, mul_assoc])
          fun x₁ x₂ y h₁ h₂ => by rw [← mul_assoc, h₁, mul_assoc, h₂, ← mul_assoc]
/-- 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
      simp only [NonUnitalSubring.val_mul]
      refine'
        closure_induction₂ x.prop y.prop hcomm
          (fun x => 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 : R
⊢ 0 * x = x * 0

Next tactic:
simp only [mul_zero, zero_mul]
/-- 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
      simp only [NonUnitalSubring.val_mul]
      refine'
        closure_induction₂ x.prop y.prop hcomm
          (fun x => by simp only [mul_zero, zero_mul])
          (fun x => 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 : R
⊢ x * 0 = 0 * x

Next tactic:
simp only [mul_zero, zero_mul]
/-- 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
      simp only [NonUnitalSubring.val_mul]
      refine'
        closure_induction₂ x.prop y.prop hcomm
          (fun x => by simp only [mul_zero, zero_mul])
          (fun x => by simp only [mul_zero, zero_mul])
          (fun x y hxy => 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 : R
hxy : x * y = y * x
⊢ -x * y = y * -x

Next tactic:
simp only [mul_neg, neg_mul, hxy]
/-- 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
      simp only [NonUnitalSubring.val_mul]
      refine'
        closure_induction₂ x.prop y.prop hcomm
          (fun x => by simp only [mul_zero, zero_mul])
          (fun x => by simp only [mul_zero, zero_mul])
          (fun x y hxy => by simp only [mul_neg, neg_mul, hxy])
          (fun x y hxy => 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 : R
hxy : x * y = y * x
⊢ x * -y = -y * x

Next tactic:
simp only [mul_neg, neg_mul, hxy]
/-- 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
      simp only [NonUnitalSubring.val_mul]
      refine'
        closure_induction₂ x.prop y.prop hcomm
          (fun x => by simp only [mul_zero, zero_mul])
          (fun x => by simp only [mul_zero, zero_mul])
          (fun x y hxy => by simp only [mul_neg, neg_mul, hxy])
          (fun x y hxy => by simp only [mul_neg, neg_mul, hxy])
          (fun x₁ x₂ y h₁ h₂ => 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₁ x₂ y : R
h₁ : x₁ * y = y * x₁
h₂ : x₂ * y = y * x₂
⊢ (x₁ + x₂) * y = y * (x₁ + x₂)

Next tactic:
simp only [add_mul, mul_add, h₁, h₂]
/-- 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
      simp only [NonUnitalSubring.val_mul]
      refine'
        closure_induction₂ x.prop y.prop hcomm
          (fun x => by simp only [mul_zero, zero_mul])
          (fun x => by simp only [mul_zero, zero_mul])
          (fun x y hxy => by simp only [mul_neg, neg_mul, hxy])
          (fun x y hxy => by simp only [mul_neg, neg_mul, hxy])
          (fun x₁ x₂ y h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂])
          (fun x₁ x₂ y h₁ h₂ => 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₁ x₂ y : R
h₁ : x₁ * x₂ = x₂ * x₁
h₂ : x₁ * y = y * x₁
⊢ x₁ * (x₂ + y) = (x₂ + y) * x₁

Next tactic:
simp only [add_mul, mul_add, h₁, h₂]
/-- 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
      simp only [NonUnitalSubring.val_mul]
      refine'
        closure_induction₂ x.prop y.prop hcomm
          (fun x => by simp only [mul_zero, zero_mul])
          (fun x => by simp only [mul_zero, zero_mul])
          (fun x y hxy => by simp only [mul_neg, neg_mul, hxy])
          (fun x y hxy => by simp only [mul_neg, neg_mul, hxy])
          (fun x₁ x₂ y h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂])
          (fun x₁ x₂ y h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂])
          (fun x₁ x₂ y h₁ h₂ => 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₁ x₂ y : R
h₁ : x₁ * y = y * x₁
h₂ : x₂ * y = y * x₂
⊢ x₁ * x₂ * y = y * (x₁ * x₂)

Next tactic:
rw [← mul_assoc, ← h₁, mul_assoc x₁ y x₂, ← h₂, mul_assoc]
/-- 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
      simp only [NonUnitalSubring.val_mul]
      refine'
        closure_induction₂ x.prop y.prop hcomm
          (fun x => by simp only [mul_zero, zero_mul])
          (fun x => by simp only [mul_zero, zero_mul])
          (fun x y hxy => by simp only [mul_neg, neg_mul, hxy])
          (fun x y hxy => by simp only [mul_neg, neg_mul, hxy])
          (fun x₁ x₂ y h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂])
          (fun x₁ x₂ y h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂])
          (fun x₁ x₂ y h₁ h₂ => by rw [← mul_assoc, ← h₁, mul_assoc x₁ y x₂, ← h₂, mul_assoc])
          fun x₁ x₂ y h₁ h₂ => 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₁ x₂ y : R
h₁ : x₁ * x₂ = x₂ * x₁
h₂ : x₁ * y = y * x₁
⊢ x₁ * (x₂ * y) = x₂ * y * x₁

Next tactic:
rw [← mul_assoc, h₁, mul_assoc, h₂, ← mul_assoc]
theorem prod_top (s : NonUnitalSubring R) :
    s.prod (⊤ : NonUnitalSubring S) = s.comap (NonUnitalRingHom.fst R S) :=
  ext fun x => 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 : NonUnitalSubring R
x : R × S
⊢ x ∈ prod s ⊤ ↔ x ∈ comap (NonUnitalRingHom.fst R S) s

Next tactic:
simp [mem_prod, MonoidHom.coe_fst]
theorem top_prod (s : NonUnitalSubring S) :
    (⊤ : NonUnitalSubring R).prod s = s.comap (NonUnitalRingHom.snd R S) :=
  ext fun x => 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 : NonUnitalSubring S
x : R × S
⊢ x ∈ prod ⊤ s ↔ x ∈ comap (NonUnitalRingHom.snd R S) s

Next tactic:
simp [mem_prod, MonoidHom.coe_snd]
/-- The underlying set of a non-empty directed Sup of `NonUnitalSubring`s is just a union of the
`NonUnitalSubring`s. Note that this fails without the directedness assumption (the union of two
`NonUnitalSubring`s is typically not a `NonUnitalSubring`) -/
theorem mem_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → NonUnitalSubring R}
    (hS : Directed (· ≤ ·) S) {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
hι : Nonempty ι
S : ι → NonUnitalSubring R
hS : Directed (fun x x_1 => x ≤ x_1) S
x : R
⊢ x ∈ ⨆ i, S i ↔ ∃ i, x ∈ S i

Next tactic:
refine ⟨?_, fun ⟨i, hi⟩ ↦ le_iSup S i hi⟩
/-- The underlying set of a non-empty directed Sup of `NonUnitalSubring`s is just a union of the
`NonUnitalSubring`s. Note that this fails without the directedness assumption (the union of two
`NonUnitalSubring`s is typically not a `NonUnitalSubring`) -/
theorem mem_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → NonUnitalSubring R}
    (hS : Directed (· ≤ ·) S) {x : R} : (x ∈ ⨆ i, S i) ↔ ∃ i, x ∈ S i := by
  refine ⟨?_, fun ⟨i, hi⟩ ↦ le_iSup S i hi⟩
  

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
hι : Nonempty ι
S : ι → NonUnitalSubring R
hS : Directed (fun x x_1 => x ≤ x_1) S
x : R
⊢ x ∈ ⨆ i, S i → ∃ i, x ∈ S i

Next tactic:
let U : NonUnitalSubring R :=
    NonUnitalSubring.mk' (⋃ i, (S i : Set R)) (⨆ i, (S i).toSubsemigroup) (⨆ i, (S i).toAddSubgroup)
      (Subsemigroup.coe_iSup_of_directed hS) (AddSubgroup.coe_iSup_of_directed hS)
/-- The underlying set of a non-empty directed Sup of `NonUnitalSubring`s is just a union of the
`NonUnitalSubring`s. Note that this fails without the directedness assumption (the union of two
`NonUnitalSubring`s is typically not a `NonUnitalSubring`) -/
theorem mem_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → NonUnitalSubring R}
    (hS : Directed (· ≤ ·) S) {x : R} : (x ∈ ⨆ i, S i) ↔ ∃ i, x ∈ S i := by
  refine ⟨?_, fun ⟨i, hi⟩ ↦ le_iSup S i hi⟩
  let U : NonUnitalSubring R :=
    NonUnitalSubring.mk' (⋃ i, (S i : Set R)) (⨆ i, (S i).toSubsemigroup) (⨆ i, (S i).toAddSubgroup)
      (Subsemigroup.coe_iSup_of_directed hS) (AddSubgroup.coe_iSup_of_directed hS)
  

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
hι : Nonempty ι
S : ι → NonUnitalSubring R
hS : Directed (fun x x_1 => x ≤ x_1) S
x : R
U : NonUnitalSubring R :=
  NonUnitalSubring.mk' (⋃ i, ↑(S i)) (⨆ i, toSubsemigroup (S i)) (⨆ i, toAddSubgroup (S i))
    (_ : ↑(⨆ i, toSubsemigroup (S i)) = ⋃ i, ↑(toSubsemigroup (S i)))
    (_ : ↑(⨆ i, toAddSubgroup (S i)) = ⋃ i, ↑(toAddSubgroup (S i)))
⊢ x ∈ ⨆ i, S i → ∃ i, x ∈ S i

Next tactic:
suffices ⨆ i, S i ≤ U by simpa using @this x
/-- The underlying set of a non-empty directed Sup of `NonUnitalSubring`s is just a union of the
`NonUnitalSubring`s. Note that this fails without the directedness assumption (the union of two
`NonUnitalSubring`s is typically not a `NonUnitalSubring`) -/
theorem mem_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → NonUnitalSubring R}
    (hS : Directed (· ≤ ·) S) {x : R} : (x ∈ ⨆ i, S i) ↔ ∃ i, x ∈ S i := by
  refine ⟨?_, fun ⟨i, hi⟩ ↦ le_iSup S i hi⟩
  let U : NonUnitalSubring R :=
    NonUnitalSubring.mk' (⋃ i, (S i : Set R)) (⨆ i, (S i).toSubsemigroup) (⨆ i, (S i).toAddSubgroup)
      (Subsemigroup.coe_iSup_of_directed hS) (AddSubgroup.coe_iSup_of_directed hS)
  suffices ⨆ i, S i ≤ U 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
hι : Nonempty ι
S : ι → NonUnitalSubring R
hS : Directed (fun x x_1 => x ≤ x_1) S
x : R
U : NonUnitalSubring R :=
  NonUnitalSubring.mk' (⋃ i, ↑(S i)) (⨆ i, toSubsemigroup (S i)) (⨆ i, toAddSubgroup (S i))
    (_ : ↑(⨆ i, toSubsemigroup (S i)) = ⋃ i, ↑(toSubsemigroup (S i)))
    (_ : ↑(⨆ i, toAddSubgroup (S i)) = ⋃ i, ↑(toAddSubgroup (S i)))
this : ⨆ i, S i ≤ U
⊢ x ∈ ⨆ i, S i → ∃ i, x ∈ S i

Next tactic:
simpa using @this x
/-- The underlying set of a non-empty directed Sup of `NonUnitalSubring`s is just a union of the
`NonUnitalSubring`s. Note that this fails without the directedness assumption (the union of two
`NonUnitalSubring`s is typically not a `NonUnitalSubring`) -/
theorem mem_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → NonUnitalSubring R}
    (hS : Directed (· ≤ ·) S) {x : R} : (x ∈ ⨆ i, S i) ↔ ∃ i, x ∈ S i := by
  refine ⟨?_, fun ⟨i, hi⟩ ↦ le_iSup S i hi⟩
  let U : NonUnitalSubring R :=
    NonUnitalSubring.mk' (⋃ i, (S i : Set R)) (⨆ i, (S i).toSubsemigroup) (⨆ i, (S i).toAddSubgroup)
      (Subsemigroup.coe_iSup_of_directed hS) (AddSubgroup.coe_iSup_of_directed hS)
  suffices ⨆ i, S i ≤ U by simpa using @this 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✝
ι : Sort u_2
hι : Nonempty ι
S : ι → NonUnitalSubring R
hS : Directed (fun x x_1 => x ≤ x_1) S
x : R
U : NonUnitalSubring R :=
  NonUnitalSubring.mk' (⋃ i, ↑(S i)) (⨆ i, toSubsemigroup (S i)) (⨆ i, toAddSubgroup (S i))
    (_ : ↑(⨆ i, toSubsemigroup (S i)) = ⋃ i, ↑(toSubsemigroup (S i)))
    (_ : ↑(⨆ i, toAddSubgroup (S i)) = ⋃ i, ↑(toAddSubgroup (S i)))
⊢ ⨆ i, S i ≤ U

Next tactic:
exact iSup_le fun i x hx ↦ Set.mem_iUnion.2 ⟨i, hx⟩
theorem coe_iSup_of_directed {ι} [Nonempty ι] {S : ι → NonUnitalSubring R}
    (hS : Directed (· ≤ ·) S) : ((⨆ i, S i : NonUnitalSubring R) : Set R) = ⋃ i, S i :=
  Set.ext fun x ↦ 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
inst✝ : Nonempty ι
S : ι → NonUnitalSubring R
hS : Directed (fun x x_1 => x ≤ x_1) S
x : R
⊢ x ∈ ↑(⨆ i, S i) ↔ x ∈ ⋃ i, ↑(S i)

Next tactic:
simp [mem_iSup_of_directed hS]
theorem mem_sSup_of_directedOn {S : Set (NonUnitalSubring R)} (Sne : S.Nonempty)
    (hS : DirectedOn (· ≤ ·) S) {x : R} : x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s := 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)
Sne : Set.Nonempty S
hS : DirectedOn (fun x x_1 => x ≤ x_1) S
x : R
⊢ x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s

Next tactic:
haveI : Nonempty S := Sne.to_subtype
theorem mem_sSup_of_directedOn {S : Set (NonUnitalSubring R)} (Sne : S.Nonempty)
    (hS : DirectedOn (· ≤ ·) S) {x : R} : x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s := by
  haveI : Nonempty S := Sne.to_subtype
  

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)
Sne : Set.Nonempty S
hS : DirectedOn (fun x x_1 => x ≤ x_1) S
x : R
this : Nonempty ↑S
⊢ x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s

Next tactic:
simp only [sSup_eq_iSup', mem_iSup_of_directed hS.directed_val, SetCoe.exists, Subtype.coe_mk,
    exists_prop]
theorem coe_sSup_of_directedOn {S : Set (NonUnitalSubring R)} (Sne : S.Nonempty)
    (hS : DirectedOn (· ≤ ·) S) : (↑(sSup S) : Set R) = ⋃ s ∈ S, ↑s :=
  Set.ext fun x => 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)
Sne : Set.Nonempty S
hS : DirectedOn (fun x x_1 => x ≤ x_1) S
x : R
⊢ x ∈ ↑(sSup S) ↔ x ∈ ⋃ s ∈ S, ↑s

Next tactic:
simp [mem_sSup_of_directedOn Sne hS]
theorem range_top_iff_surjective {f : R →ₙ+* S} :
    f.range = (⊤ : NonUnitalSubring S) ↔ Function.Surjective f :=
  SetLike.ext'_iff.trans <| Iff.trans (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 : NonUnitalSubring R
f : R →ₙ+* S
⊢ ↑(range f) = ↑⊤ ↔ Set.range ⇑f = Set.univ

Next tactic:
rw [coe_range, coe_top]
/-- Restrict a ring homomorphism with a left inverse to a ring isomorphism to its
`RingHom.range`. -/
def ofLeftInverse' {g : S → R} {f : R →ₙ+* S} (h : Function.LeftInverse g f) : R ≃+* f.range :=
  { f.rangeRestrict with
    toFun := fun x => f.rangeRestrict x
    invFun := fun x => (g ∘ NonUnitalSubringClass.subtype f.range) x
    left_inv := h
    right_inv := fun x =>
      Subtype.ext <|
        let ⟨x', hx'⟩ := NonUnitalRingHom.mem_range.mp x.prop
        show f (g x) = x by 

Proof state:
F : Type w
R : Type u
S : Type v
T : Type u_1
inst✝³ : NonUnitalRing R
inst✝² : NonUnitalRing S
inst✝¹ : NonUnitalRing T
inst✝ : NonUnitalRingHomClass F R S
g✝ : S →ₙ+* T
f✝ : R →ₙ+* S
s t : NonUnitalSubring R
g : S → R
f : R →ₙ+* S
h : Function.LeftInverse g ⇑f
src✝ : R →ₙ+* ↥(NonUnitalRingHom.range f) := NonUnitalRingHom.rangeRestrict f
x : ↥(NonUnitalRingHom.range f)
x' : R
hx' : f x' = ↑x
⊢ f (g ↑x) = ↑x

Next tactic:
rw [← hx', h x']
@[reassoc (attr := simp)]
theorem objEqToHom_d {x y : β} (h : x = y) :
    X.objEqToHom h ≫ X.d y = X.d x ≫ X.objEqToHom (by 

Proof state:
β : Type u_1
inst✝² : AddCommGroup β
b : β
V : Type u_2
inst✝¹ : Category.{?u.1353, u_2} V
inst✝ : HasZeroMorphisms V
X : DifferentialObject ℤ (GradedObjectWithShift b V)
x y : β
h : x = y
⊢ (fun b_1 => b_1 + { as := 1 }.as • b) x = (fun b_1 => b_1 + { as := 1 }.as • b) y

Next tactic:
cases h
@[reassoc (attr := simp)]
theorem objEqToHom_d {x y : β} (h : x = y) :
    X.objEqToHom h ≫ X.d y = X.d x ≫ X.objEqToHom (by cases h; 

Proof state:
case refl
β : Type u_1
inst✝² : AddCommGroup β
b : β
V : Type u_2
inst✝¹ : Category.{?u.1353, u_2} V
inst✝ : HasZeroMorphisms V
X : DifferentialObject ℤ (GradedObjectWithShift b V)
x : β
⊢ (fun b_1 => b_1 + { as := 1 }.as • b) x = (fun b_1 => b_1 + { as := 1 }.as • b) x

Next tactic:
rfl
@[reassoc (attr := simp)]
theorem objEqToHom_d {x y : β} (h : x = y) :
    X.objEqToHom h ≫ X.d y = X.d x ≫ X.objEqToHom (by cases h; rfl) := by 

Proof state:
β : Type u_1
inst✝² : AddCommGroup β
b : β
V : Type u_2
inst✝¹ : Category.{u_3, u_2} V
inst✝ : HasZeroMorphisms V
X : DifferentialObject ℤ (GradedObjectWithShift b V)
x y : β
h : x = y
⊢ objEqToHom X h ≫ d X y =
    d X x ≫ objEqToHom X (_ : (fun b_1 => b_1 + { as := 1 }.as • b) x = (fun b_1 => b_1 + { as := 1 }.as • b) y)

Next tactic:
cases h
@[reassoc (attr := simp)]
theorem objEqToHom_d {x y : β} (h : x = y) :
    X.objEqToHom h ≫ X.d y = X.d x ≫ X.objEqToHom (by cases h; rfl) := by cases h; 

Proof state:
case refl
β : Type u_1
inst✝² : AddCommGroup β
b : β
V : Type u_2
inst✝¹ : Category.{u_3, u_2} V
inst✝ : HasZeroMorphisms V
X : DifferentialObject ℤ (GradedObjectWithShift b V)
x : β
⊢ objEqToHom X (_ : x = x) ≫ d X x =
    d X x ≫ objEqToHom X (_ : (fun b_1 => b_1 + { as := 1 }.as • b) x = (fun b_1 => b_1 + { as := 1 }.as • b) x)

Next tactic:
dsimp
@[reassoc (attr := simp)]
theorem objEqToHom_d {x y : β} (h : x = y) :
    X.objEqToHom h ≫ X.d y = X.d x ≫ X.objEqToHom (by cases h; rfl) := by cases h; dsimp; 

Proof state:
case refl
β : Type u_1
inst✝² : AddCommGroup β
b : β
V : Type u_2
inst✝¹ : Category.{u_3, u_2} V
inst✝ : HasZeroMorphisms V
X : DifferentialObject ℤ (GradedObjectWithShift b V)
x : β
⊢ 𝟙 (obj X x) ≫ d X x = d X x ≫ 𝟙 (obj X (x + 1 • b))

Next tactic:
simp