l3lab/ntp-mathlib huggingface dataset:
private theorem add''_char (r₁ : R) (s₁ : S) (r₂ : R) (s₂ : S) (rb : R) (sb : S)
    (hb : (s₁ : R) * sb = (s₂ : R) * rb) :
    add'' r₁ s₁ r₂ s₂ = (r₁ * sb + r₂ * rb) /ₒ (s₁ * sb) := by
  -- Porting note: `noncomm_ring` was not ported yet
  simp only [add'']
  have ha := ore_eq (s₁ : R) s₂
  set! ra := oreNum (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- r tilde
  set! sa := oreDenom (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- s tilde
  rcases oreCondition (sa : R) sb with ⟨rc, sc, hc⟩
  -- s*, r*
  have : (s₂ : R) * (rb * rc) = s₂ * (ra * sc) := by
    rw [← mul_assoc, ← hb, mul_assoc, ← hc, ← mul_assoc, ← mul_assoc, ha]
  rcases ore_left_cancel _ _ s₂ this with ⟨sd, hd⟩
  -- s#
  symm
  rw [oreDiv_eq_iff]
  

Proof state:
case mk.mk.intro
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
rb : R
sb : ↥S
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : ↥S := oreDenom (↑s₁) s₂
rc : R
sc : ↥S
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : ↥S
hd : rb * rc * ↑sd = ra * ↑sc * ↑sd
⊢ ∃ u v, (r₁ * ↑sa + r₂ * ra) * ↑u = (r₁ * ↑sb + r₂ * rb) * v ∧ ↑(s₁ * sa) * ↑u = ↑(s₁ * sb) * v

Next tactic:
use sc * sd
private theorem add''_char (r₁ : R) (s₁ : S) (r₂ : R) (s₂ : S) (rb : R) (sb : S)
    (hb : (s₁ : R) * sb = (s₂ : R) * rb) :
    add'' r₁ s₁ r₂ s₂ = (r₁ * sb + r₂ * rb) /ₒ (s₁ * sb) := by
  -- Porting note: `noncomm_ring` was not ported yet
  simp only [add'']
  have ha := ore_eq (s₁ : R) s₂
  set! ra := oreNum (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- r tilde
  set! sa := oreDenom (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- s tilde
  rcases oreCondition (sa : R) sb with ⟨rc, sc, hc⟩
  -- s*, r*
  have : (s₂ : R) * (rb * rc) = s₂ * (ra * sc) := by
    rw [← mul_assoc, ← hb, mul_assoc, ← hc, ← mul_assoc, ← mul_assoc, ha]
  rcases ore_left_cancel _ _ s₂ this with ⟨sd, hd⟩
  -- s#
  symm
  rw [oreDiv_eq_iff]
  use sc * sd
  

Proof state:
case h
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
rb : R
sb : ↥S
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : ↥S := oreDenom (↑s₁) s₂
rc : R
sc : ↥S
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : ↥S
hd : rb * rc * ↑sd = ra * ↑sc * ↑sd
⊢ ∃ v, (r₁ * ↑sa + r₂ * ra) * ↑(sc * sd) = (r₁ * ↑sb + r₂ * rb) * v ∧ ↑(s₁ * sa) * ↑(sc * sd) = ↑(s₁ * sb) * v

Next tactic:
use rc * sd
private theorem add''_char (r₁ : R) (s₁ : S) (r₂ : R) (s₂ : S) (rb : R) (sb : S)
    (hb : (s₁ : R) * sb = (s₂ : R) * rb) :
    add'' r₁ s₁ r₂ s₂ = (r₁ * sb + r₂ * rb) /ₒ (s₁ * sb) := by
  -- Porting note: `noncomm_ring` was not ported yet
  simp only [add'']
  have ha := ore_eq (s₁ : R) s₂
  set! ra := oreNum (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- r tilde
  set! sa := oreDenom (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- s tilde
  rcases oreCondition (sa : R) sb with ⟨rc, sc, hc⟩
  -- s*, r*
  have : (s₂ : R) * (rb * rc) = s₂ * (ra * sc) := by
    rw [← mul_assoc, ← hb, mul_assoc, ← hc, ← mul_assoc, ← mul_assoc, ha]
  rcases ore_left_cancel _ _ s₂ this with ⟨sd, hd⟩
  -- s#
  symm
  rw [oreDiv_eq_iff]
  use sc * sd
  use rc * sd
  

Proof state:
case h
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
rb : R
sb : ↥S
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : ↥S := oreDenom (↑s₁) s₂
rc : R
sc : ↥S
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : ↥S
hd : rb * rc * ↑sd = ra * ↑sc * ↑sd
⊢ (r₁ * ↑sa + r₂ * ra) * ↑(sc * sd) = (r₁ * ↑sb + r₂ * rb) * (rc * ↑sd) ∧
    ↑(s₁ * sa) * ↑(sc * sd) = ↑(s₁ * sb) * (rc * ↑sd)

Next tactic:
constructor
private theorem add''_char (r₁ : R) (s₁ : S) (r₂ : R) (s₂ : S) (rb : R) (sb : S)
    (hb : (s₁ : R) * sb = (s₂ : R) * rb) :
    add'' r₁ s₁ r₂ s₂ = (r₁ * sb + r₂ * rb) /ₒ (s₁ * sb) := by
  -- Porting note: `noncomm_ring` was not ported yet
  simp only [add'']
  have ha := ore_eq (s₁ : R) s₂
  set! ra := oreNum (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- r tilde
  set! sa := oreDenom (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- s tilde
  rcases oreCondition (sa : R) sb with ⟨rc, sc, hc⟩
  -- s*, r*
  have : (s₂ : R) * (rb * rc) = s₂ * (ra * sc) := by
    rw [← mul_assoc, ← hb, mul_assoc, ← hc, ← mul_assoc, ← mul_assoc, ha]
  rcases ore_left_cancel _ _ s₂ this with ⟨sd, hd⟩
  -- s#
  symm
  rw [oreDiv_eq_iff]
  use sc * sd
  use rc * sd
  constructor <;> 

Proof state:
case h.left
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
rb : R
sb : ↥S
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : ↥S := oreDenom (↑s₁) s₂
rc : R
sc : ↥S
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : ↥S
hd : rb * rc * ↑sd = ra * ↑sc * ↑sd
⊢ (r₁ * ↑sa + r₂ * ra) * ↑(sc * sd) = (r₁ * ↑sb + r₂ * rb) * (rc * ↑sd)

Next tactic:
simp only [Submonoid.coe_mul]
private theorem add''_char (r₁ : R) (s₁ : S) (r₂ : R) (s₂ : S) (rb : R) (sb : S)
    (hb : (s₁ : R) * sb = (s₂ : R) * rb) :
    add'' r₁ s₁ r₂ s₂ = (r₁ * sb + r₂ * rb) /ₒ (s₁ * sb) := by
  -- Porting note: `noncomm_ring` was not ported yet
  simp only [add'']
  have ha := ore_eq (s₁ : R) s₂
  set! ra := oreNum (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- r tilde
  set! sa := oreDenom (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- s tilde
  rcases oreCondition (sa : R) sb with ⟨rc, sc, hc⟩
  -- s*, r*
  have : (s₂ : R) * (rb * rc) = s₂ * (ra * sc) := by
    rw [← mul_assoc, ← hb, mul_assoc, ← hc, ← mul_assoc, ← mul_assoc, ha]
  rcases ore_left_cancel _ _ s₂ this with ⟨sd, hd⟩
  -- s#
  symm
  rw [oreDiv_eq_iff]
  use sc * sd
  use rc * sd
  constructor <;> 

Proof state:
case h.right
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
rb : R
sb : ↥S
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : ↥S := oreDenom (↑s₁) s₂
rc : R
sc : ↥S
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : ↥S
hd : rb * rc * ↑sd = ra * ↑sc * ↑sd
⊢ ↑(s₁ * sa) * ↑(sc * sd) = ↑(s₁ * sb) * (rc * ↑sd)

Next tactic:
simp only [Submonoid.coe_mul]
private theorem add''_char (r₁ : R) (s₁ : S) (r₂ : R) (s₂ : S) (rb : R) (sb : S)
    (hb : (s₁ : R) * sb = (s₂ : R) * rb) :
    add'' r₁ s₁ r₂ s₂ = (r₁ * sb + r₂ * rb) /ₒ (s₁ * sb) := by
  -- Porting note: `noncomm_ring` was not ported yet
  simp only [add'']
  have ha := ore_eq (s₁ : R) s₂
  set! ra := oreNum (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- r tilde
  set! sa := oreDenom (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- s tilde
  rcases oreCondition (sa : R) sb with ⟨rc, sc, hc⟩
  -- s*, r*
  have : (s₂ : R) * (rb * rc) = s₂ * (ra * sc) := by
    rw [← mul_assoc, ← hb, mul_assoc, ← hc, ← mul_assoc, ← mul_assoc, ha]
  rcases ore_left_cancel _ _ s₂ this with ⟨sd, hd⟩
  -- s#
  symm
  rw [oreDiv_eq_iff]
  use sc * sd
  use rc * sd
  constructor <;> simp only [Submonoid.coe_mul]
  · 

Proof state:
case h.left
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
rb : R
sb : ↥S
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : ↥S := oreDenom (↑s₁) s₂
rc : R
sc : ↥S
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : ↥S
hd : rb * rc * ↑sd = ra * ↑sc * ↑sd
⊢ (r₁ * ↑(oreDenom (↑s₁) s₂) + r₂ * oreNum (↑s₁) s₂) * (↑sc * ↑sd) = (r₁ * ↑sb + r₂ * rb) * (rc * ↑sd)

Next tactic:
noncomm_ring
private theorem add''_char (r₁ : R) (s₁ : S) (r₂ : R) (s₂ : S) (rb : R) (sb : S)
    (hb : (s₁ : R) * sb = (s₂ : R) * rb) :
    add'' r₁ s₁ r₂ s₂ = (r₁ * sb + r₂ * rb) /ₒ (s₁ * sb) := by
  -- Porting note: `noncomm_ring` was not ported yet
  simp only [add'']
  have ha := ore_eq (s₁ : R) s₂
  set! ra := oreNum (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- r tilde
  set! sa := oreDenom (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- s tilde
  rcases oreCondition (sa : R) sb with ⟨rc, sc, hc⟩
  -- s*, r*
  have : (s₂ : R) * (rb * rc) = s₂ * (ra * sc) := by
    rw [← mul_assoc, ← hb, mul_assoc, ← hc, ← mul_assoc, ← mul_assoc, ha]
  rcases ore_left_cancel _ _ s₂ this with ⟨sd, hd⟩
  -- s#
  symm
  rw [oreDiv_eq_iff]
  use sc * sd
  use rc * sd
  constructor <;> simp only [Submonoid.coe_mul]
  · noncomm_ring
    

Proof state:
case h.left
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
rb : R
sb : ↥S
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : ↥S := oreDenom (↑s₁) s₂
rc : R
sc : ↥S
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : ↥S
hd : rb * rc * ↑sd = ra * ↑sc * ↑sd
⊢ r₁ * (↑(oreDenom (↑s₁) s₂) * (↑sc * ↑sd)) + r₂ * (oreNum (↑s₁) s₂ * (↑sc * ↑sd)) =
    r₁ * (↑sb * (rc * ↑sd)) + r₂ * (rb * (rc * ↑sd))

Next tactic:
rw [← mul_assoc (a := rb), hd, ← mul_assoc (a := (sa : R)), hc]
private theorem add''_char (r₁ : R) (s₁ : S) (r₂ : R) (s₂ : S) (rb : R) (sb : S)
    (hb : (s₁ : R) * sb = (s₂ : R) * rb) :
    add'' r₁ s₁ r₂ s₂ = (r₁ * sb + r₂ * rb) /ₒ (s₁ * sb) := by
  -- Porting note: `noncomm_ring` was not ported yet
  simp only [add'']
  have ha := ore_eq (s₁ : R) s₂
  set! ra := oreNum (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- r tilde
  set! sa := oreDenom (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- s tilde
  rcases oreCondition (sa : R) sb with ⟨rc, sc, hc⟩
  -- s*, r*
  have : (s₂ : R) * (rb * rc) = s₂ * (ra * sc) := by
    rw [← mul_assoc, ← hb, mul_assoc, ← hc, ← mul_assoc, ← mul_assoc, ha]
  rcases ore_left_cancel _ _ s₂ this with ⟨sd, hd⟩
  -- s#
  symm
  rw [oreDiv_eq_iff]
  use sc * sd
  use rc * sd
  constructor <;> simp only [Submonoid.coe_mul]
  · noncomm_ring
    rw [← mul_assoc (a := rb), hd, ← mul_assoc (a := (sa : R)), hc]
    

Proof state:
case h.left
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
rb : R
sb : ↥S
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : ↥S := oreDenom (↑s₁) s₂
rc : R
sc : ↥S
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : ↥S
hd : rb * rc * ↑sd = ra * ↑sc * ↑sd
⊢ r₁ * (↑sb * rc * ↑sd) + r₂ * (oreNum (↑s₁) s₂ * (↑sc * ↑sd)) = r₁ * (↑sb * (rc * ↑sd)) + r₂ * (ra * ↑sc * ↑sd)

Next tactic:
noncomm_ring
private theorem add''_char (r₁ : R) (s₁ : S) (r₂ : R) (s₂ : S) (rb : R) (sb : S)
    (hb : (s₁ : R) * sb = (s₂ : R) * rb) :
    add'' r₁ s₁ r₂ s₂ = (r₁ * sb + r₂ * rb) /ₒ (s₁ * sb) := by
  -- Porting note: `noncomm_ring` was not ported yet
  simp only [add'']
  have ha := ore_eq (s₁ : R) s₂
  set! ra := oreNum (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- r tilde
  set! sa := oreDenom (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- s tilde
  rcases oreCondition (sa : R) sb with ⟨rc, sc, hc⟩
  -- s*, r*
  have : (s₂ : R) * (rb * rc) = s₂ * (ra * sc) := by
    rw [← mul_assoc, ← hb, mul_assoc, ← hc, ← mul_assoc, ← mul_assoc, ha]
  rcases ore_left_cancel _ _ s₂ this with ⟨sd, hd⟩
  -- s#
  symm
  rw [oreDiv_eq_iff]
  use sc * sd
  use rc * sd
  constructor <;> simp only [Submonoid.coe_mul]
  · noncomm_ring
    rw [← mul_assoc (a := rb), hd, ← mul_assoc (a := (sa : R)), hc]
    noncomm_ring
  · 

Proof state:
case h.right
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
rb : R
sb : ↥S
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : ↥S := oreDenom (↑s₁) s₂
rc : R
sc : ↥S
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : ↥S
hd : rb * rc * ↑sd = ra * ↑sc * ↑sd
⊢ ↑s₁ * ↑(oreDenom (↑s₁) s₂) * (↑sc * ↑sd) = ↑s₁ * ↑sb * (rc * ↑sd)

Next tactic:
rw [mul_assoc (a := (s₁ : R)), ← mul_assoc (a := (sa : R)), hc]
private theorem add''_char (r₁ : R) (s₁ : S) (r₂ : R) (s₂ : S) (rb : R) (sb : S)
    (hb : (s₁ : R) * sb = (s₂ : R) * rb) :
    add'' r₁ s₁ r₂ s₂ = (r₁ * sb + r₂ * rb) /ₒ (s₁ * sb) := by
  -- Porting note: `noncomm_ring` was not ported yet
  simp only [add'']
  have ha := ore_eq (s₁ : R) s₂
  set! ra := oreNum (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- r tilde
  set! sa := oreDenom (s₁ : R) s₂ with h
  rw [← h] at *
  clear h
  -- s tilde
  rcases oreCondition (sa : R) sb with ⟨rc, sc, hc⟩
  -- s*, r*
  have : (s₂ : R) * (rb * rc) = s₂ * (ra * sc) := by
    rw [← mul_assoc, ← hb, mul_assoc, ← hc, ← mul_assoc, ← mul_assoc, ha]
  rcases ore_left_cancel _ _ s₂ this with ⟨sd, hd⟩
  -- s#
  symm
  rw [oreDiv_eq_iff]
  use sc * sd
  use rc * sd
  constructor <;> simp only [Submonoid.coe_mul]
  · noncomm_ring
    rw [← mul_assoc (a := rb), hd, ← mul_assoc (a := (sa : R)), hc]
    noncomm_ring
  · rw [mul_assoc (a := (s₁ : R)), ← mul_assoc (a := (sa : R)), hc]
    

Proof state:
case h.right
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
rb : R
sb : ↥S
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : ↥S := oreDenom (↑s₁) s₂
rc : R
sc : ↥S
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : ↥S
hd : rb * rc * ↑sd = ra * ↑sc * ↑sd
⊢ ↑s₁ * (↑sb * rc * ↑sd) = ↑s₁ * ↑sb * (rc * ↑sd)

Next tactic:
noncomm_ring
private def add' (r₂ : R) (s₂ : S) : R[S⁻¹] → R[S⁻¹] :=
  (--plus tilde
      Quotient.lift
      fun r₁s₁ : R × S => add'' r₁s₁.1 r₁s₁.2 r₂ s₂) <| by
    -- Porting note: `assoc_rw` & `noncomm_ring` were not ported yet
    

Proof state:
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₂ : R
s₂ : ↥S
⊢ ∀ (a b : R × ↥S), a ≈ b → OreLocalization.add'' a.1 a.2 r₂ s₂ = OreLocalization.add'' b.1 b.2 r₂ s₂

Next tactic:
rintro ⟨r₁', s₁'⟩ ⟨r₁, s₁⟩ ⟨sb, rb, hb, hb'⟩
private def add' (r₂ : R) (s₂ : S) : R[S⁻¹] → R[S⁻¹] :=
  (--plus tilde
      Quotient.lift
      fun r₁s₁ : R × S => add'' r₁s₁.1 r₁s₁.2 r₂ s₂) <| by
    -- Porting note: `assoc_rw` & `noncomm_ring` were not ported yet
    rintro ⟨r₁', s₁'⟩ ⟨r₁, s₁⟩ ⟨sb, rb, hb, hb'⟩
    -- s*, r*
    

Proof state:
case mk.mk.intro.intro.intro
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₂ : R
s₂ : ↥S
r₁' : R
s₁' : ↥S
r₁ : R
s₁ : ↥S
sb : ↥S
rb : R
hb : (r₁, s₁).1 * ↑sb = (r₁', s₁').1 * rb
hb' : ↑(r₁, s₁).2 * ↑sb = ↑(r₁', s₁').2 * rb
⊢ OreLocalization.add'' (r₁', s₁').1 (r₁', s₁').2 r₂ s₂ = OreLocalization.add'' (r₁, s₁).1 (r₁, s₁).2 r₂ s₂

Next tactic:
rcases oreCondition (s₁' : R) s₂ with ⟨rc, sc, hc⟩
private def add' (r₂ : R) (s₂ : S) : R[S⁻¹] → R[S⁻¹] :=
  (--plus tilde
      Quotient.lift
      fun r₁s₁ : R × S => add'' r₁s₁.1 r₁s₁.2 r₂ s₂) <| by
    -- Porting note: `assoc_rw` & `noncomm_ring` were not ported yet
    rintro ⟨r₁', s₁'⟩ ⟨r₁, s₁⟩ ⟨sb, rb, hb, hb'⟩
    -- s*, r*
    rcases oreCondition (s₁' : R) s₂ with ⟨rc, sc, hc⟩
    --s~~, r~~
    

Proof state:
case mk.mk.intro.intro.intro.mk.mk
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₂ : R
s₂ : ↥S
r₁' : R
s₁' : ↥S
r₁ : R
s₁ : ↥S
sb : ↥S
rb : R
hb : (r₁, s₁).1 * ↑sb = (r₁', s₁').1 * rb
hb' : ↑(r₁, s₁).2 * ↑sb = ↑(r₁', s₁').2 * rb
rc : R
sc : ↥S
hc : ↑s₁' * ↑sc = ↑s₂ * rc
⊢ OreLocalization.add'' (r₁', s₁').1 (r₁', s₁').2 r₂ s₂ = OreLocalization.add'' (r₁, s₁).1 (r₁, s₁).2 r₂ s₂

Next tactic:
rcases oreCondition rb sc with ⟨rd, sd, hd⟩
private def add' (r₂ : R) (s₂ : S) : R[S⁻¹] → R[S⁻¹] :=
  (--plus tilde
      Quotient.lift
      fun r₁s₁ : R × S => add'' r₁s₁.1 r₁s₁.2 r₂ s₂) <| by
    -- Porting note: `assoc_rw` & `noncomm_ring` were not ported yet
    rintro ⟨r₁', s₁'⟩ ⟨r₁, s₁⟩ ⟨sb, rb, hb, hb'⟩
    -- s*, r*
    rcases oreCondition (s₁' : R) s₂ with ⟨rc, sc, hc⟩
    --s~~, r~~
    rcases oreCondition rb sc with ⟨rd, sd, hd⟩
    -- s#, r#
    

Proof state:
case mk.mk.intro.intro.intro.mk.mk.mk.mk
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₂ : R
s₂ : ↥S
r₁' : R
s₁' : ↥S
r₁ : R
s₁ : ↥S
sb : ↥S
rb : R
hb : (r₁, s₁).1 * ↑sb = (r₁', s₁').1 * rb
hb' : ↑(r₁, s₁).2 * ↑sb = ↑(r₁', s₁').2 * rb
rc : R
sc : ↥S
hc : ↑s₁' * ↑sc = ↑s₂ * rc
rd : R
sd : ↥S
hd : rb * ↑sd = ↑sc * rd
⊢ OreLocalization.add'' (r₁', s₁').1 (r₁', s₁').2 r₂ s₂ = OreLocalization.add'' (r₁, s₁).1 (r₁, s₁).2 r₂ s₂

Next tactic:
dsimp at *
private def add' (r₂ : R) (s₂ : S) : R[S⁻¹] → R[S⁻¹] :=
  (--plus tilde
      Quotient.lift
      fun r₁s₁ : R × S => add'' r₁s₁.1 r₁s₁.2 r₂ s₂) <| by
    -- Porting note: `assoc_rw` & `noncomm_ring` were not ported yet
    rintro ⟨r₁', s₁'⟩ ⟨r₁, s₁⟩ ⟨sb, rb, hb, hb'⟩
    -- s*, r*
    rcases oreCondition (s₁' : R) s₂ with ⟨rc, sc, hc⟩
    --s~~, r~~
    rcases oreCondition rb sc with ⟨rd, sd, hd⟩
    -- s#, r#
    dsimp at *
    

Proof state:
case mk.mk.intro.intro.intro.mk.mk.mk.mk
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₂ : R
s₂ : ↥S
r₁' : R
s₁' : ↥S
r₁ : R
s₁ : ↥S
sb : ↥S
rb : R
hb : r₁ * ↑sb = r₁' * rb
hb' : ↑s₁ * ↑sb = ↑s₁' * rb
rc : R
sc : ↥S
hc : ↑s₁' * ↑sc = ↑s₂ * rc
rd : R
sd : ↥S
hd : rb * ↑sd = ↑sc * rd
⊢ OreLocalization.add'' r₁' s₁' r₂ s₂ = OreLocalization.add'' r₁ s₁ r₂ s₂

Next tactic:
rw [add''_char _ _ _ _ rc sc hc]
private def add' (r₂ : R) (s₂ : S) : R[S⁻¹] → R[S⁻¹] :=
  (--plus tilde
      Quotient.lift
      fun r₁s₁ : R × S => add'' r₁s₁.1 r₁s₁.2 r₂ s₂) <| by
    -- Porting note: `assoc_rw` & `noncomm_ring` were not ported yet
    rintro ⟨r₁', s₁'⟩ ⟨r₁, s₁⟩ ⟨sb, rb, hb, hb'⟩
    -- s*, r*
    rcases oreCondition (s₁' : R) s₂ with ⟨rc, sc, hc⟩
    --s~~, r~~
    rcases oreCondition rb sc with ⟨rd, sd, hd⟩
    -- s#, r#
    dsimp at *
    rw [add''_char _ _ _ _ rc sc hc]
    

Proof state:
case mk.mk.intro.intro.intro.mk.mk.mk.mk
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₂ : R
s₂ : ↥S
r₁' : R
s₁' : ↥S
r₁ : R
s₁ : ↥S
sb : ↥S
rb : R
hb : r₁ * ↑sb = r₁' * rb
hb' : ↑s₁ * ↑sb = ↑s₁' * rb
rc : R
sc : ↥S
hc : ↑s₁' * ↑sc = ↑s₂ * rc
rd : R
sd : ↥S
hd : rb * ↑sd = ↑sc * rd
⊢ (r₁' * ↑sc + r₂ * rc) /ₒ (s₁' * sc) = OreLocalization.add'' r₁ s₁ r₂ s₂

Next tactic:
have : ↑s₁ * ↑(sb * sd) = ↑s₂ * (rc * rd) := by
      simp only [Submonoid.coe_mul]
      rw [← mul_assoc, hb', mul_assoc, hd, ← mul_assoc, hc, mul_assoc]
private def add' (r₂ : R) (s₂ : S) : R[S⁻¹] → R[S⁻¹] :=
  (--plus tilde
      Quotient.lift
      fun r₁s₁ : R × S => add'' r₁s₁.1 r₁s₁.2 r₂ s₂) <| by
    -- Porting note: `assoc_rw` & `noncomm_ring` were not ported yet
    rintro ⟨r₁', s₁'⟩ ⟨r₁, s₁⟩ ⟨sb, rb, hb, hb'⟩
    -- s*, r*
    rcases oreCondition (s₁' : R) s₂ with ⟨rc, sc, hc⟩
    --s~~, r~~
    rcases oreCondition rb sc with ⟨rd, sd, hd⟩
    -- s#, r#
    dsimp at *
    rw [add''_char _ _ _ _ rc sc hc]
    have : ↑s₁ * ↑(sb * sd) = ↑s₂ * (rc * rd) := by
      

Proof state:
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₂ : R
s₂ : ↥S
r₁' : R
s₁' : ↥S
r₁ : R
s₁ : ↥S
sb : ↥S
rb : R
hb : r₁ * ↑sb = r₁' * rb
hb' : ↑s₁ * ↑sb = ↑s₁' * rb
rc : R
sc : ↥S
hc : ↑s₁' * ↑sc = ↑s₂ * rc
rd : R
sd : ↥S
hd : rb * ↑sd = ↑sc * rd
⊢ ↑s₁ * ↑(sb * sd) = ↑s₂ * (rc * rd)

Next tactic:
simp only [Submonoid.coe_mul]
private def add' (r₂ : R) (s₂ : S) : R[S⁻¹] → R[S⁻¹] :=
  (--plus tilde
      Quotient.lift
      fun r₁s₁ : R × S => add'' r₁s₁.1 r₁s₁.2 r₂ s₂) <| by
    -- Porting note: `assoc_rw` & `noncomm_ring` were not ported yet
    rintro ⟨r₁', s₁'⟩ ⟨r₁, s₁⟩ ⟨sb, rb, hb, hb'⟩
    -- s*, r*
    rcases oreCondition (s₁' : R) s₂ with ⟨rc, sc, hc⟩
    --s~~, r~~
    rcases oreCondition rb sc with ⟨rd, sd, hd⟩
    -- s#, r#
    dsimp at *
    rw [add''_char _ _ _ _ rc sc hc]
    have : ↑s₁ * ↑(sb * sd) = ↑s₂ * (rc * rd) := by
      simp only [Submonoid.coe_mul]
      

Proof state:
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₂ : R
s₂ : ↥S
r₁' : R
s₁' : ↥S
r₁ : R
s₁ : ↥S
sb : ↥S
rb : R
hb : r₁ * ↑sb = r₁' * rb
hb' : ↑s₁ * ↑sb = ↑s₁' * rb
rc : R
sc : ↥S
hc : ↑s₁' * ↑sc = ↑s₂ * rc
rd : R
sd : ↥S
hd : rb * ↑sd = ↑sc * rd
⊢ ↑s₁ * (↑sb * ↑sd) = ↑s₂ * (rc * rd)

Next tactic:
rw [← mul_assoc, hb', mul_assoc, hd, ← mul_assoc, hc, mul_assoc]
private def add' (r₂ : R) (s₂ : S) : R[S⁻¹] → R[S⁻¹] :=
  (--plus tilde
      Quotient.lift
      fun r₁s₁ : R × S => add'' r₁s₁.1 r₁s₁.2 r₂ s₂) <| by
    -- Porting note: `assoc_rw` & `noncomm_ring` were not ported yet
    rintro ⟨r₁', s₁'⟩ ⟨r₁, s₁⟩ ⟨sb, rb, hb, hb'⟩
    -- s*, r*
    rcases oreCondition (s₁' : R) s₂ with ⟨rc, sc, hc⟩
    --s~~, r~~
    rcases oreCondition rb sc with ⟨rd, sd, hd⟩
    -- s#, r#
    dsimp at *
    rw [add''_char _ _ _ _ rc sc hc]
    have : ↑s₁ * ↑(sb * sd) = ↑s₂ * (rc * rd) := by
      simp only [Submonoid.coe_mul]
      rw [← mul_assoc, hb', mul_assoc, hd, ← mul_assoc, hc, mul_assoc]
    

Proof state:
case mk.mk.intro.intro.intro.mk.mk.mk.mk
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₂ : R
s₂ : ↥S
r₁' : R
s₁' : ↥S
r₁ : R
s₁ : ↥S
sb : ↥S
rb : R
hb : r₁ * ↑sb = r₁' * rb
hb' : ↑s₁ * ↑sb = ↑s₁' * rb
rc : R
sc : ↥S
hc : ↑s₁' * ↑sc = ↑s₂ * rc
rd : R
sd : ↥S
hd : rb * ↑sd = ↑sc * rd
this : ↑s₁ * ↑(sb * sd) = ↑s₂ * (rc * rd)
⊢ (r₁' * ↑sc + r₂ * rc) /ₒ (s₁' * sc) = OreLocalization.add'' r₁ s₁ r₂ s₂

Next tactic:
rw [add''_char _ _ _ _ (rc * rd : R) (sb * sd : S) this]
private def add' (r₂ : R) (s₂ : S) : R[S⁻¹] → R[S⁻¹] :=
  (--plus tilde
      Quotient.lift
      fun r₁s₁ : R × S => add'' r₁s₁.1 r₁s₁.2 r₂ s₂) <| by
    -- Porting note: `assoc_rw` & `noncomm_ring` were not ported yet
    rintro ⟨r₁', s₁'⟩ ⟨r₁, s₁⟩ ⟨sb, rb, hb, hb'⟩
    -- s*, r*
    rcases oreCondition (s₁' : R) s₂ with ⟨rc, sc, hc⟩
    --s~~, r~~
    rcases oreCondition rb sc with ⟨rd, sd, hd⟩
    -- s#, r#
    dsimp at *
    rw [add''_char _ _ _ _ rc sc hc]
    have : ↑s₁ * ↑(sb * sd) = ↑s₂ * (rc * rd) := by
      simp only [Submonoid.coe_mul]
      rw [← mul_assoc, hb', mul_assoc, hd, ← mul_assoc, hc, mul_assoc]
    rw [add''_char _ _ _ _ (rc * rd : R) (sb * sd : S) this]
    

Proof state:
case mk.mk.intro.intro.intro.mk.mk.mk.mk
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₂ : R
s₂ : ↥S
r₁' : R
s₁' : ↥S
r₁ : R
s₁ : ↥S
sb : ↥S
rb : R
hb : r₁ * ↑sb = r₁' * rb
hb' : ↑s₁ * ↑sb = ↑s₁' * rb
rc : R
sc : ↥S
hc : ↑s₁' * ↑sc = ↑s₂ * rc
rd : R
sd : ↥S
hd : rb * ↑sd = ↑sc * rd
this : ↑s₁ * ↑(sb * sd) = ↑s₂ * (rc * rd)
⊢ (r₁' * ↑sc + r₂ * rc) /ₒ (s₁' * sc) = (r₁ * ↑(sb * sd) + r₂ * (rc * rd)) /ₒ (s₁ * (sb * sd))

Next tactic:
simp only [Submonoid.coe_mul]
private def add' (r₂ : R) (s₂ : S) : R[S⁻¹] → R[S⁻¹] :=
  (--plus tilde
      Quotient.lift
      fun r₁s₁ : R × S => add'' r₁s₁.1 r₁s₁.2 r₂ s₂) <| by
    -- Porting note: `assoc_rw` & `noncomm_ring` were not ported yet
    rintro ⟨r₁', s₁'⟩ ⟨r₁, s₁⟩ ⟨sb, rb, hb, hb'⟩
    -- s*, r*
    rcases oreCondition (s₁' : R) s₂ with ⟨rc, sc, hc⟩
    --s~~, r~~
    rcases oreCondition rb sc with ⟨rd, sd, hd⟩
    -- s#, r#
    dsimp at *
    rw [add''_char _ _ _ _ rc sc hc]
    have : ↑s₁ * ↑(sb * sd) = ↑s₂ * (rc * rd) := by
      simp only [Submonoid.coe_mul]
      rw [← mul_assoc, hb', mul_assoc, hd, ← mul_assoc, hc, mul_assoc]
    rw [add''_char _ _ _ _ (rc * rd : R) (sb * sd : S) this]
    simp only [Submonoid.coe_mul]
    

Proof state:
case mk.mk.intro.intro.intro.mk.mk.mk.mk
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₂ : R
s₂ : ↥S
r₁' : R
s₁' : ↥S
r₁ : R
s₁ : ↥S
sb : ↥S
rb : R
hb : r₁ * ↑sb = r₁' * rb
hb' : ↑s₁ * ↑sb = ↑s₁' * rb
rc : R
sc : ↥S
hc : ↑s₁' * ↑sc = ↑s₂ * rc
rd : R
sd : ↥S
hd : rb * ↑sd = ↑sc * rd
this : ↑s₁ * ↑(sb * sd) = ↑s₂ * (rc * rd)
⊢ (r₁' * ↑sc + r₂ * rc) /ₒ (s₁' * sc) = (r₁ * (↑sb * ↑sd) + r₂ * (rc * rd)) /ₒ (s₁ * (sb * sd))

Next tactic:
rw [← mul_assoc (a := r₁) (b := (sb : R)), hb, mul_assoc (a := r₁') (b := (rb : R)), hd,
      ← mul_assoc, ← mul_assoc, ← add_mul, oreDiv_eq_iff]