l3lab/ntp-mathlib huggingface dataset:
protected theorem add_assoc (x y z : R[S⁻¹]) : x + y + z = x + (y + z) := by
  -- Porting note: `assoc_rw` was not ported yet
  induction' x using OreLocalization.ind with r₁ s₁
  induction' y using OreLocalization.ind with r₂ s₂
  induction' z using OreLocalization.ind with r₃ s₃
  rcases oreDivAddChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivAddChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb'
  rcases oreDivAddChar' (r₁ * sa + r₂ * ra) r₃ (s₁ * sa) s₃ with ⟨rc, sc, hc, q⟩; rw [q]; clear q
  rcases oreDivAddChar' r₁ (r₂ * sb + r₃ * rb) s₁ (s₂ * sb) with ⟨rd, sd, hd, q⟩; rw [q]; clear q
  

Proof state:
case c.c.c.mk.mk.intro.mk.mk.intro.mk.mk.intro.mk.mk.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
ra : R
sa : ↥S
ha : ↑s₁ * ↑sa = ↑s₂ * ra
rb : R
sb : ↥S
hb : ↑s₂ * ↑sb = ↑s₃ * rb
rc : R
sc : ↥S
hc : ↑(s₁ * sa) * ↑sc = ↑s₃ * rc
rd : R
sd : ↥S
hd : ↑s₁ * ↑sd = ↑(s₂ * sb) * rd
⊢ ((r₁ * ↑sa + r₂ * ra) * ↑sc + r₃ * rc) /ₒ (s₁ * sa * sc) = (r₁ * ↑sd + (r₂ * ↑sb + r₃ * rb) * rd) /ₒ (s₁ * sd)

Next tactic:
simp only [right_distrib, mul_assoc, add_assoc]
protected theorem add_assoc (x y z : R[S⁻¹]) : x + y + z = x + (y + z) := by
  -- Porting note: `assoc_rw` was not ported yet
  induction' x using OreLocalization.ind with r₁ s₁
  induction' y using OreLocalization.ind with r₂ s₂
  induction' z using OreLocalization.ind with r₃ s₃
  rcases oreDivAddChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivAddChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb'
  rcases oreDivAddChar' (r₁ * sa + r₂ * ra) r₃ (s₁ * sa) s₃ with ⟨rc, sc, hc, q⟩; rw [q]; clear q
  rcases oreDivAddChar' r₁ (r₂ * sb + r₃ * rb) s₁ (s₂ * sb) with ⟨rd, sd, hd, q⟩; rw [q]; clear q
  simp only [right_distrib, mul_assoc, add_assoc]
  -- Porting note: `simp` required because `repeat' rw` behaves differently
  

Proof state:
case c.c.c.mk.mk.intro.mk.mk.intro.mk.mk.intro.mk.mk.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
ra : R
sa : ↥S
ha : ↑s₁ * ↑sa = ↑s₂ * ra
rb : R
sb : ↥S
hb : ↑s₂ * ↑sb = ↑s₃ * rb
rc : R
sc : ↥S
hc : ↑(s₁ * sa) * ↑sc = ↑s₃ * rc
rd : R
sd : ↥S
hd : ↑s₁ * ↑sd = ↑(s₂ * sb) * rd
⊢ (r₁ * (↑sa * ↑sc) + (r₂ * (ra * ↑sc) + r₃ * rc)) /ₒ (s₁ * (sa * sc)) =
    (r₁ * ↑sd + (r₂ * (↑sb * rd) + r₃ * (rb * rd))) /ₒ (s₁ * sd)

Next tactic:
simp only [← add_oreDiv]
protected theorem add_assoc (x y z : R[S⁻¹]) : x + y + z = x + (y + z) := by
  -- Porting note: `assoc_rw` was not ported yet
  induction' x using OreLocalization.ind with r₁ s₁
  induction' y using OreLocalization.ind with r₂ s₂
  induction' z using OreLocalization.ind with r₃ s₃
  rcases oreDivAddChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivAddChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb'
  rcases oreDivAddChar' (r₁ * sa + r₂ * ra) r₃ (s₁ * sa) s₃ with ⟨rc, sc, hc, q⟩; rw [q]; clear q
  rcases oreDivAddChar' r₁ (r₂ * sb + r₃ * rb) s₁ (s₂ * sb) with ⟨rd, sd, hd, q⟩; rw [q]; clear q
  simp only [right_distrib, mul_assoc, add_assoc]
  -- Porting note: `simp` required because `repeat' rw` behaves differently
  simp only [← add_oreDiv]
  

Proof state:
case c.c.c.mk.mk.intro.mk.mk.intro.mk.mk.intro.mk.mk.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
ra : R
sa : ↥S
ha : ↑s₁ * ↑sa = ↑s₂ * ra
rb : R
sb : ↥S
hb : ↑s₂ * ↑sb = ↑s₃ * rb
rc : R
sc : ↥S
hc : ↑(s₁ * sa) * ↑sc = ↑s₃ * rc
rd : R
sd : ↥S
hd : ↑s₁ * ↑sd = ↑(s₂ * sb) * rd
⊢ r₁ * (↑sa * ↑sc) /ₒ (s₁ * (sa * sc)) + (r₂ * (ra * ↑sc) /ₒ (s₁ * (sa * sc)) + r₃ * rc /ₒ (s₁ * (sa * sc))) =
    r₁ * ↑sd /ₒ (s₁ * sd) + (r₂ * (↑sb * rd) /ₒ (s₁ * sd) + r₃ * (rb * rd) /ₒ (s₁ * sd))

Next tactic:
congr 1
protected theorem add_assoc (x y z : R[S⁻¹]) : x + y + z = x + (y + z) := by
  -- Porting note: `assoc_rw` was not ported yet
  induction' x using OreLocalization.ind with r₁ s₁
  induction' y using OreLocalization.ind with r₂ s₂
  induction' z using OreLocalization.ind with r₃ s₃
  rcases oreDivAddChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivAddChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb'
  rcases oreDivAddChar' (r₁ * sa + r₂ * ra) r₃ (s₁ * sa) s₃ with ⟨rc, sc, hc, q⟩; rw [q]; clear q
  rcases oreDivAddChar' r₁ (r₂ * sb + r₃ * rb) s₁ (s₂ * sb) with ⟨rd, sd, hd, q⟩; rw [q]; clear q
  simp only [right_distrib, mul_assoc, add_assoc]
  -- Porting note: `simp` required because `repeat' rw` behaves differently
  simp only [← add_oreDiv]
  congr 1
  · 

Proof state:
case c.c.c.mk.mk.intro.mk.mk.intro.mk.mk.intro.mk.mk.intro.e_a
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
ra : R
sa : ↥S
ha : ↑s₁ * ↑sa = ↑s₂ * ra
rb : R
sb : ↥S
hb : ↑s₂ * ↑sb = ↑s₃ * rb
rc : R
sc : ↥S
hc : ↑(s₁ * sa) * ↑sc = ↑s₃ * rc
rd : R
sd : ↥S
hd : ↑s₁ * ↑sd = ↑(s₂ * sb) * rd
⊢ r₁ * (↑sa * ↑sc) /ₒ (s₁ * (sa * sc)) = r₁ * ↑sd /ₒ (s₁ * sd)

Next tactic:
rw [← OreLocalization.expand', ← mul_assoc, ← mul_assoc, ← OreLocalization.expand', ←
      OreLocalization.expand']
protected theorem add_assoc (x y z : R[S⁻¹]) : x + y + z = x + (y + z) := by
  -- Porting note: `assoc_rw` was not ported yet
  induction' x using OreLocalization.ind with r₁ s₁
  induction' y using OreLocalization.ind with r₂ s₂
  induction' z using OreLocalization.ind with r₃ s₃
  rcases oreDivAddChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivAddChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb'
  rcases oreDivAddChar' (r₁ * sa + r₂ * ra) r₃ (s₁ * sa) s₃ with ⟨rc, sc, hc, q⟩; rw [q]; clear q
  rcases oreDivAddChar' r₁ (r₂ * sb + r₃ * rb) s₁ (s₂ * sb) with ⟨rd, sd, hd, q⟩; rw [q]; clear q
  simp only [right_distrib, mul_assoc, add_assoc]
  -- Porting note: `simp` required because `repeat' rw` behaves differently
  simp only [← add_oreDiv]
  congr 1
  · rw [← OreLocalization.expand', ← mul_assoc, ← mul_assoc, ← OreLocalization.expand', ←
      OreLocalization.expand']
  

Proof state:
case c.c.c.mk.mk.intro.mk.mk.intro.mk.mk.intro.mk.mk.intro.e_a
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
ra : R
sa : ↥S
ha : ↑s₁ * ↑sa = ↑s₂ * ra
rb : R
sb : ↥S
hb : ↑s₂ * ↑sb = ↑s₃ * rb
rc : R
sc : ↥S
hc : ↑(s₁ * sa) * ↑sc = ↑s₃ * rc
rd : R
sd : ↥S
hd : ↑s₁ * ↑sd = ↑(s₂ * sb) * rd
⊢ r₂ * (ra * ↑sc) /ₒ (s₁ * (sa * sc)) + r₃ * rc /ₒ (s₁ * (sa * sc)) =
    r₂ * (↑sb * rd) /ₒ (s₁ * sd) + r₃ * (rb * rd) /ₒ (s₁ * sd)

Next tactic:
congr 1
protected theorem add_assoc (x y z : R[S⁻¹]) : x + y + z = x + (y + z) := by
  -- Porting note: `assoc_rw` was not ported yet
  induction' x using OreLocalization.ind with r₁ s₁
  induction' y using OreLocalization.ind with r₂ s₂
  induction' z using OreLocalization.ind with r₃ s₃
  rcases oreDivAddChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivAddChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb'
  rcases oreDivAddChar' (r₁ * sa + r₂ * ra) r₃ (s₁ * sa) s₃ with ⟨rc, sc, hc, q⟩; rw [q]; clear q
  rcases oreDivAddChar' r₁ (r₂ * sb + r₃ * rb) s₁ (s₂ * sb) with ⟨rd, sd, hd, q⟩; rw [q]; clear q
  simp only [right_distrib, mul_assoc, add_assoc]
  -- Porting note: `simp` required because `repeat' rw` behaves differently
  simp only [← add_oreDiv]
  congr 1
  · rw [← OreLocalization.expand', ← mul_assoc, ← mul_assoc, ← OreLocalization.expand', ←
      OreLocalization.expand']
  congr 1
  · 

Proof state:
case c.c.c.mk.mk.intro.mk.mk.intro.mk.mk.intro.mk.mk.intro.e_a.e_a
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
ra : R
sa : ↥S
ha : ↑s₁ * ↑sa = ↑s₂ * ra
rb : R
sb : ↥S
hb : ↑s₂ * ↑sb = ↑s₃ * rb
rc : R
sc : ↥S
hc : ↑(s₁ * sa) * ↑sc = ↑s₃ * rc
rd : R
sd : ↥S
hd : ↑s₁ * ↑sd = ↑(s₂ * sb) * rd
⊢ r₂ * (ra * ↑sc) /ₒ (s₁ * (sa * sc)) = r₂ * (↑sb * rd) /ₒ (s₁ * sd)

Next tactic:
simp_rw [← Submonoid.coe_mul] at ha hd
protected theorem add_assoc (x y z : R[S⁻¹]) : x + y + z = x + (y + z) := by
  -- Porting note: `assoc_rw` was not ported yet
  induction' x using OreLocalization.ind with r₁ s₁
  induction' y using OreLocalization.ind with r₂ s₂
  induction' z using OreLocalization.ind with r₃ s₃
  rcases oreDivAddChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivAddChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb'
  rcases oreDivAddChar' (r₁ * sa + r₂ * ra) r₃ (s₁ * sa) s₃ with ⟨rc, sc, hc, q⟩; rw [q]; clear q
  rcases oreDivAddChar' r₁ (r₂ * sb + r₃ * rb) s₁ (s₂ * sb) with ⟨rd, sd, hd, q⟩; rw [q]; clear q
  simp only [right_distrib, mul_assoc, add_assoc]
  -- Porting note: `simp` required because `repeat' rw` behaves differently
  simp only [← add_oreDiv]
  congr 1
  · rw [← OreLocalization.expand', ← mul_assoc, ← mul_assoc, ← OreLocalization.expand', ←
      OreLocalization.expand']
  congr 1
  · simp_rw [← Submonoid.coe_mul] at ha hd
    

Proof state:
case c.c.c.mk.mk.intro.mk.mk.intro.mk.mk.intro.mk.mk.intro.e_a.e_a
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
ra : R
sa : ↥S
ha : ↑(s₁ * sa) = ↑s₂ * ra
rb : R
sb : ↥S
hb : ↑s₂ * ↑sb = ↑s₃ * rb
rc : R
sc : ↥S
hc : ↑(s₁ * sa) * ↑sc = ↑s₃ * rc
rd : R
sd : ↥S
hd : ↑(s₁ * sd) = ↑(s₂ * sb) * rd
⊢ r₂ * (ra * ↑sc) /ₒ (s₁ * (sa * sc)) = r₂ * (↑sb * rd) /ₒ (s₁ * sd)

Next tactic:
rw [Subtype.coe_eq_of_eq_mk hd, ← mul_assoc, ← mul_assoc, ← mul_assoc, ← OreLocalization.expand,
      ← OreLocalization.expand', Subtype.coe_eq_of_eq_mk ha, ← OreLocalization.expand]
protected theorem add_assoc (x y z : R[S⁻¹]) : x + y + z = x + (y + z) := by
  -- Porting note: `assoc_rw` was not ported yet
  induction' x using OreLocalization.ind with r₁ s₁
  induction' y using OreLocalization.ind with r₂ s₂
  induction' z using OreLocalization.ind with r₃ s₃
  rcases oreDivAddChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivAddChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb'
  rcases oreDivAddChar' (r₁ * sa + r₂ * ra) r₃ (s₁ * sa) s₃ with ⟨rc, sc, hc, q⟩; rw [q]; clear q
  rcases oreDivAddChar' r₁ (r₂ * sb + r₃ * rb) s₁ (s₂ * sb) with ⟨rd, sd, hd, q⟩; rw [q]; clear q
  simp only [right_distrib, mul_assoc, add_assoc]
  -- Porting note: `simp` required because `repeat' rw` behaves differently
  simp only [← add_oreDiv]
  congr 1
  · rw [← OreLocalization.expand', ← mul_assoc, ← mul_assoc, ← OreLocalization.expand', ←
      OreLocalization.expand']
  congr 1
  · simp_rw [← Submonoid.coe_mul] at ha hd
    rw [Subtype.coe_eq_of_eq_mk hd, ← mul_assoc, ← mul_assoc, ← mul_assoc, ← OreLocalization.expand,
      ← OreLocalization.expand', Subtype.coe_eq_of_eq_mk ha, ← OreLocalization.expand]
    

Proof state:
case c.c.c.mk.mk.intro.mk.mk.intro.mk.mk.intro.mk.mk.intro.e_a.e_a
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
ra : R
sa : ↥S
ha : ↑(s₁ * sa) = ↑s₂ * ra
rb : R
sb : ↥S
hb : ↑s₂ * ↑sb = ↑s₃ * rb
rc : R
sc : ↥S
hc : ↑(s₁ * sa) * ↑sc = ↑s₃ * rc
rd : R
sd : ↥S
hd : ↑(s₁ * sd) = ↑(s₂ * sb) * rd
⊢ r₂ /ₒ s₂ = r₂ * ↑sb /ₒ (s₂ * sb)

Next tactic:
apply OreLocalization.expand'
protected theorem add_assoc (x y z : R[S⁻¹]) : x + y + z = x + (y + z) := by
  -- Porting note: `assoc_rw` was not ported yet
  induction' x using OreLocalization.ind with r₁ s₁
  induction' y using OreLocalization.ind with r₂ s₂
  induction' z using OreLocalization.ind with r₃ s₃
  rcases oreDivAddChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivAddChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb'
  rcases oreDivAddChar' (r₁ * sa + r₂ * ra) r₃ (s₁ * sa) s₃ with ⟨rc, sc, hc, q⟩; rw [q]; clear q
  rcases oreDivAddChar' r₁ (r₂ * sb + r₃ * rb) s₁ (s₂ * sb) with ⟨rd, sd, hd, q⟩; rw [q]; clear q
  simp only [right_distrib, mul_assoc, add_assoc]
  -- Porting note: `simp` required because `repeat' rw` behaves differently
  simp only [← add_oreDiv]
  congr 1
  · rw [← OreLocalization.expand', ← mul_assoc, ← mul_assoc, ← OreLocalization.expand', ←
      OreLocalization.expand']
  congr 1
  · simp_rw [← Submonoid.coe_mul] at ha hd
    rw [Subtype.coe_eq_of_eq_mk hd, ← mul_assoc, ← mul_assoc, ← mul_assoc, ← OreLocalization.expand,
      ← OreLocalization.expand', Subtype.coe_eq_of_eq_mk ha, ← OreLocalization.expand]
    apply OreLocalization.expand'
  · 

Proof state:
case c.c.c.mk.mk.intro.mk.mk.intro.mk.mk.intro.mk.mk.intro.e_a.e_a
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
ra : R
sa : ↥S
ha : ↑s₁ * ↑sa = ↑s₂ * ra
rb : R
sb : ↥S
hb : ↑s₂ * ↑sb = ↑s₃ * rb
rc : R
sc : ↥S
hc : ↑(s₁ * sa) * ↑sc = ↑s₃ * rc
rd : R
sd : ↥S
hd : ↑s₁ * ↑sd = ↑(s₂ * sb) * rd
⊢ r₃ * rc /ₒ (s₁ * (sa * sc)) = r₃ * (rb * rd) /ₒ (s₁ * sd)

Next tactic:
rcases oreCondition (sd : R) (sa * sc) with ⟨re, _, _⟩
protected theorem add_assoc (x y z : R[S⁻¹]) : x + y + z = x + (y + z) := by
  -- Porting note: `assoc_rw` was not ported yet
  induction' x using OreLocalization.ind with r₁ s₁
  induction' y using OreLocalization.ind with r₂ s₂
  induction' z using OreLocalization.ind with r₃ s₃
  rcases oreDivAddChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivAddChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb'
  rcases oreDivAddChar' (r₁ * sa + r₂ * ra) r₃ (s₁ * sa) s₃ with ⟨rc, sc, hc, q⟩; rw [q]; clear q
  rcases oreDivAddChar' r₁ (r₂ * sb + r₃ * rb) s₁ (s₂ * sb) with ⟨rd, sd, hd, q⟩; rw [q]; clear q
  simp only [right_distrib, mul_assoc, add_assoc]
  -- Porting note: `simp` required because `repeat' rw` behaves differently
  simp only [← add_oreDiv]
  congr 1
  · rw [← OreLocalization.expand', ← mul_assoc, ← mul_assoc, ← OreLocalization.expand', ←
      OreLocalization.expand']
  congr 1
  · simp_rw [← Submonoid.coe_mul] at ha hd
    rw [Subtype.coe_eq_of_eq_mk hd, ← mul_assoc, ← mul_assoc, ← mul_assoc, ← OreLocalization.expand,
      ← OreLocalization.expand', Subtype.coe_eq_of_eq_mk ha, ← OreLocalization.expand]
    apply OreLocalization.expand'
  · rcases oreCondition (sd : R) (sa * sc) with ⟨re, _, _⟩
    · 

Proof state:
case c.c.c.mk.mk.intro.mk.mk.intro.mk.mk.intro.mk.mk.intro.e_a.e_a.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
ra : R
sa : ↥S
ha : ↑s₁ * ↑sa = ↑s₂ * ra
rb : R
sb : ↥S
hb : ↑s₂ * ↑sb = ↑s₃ * rb
rc : R
sc : ↥S
hc : ↑(s₁ * sa) * ↑sc = ↑s₃ * rc
rd : R
sd : ↥S
hd : ↑s₁ * ↑sd = ↑(s₂ * sb) * rd
re : R
fst✝ : ↥S
snd✝ : ↑sd * ↑fst✝ = ↑(sa * sc) * re
⊢ r₃ * rc /ₒ (s₁ * (sa * sc)) = r₃ * (rb * rd) /ₒ (s₁ * sd)

Next tactic:
simp_rw [← Submonoid.coe_mul] at hb hc hd
protected theorem add_assoc (x y z : R[S⁻¹]) : x + y + z = x + (y + z) := by
  -- Porting note: `assoc_rw` was not ported yet
  induction' x using OreLocalization.ind with r₁ s₁
  induction' y using OreLocalization.ind with r₂ s₂
  induction' z using OreLocalization.ind with r₃ s₃
  rcases oreDivAddChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivAddChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb'
  rcases oreDivAddChar' (r₁ * sa + r₂ * ra) r₃ (s₁ * sa) s₃ with ⟨rc, sc, hc, q⟩; rw [q]; clear q
  rcases oreDivAddChar' r₁ (r₂ * sb + r₃ * rb) s₁ (s₂ * sb) with ⟨rd, sd, hd, q⟩; rw [q]; clear q
  simp only [right_distrib, mul_assoc, add_assoc]
  -- Porting note: `simp` required because `repeat' rw` behaves differently
  simp only [← add_oreDiv]
  congr 1
  · rw [← OreLocalization.expand', ← mul_assoc, ← mul_assoc, ← OreLocalization.expand', ←
      OreLocalization.expand']
  congr 1
  · simp_rw [← Submonoid.coe_mul] at ha hd
    rw [Subtype.coe_eq_of_eq_mk hd, ← mul_assoc, ← mul_assoc, ← mul_assoc, ← OreLocalization.expand,
      ← OreLocalization.expand', Subtype.coe_eq_of_eq_mk ha, ← OreLocalization.expand]
    apply OreLocalization.expand'
  · rcases oreCondition (sd : R) (sa * sc) with ⟨re, _, _⟩
    · simp_rw [← Submonoid.coe_mul] at hb hc hd
      

Proof state:
case c.c.c.mk.mk.intro.mk.mk.intro.mk.mk.intro.mk.mk.intro.e_a.e_a.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
ra : R
sa : ↥S
ha : ↑s₁ * ↑sa = ↑s₂ * ra
rb : R
sb : ↥S
hb : ↑(s₂ * sb) = ↑s₃ * rb
rc : R
sc : ↥S
hc : ↑(s₁ * sa * sc) = ↑s₃ * rc
rd : R
sd : ↥S
hd : ↑(s₁ * sd) = ↑(s₂ * sb) * rd
re : R
fst✝ : ↥S
snd✝ : ↑sd * ↑fst✝ = ↑(sa * sc) * re
⊢ r₃ * rc /ₒ (s₁ * (sa * sc)) = r₃ * (rb * rd) /ₒ (s₁ * sd)

Next tactic:
rw [← mul_assoc, Subtype.coe_eq_of_eq_mk hc]
protected theorem add_assoc (x y z : R[S⁻¹]) : x + y + z = x + (y + z) := by
  -- Porting note: `assoc_rw` was not ported yet
  induction' x using OreLocalization.ind with r₁ s₁
  induction' y using OreLocalization.ind with r₂ s₂
  induction' z using OreLocalization.ind with r₃ s₃
  rcases oreDivAddChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivAddChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb'
  rcases oreDivAddChar' (r₁ * sa + r₂ * ra) r₃ (s₁ * sa) s₃ with ⟨rc, sc, hc, q⟩; rw [q]; clear q
  rcases oreDivAddChar' r₁ (r₂ * sb + r₃ * rb) s₁ (s₂ * sb) with ⟨rd, sd, hd, q⟩; rw [q]; clear q
  simp only [right_distrib, mul_assoc, add_assoc]
  -- Porting note: `simp` required because `repeat' rw` behaves differently
  simp only [← add_oreDiv]
  congr 1
  · rw [← OreLocalization.expand', ← mul_assoc, ← mul_assoc, ← OreLocalization.expand', ←
      OreLocalization.expand']
  congr 1
  · simp_rw [← Submonoid.coe_mul] at ha hd
    rw [Subtype.coe_eq_of_eq_mk hd, ← mul_assoc, ← mul_assoc, ← mul_assoc, ← OreLocalization.expand,
      ← OreLocalization.expand', Subtype.coe_eq_of_eq_mk ha, ← OreLocalization.expand]
    apply OreLocalization.expand'
  · rcases oreCondition (sd : R) (sa * sc) with ⟨re, _, _⟩
    · simp_rw [← Submonoid.coe_mul] at hb hc hd
      rw [← mul_assoc, Subtype.coe_eq_of_eq_mk hc]
      

Proof state:
case c.c.c.mk.mk.intro.mk.mk.intro.mk.mk.intro.mk.mk.intro.e_a.e_a.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
ra : R
sa : ↥S
ha : ↑s₁ * ↑sa = ↑s₂ * ra
rb : R
sb : ↥S
hb : ↑(s₂ * sb) = ↑s₃ * rb
rc : R
sc : ↥S
hc : ↑(s₁ * sa * sc) = ↑s₃ * rc
rd : R
sd : ↥S
hd : ↑(s₁ * sd) = ↑(s₂ * sb) * rd
re : R
fst✝ : ↥S
snd✝ : ↑sd * ↑fst✝ = ↑(sa * sc) * re
⊢ r₃ * rc /ₒ { val := ↑s₃ * rc, property := (_ : ↑s₃ * rc ∈ ↑S) } = r₃ * (rb * rd) /ₒ (s₁ * sd)

Next tactic:
rw [← OreLocalization.expand, Subtype.coe_eq_of_eq_mk hd, ← mul_assoc, ←
        OreLocalization.expand, Subtype.coe_eq_of_eq_mk hb]
protected theorem add_assoc (x y z : R[S⁻¹]) : x + y + z = x + (y + z) := by
  -- Porting note: `assoc_rw` was not ported yet
  induction' x using OreLocalization.ind with r₁ s₁
  induction' y using OreLocalization.ind with r₂ s₂
  induction' z using OreLocalization.ind with r₃ s₃
  rcases oreDivAddChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivAddChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb'
  rcases oreDivAddChar' (r₁ * sa + r₂ * ra) r₃ (s₁ * sa) s₃ with ⟨rc, sc, hc, q⟩; rw [q]; clear q
  rcases oreDivAddChar' r₁ (r₂ * sb + r₃ * rb) s₁ (s₂ * sb) with ⟨rd, sd, hd, q⟩; rw [q]; clear q
  simp only [right_distrib, mul_assoc, add_assoc]
  -- Porting note: `simp` required because `repeat' rw` behaves differently
  simp only [← add_oreDiv]
  congr 1
  · rw [← OreLocalization.expand', ← mul_assoc, ← mul_assoc, ← OreLocalization.expand', ←
      OreLocalization.expand']
  congr 1
  · simp_rw [← Submonoid.coe_mul] at ha hd
    rw [Subtype.coe_eq_of_eq_mk hd, ← mul_assoc, ← mul_assoc, ← mul_assoc, ← OreLocalization.expand,
      ← OreLocalization.expand', Subtype.coe_eq_of_eq_mk ha, ← OreLocalization.expand]
    apply OreLocalization.expand'
  · rcases oreCondition (sd : R) (sa * sc) with ⟨re, _, _⟩
    · simp_rw [← Submonoid.coe_mul] at hb hc hd
      rw [← mul_assoc, Subtype.coe_eq_of_eq_mk hc]
      rw [← OreLocalization.expand, Subtype.coe_eq_of_eq_mk hd, ← mul_assoc, ←
        OreLocalization.expand, Subtype.coe_eq_of_eq_mk hb]
      

Proof state:
case c.c.c.mk.mk.intro.mk.mk.intro.mk.mk.intro.mk.mk.intro.e_a.e_a.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
ra : R
sa : ↥S
ha : ↑s₁ * ↑sa = ↑s₂ * ra
rb : R
sb : ↥S
hb : ↑(s₂ * sb) = ↑s₃ * rb
rc : R
sc : ↥S
hc : ↑(s₁ * sa * sc) = ↑s₃ * rc
rd : R
sd : ↥S
hd : ↑(s₁ * sd) = ↑(s₂ * sb) * rd
re : R
fst✝ : ↥S
snd✝ : ↑sd * ↑fst✝ = ↑(sa * sc) * re
⊢ r₃ /ₒ s₃ = r₃ * rb /ₒ { val := ↑s₃ * rb, property := (_ : ↑s₃ * rb ∈ ↑S) }

Next tactic:
apply OreLocalization.expand
@[simp]
theorem zero_div_eq_zero (s : S) : 0 /ₒ s = 0 := by
  

Proof state:
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
s : ↥S
⊢ 0 /ₒ s = 0

Next tactic:
rw [OreLocalization.zero_def, oreDiv_eq_iff]
@[simp]
theorem zero_div_eq_zero (s : S) : 0 /ₒ s = 0 := by
  rw [OreLocalization.zero_def, oreDiv_eq_iff]
  

Proof state:
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
s : ↥S
⊢ ∃ u v, 0 * ↑u = 0 * v ∧ ↑1 * ↑u = ↑s * v

Next tactic:
exact ⟨s, 1, by simp⟩
@[simp]
theorem zero_div_eq_zero (s : S) : 0 /ₒ s = 0 := by
  rw [OreLocalization.zero_def, oreDiv_eq_iff]
  exact ⟨s, 1, by 

Proof state:
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
s : ↥S
⊢ 0 * ↑s = 0 * 1 ∧ ↑1 * ↑s = ↑s * 1

Next tactic:
simp
protected theorem zero_add (x : R[S⁻¹]) : 0 + x = x := by
  

Proof state:
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
x : OreLocalization R S
⊢ 0 + x = x

Next tactic:
induction x using OreLocalization.ind
protected theorem zero_add (x : R[S⁻¹]) : 0 + x = x := by
  induction x using OreLocalization.ind
  

Proof state:
case c
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r✝ : R
s✝ : ↥S
⊢ 0 + r✝ /ₒ s✝ = r✝ /ₒ s✝

Next tactic:
rw [← zero_div_eq_zero, add_oreDiv]
protected theorem zero_add (x : R[S⁻¹]) : 0 + x = x := by
  induction x using OreLocalization.ind
  rw [← zero_div_eq_zero, add_oreDiv]; 

Proof state:
case c
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r✝ : R
s✝ : ↥S
⊢ (0 + r✝) /ₒ s✝ = r✝ /ₒ s✝

Next tactic:
simp
protected theorem add_comm (x y : R[S⁻¹]) : x + y = y + x := by
  

Proof state:
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
x y : OreLocalization R S
⊢ x + y = y + x

Next tactic:
induction x using OreLocalization.ind
protected theorem add_comm (x y : R[S⁻¹]) : x + y = y + x := by
  induction x using OreLocalization.ind
  

Proof state:
case c
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
y : OreLocalization R S
r✝ : R
s✝ : ↥S
⊢ r✝ /ₒ s✝ + y = y + r✝ /ₒ s✝

Next tactic:
induction y using OreLocalization.ind
protected theorem add_comm (x y : R[S⁻¹]) : x + y = y + x := by
  induction x using OreLocalization.ind
  induction y using OreLocalization.ind
  

Proof state:
case c.c
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r✝¹ : R
s✝¹ : ↥S
r✝ : R
s✝ : ↥S
⊢ r✝¹ /ₒ s✝¹ + r✝ /ₒ s✝ = r✝ /ₒ s✝ + r✝¹ /ₒ s✝¹

Next tactic:
change add' _ _ (_ /ₒ _) = _
protected theorem add_comm (x y : R[S⁻¹]) : x + y = y + x := by
  induction x using OreLocalization.ind
  induction y using OreLocalization.ind
  change add' _ _ (_ /ₒ _) = _; 

Proof state:
case c.c
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r✝¹ : R
s✝¹ : ↥S
r✝ : R
s✝ : ↥S
⊢ OreLocalization.add' (r✝, s✝).1 (r✝, s✝).2 (r✝¹ /ₒ s✝¹) = r✝ /ₒ s✝ + r✝¹ /ₒ s✝¹

Next tactic:
apply add'_comm
instance instAddCommMonoidOreLocalization : AddCommMonoid R[S⁻¹] :=
  { OreLocalization.instAddOreLocalization with
    add_comm := OreLocalization.add_comm
    add_assoc := OreLocalization.add_assoc
    zero := zero
    zero_add := OreLocalization.zero_add
    add_zero := fun x => by 

Proof state:
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
src✝ : Add (OreLocalization R S) := instAddOreLocalization
x : OreLocalization R S
⊢ x + 0 = x

Next tactic:
rw [OreLocalization.add_comm, OreLocalization.zero_add]
protected theorem zero_mul (x : R[S⁻¹]) : 0 * x = 0 := by
  

Proof state:
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
x : OreLocalization R S
⊢ 0 * x = 0

Next tactic:
induction' x using OreLocalization.ind with r s