l3lab/ntp-mathlib huggingface dataset:
protected theorem left_distrib (x y z : R[S⁻¹]) : x * (y + z) = x * y + x * z := by
  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, q⟩
  rw [q]
  clear q
  rw [OreLocalization.expand' r₂ s₂ sa]
  rcases oreDivMulChar' r₁ (r₂ * sa) s₁ (s₂ * sa) with ⟨rb, sb, hb, q⟩
  rw [q]
  clear q
  have hs₃rasb : ↑s₃ * (ra * sb) ∈ S := by
    rw [← mul_assoc, ← ha]
    norm_cast
    apply SetLike.coe_mem
  rw [OreLocalization.expand _ _ _ hs₃rasb]
  have ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * sb) := by simp [ha, ← mul_assoc]
  rw [← Subtype.coe_eq_of_eq_mk ha']
  rcases oreDivMulChar' r₁ (r₃ * (ra * sb)) s₁ (s₂ * sa * sb) with ⟨rc, sc, hc, hc'⟩
  rw [hc']
  rw [oreDiv_add_char (s₂ * sa * sb) (s₂ * sa * sb * sc) 1 sc (by simp)]
  rw [OreLocalization.expand' (r₂ * ↑sa + r₃ * ra) (s₂ * sa) (sb * sc)]
  

Proof state:
case c.c.c.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 : r₂ * ↑sa * ↑sb = ↑s₁ * rb
hs₃rasb : ↑s₃ * (ra * ↑sb) ∈ S
ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * ↑sb)
rc : R
sc : ↥S
hc : r₃ * (ra * ↑sb) * ↑sc = ↑s₁ * rc
hc' : r₁ /ₒ s₁ * (r₃ * (ra * ↑sb) /ₒ (s₂ * sa * sb)) = r₁ * rc /ₒ (s₂ * sa * sb * sc)
⊢ r₁ /ₒ s₁ * ((r₂ * ↑sa + r₃ * ra) * ↑(sb * sc) /ₒ (s₂ * sa * (sb * sc))) =
    (r₁ * rb * ↑sc + r₁ * rc * 1) /ₒ (s₂ * sa * sb * sc)

Next tactic:
conv_lhs =>
    congr
    · skip
    congr
    rw [add_mul, S.coe_mul, ← mul_assoc, hb, ← mul_assoc, mul_assoc r₃, hc, mul_assoc, ← mul_add]
protected theorem left_distrib (x y z : R[S⁻¹]) : x * (y + z) = x * y + x * z := by
  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, q⟩
  rw [q]
  clear q
  rw [OreLocalization.expand' r₂ s₂ sa]
  rcases oreDivMulChar' r₁ (r₂ * sa) s₁ (s₂ * sa) with ⟨rb, sb, hb, q⟩
  rw [q]
  clear q
  have hs₃rasb : ↑s₃ * (ra * sb) ∈ S := by
    rw [← mul_assoc, ← ha]
    norm_cast
    apply SetLike.coe_mem
  rw [OreLocalization.expand _ _ _ hs₃rasb]
  have ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * sb) := by simp [ha, ← mul_assoc]
  rw [← Subtype.coe_eq_of_eq_mk ha']
  rcases oreDivMulChar' r₁ (r₃ * (ra * sb)) s₁ (s₂ * sa * sb) with ⟨rc, sc, hc, hc'⟩
  rw [hc']
  rw [oreDiv_add_char (s₂ * sa * sb) (s₂ * sa * sb * sc) 1 sc (by simp)]
  rw [OreLocalization.expand' (r₂ * ↑sa + r₃ * ra) (s₂ * sa) (sb * sc)]
  conv_lhs =>
    

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
ra : R
sa : ↥S
ha : ↑s₂ * ↑sa = ↑s₃ * ra
rb : R
sb : ↥S
hb : r₂ * ↑sa * ↑sb = ↑s₁ * rb
hs₃rasb : ↑s₃ * (ra * ↑sb) ∈ S
ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * ↑sb)
rc : R
sc : ↥S
hc : r₃ * (ra * ↑sb) * ↑sc = ↑s₁ * rc
hc' : r₁ /ₒ s₁ * (r₃ * (ra * ↑sb) /ₒ (s₂ * sa * sb)) = r₁ * rc /ₒ (s₂ * sa * sb * sc)
| r₁ /ₒ s₁ * ((r₂ * ↑sa + r₃ * ra) * ↑(sb * sc) /ₒ (s₂ * sa * (sb * sc)))

Next tactic:
congr
    · skip
    congr
    rw [add_mul, S.coe_mul, ← mul_assoc, hb, ← mul_assoc, mul_assoc r₃, hc, mul_assoc, ← mul_add]
protected theorem left_distrib (x y z : R[S⁻¹]) : x * (y + z) = x * y + x * z := by
  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, q⟩
  rw [q]
  clear q
  rw [OreLocalization.expand' r₂ s₂ sa]
  rcases oreDivMulChar' r₁ (r₂ * sa) s₁ (s₂ * sa) with ⟨rb, sb, hb, q⟩
  rw [q]
  clear q
  have hs₃rasb : ↑s₃ * (ra * sb) ∈ S := by
    rw [← mul_assoc, ← ha]
    norm_cast
    apply SetLike.coe_mem
  rw [OreLocalization.expand _ _ _ hs₃rasb]
  have ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * sb) := by simp [ha, ← mul_assoc]
  rw [← Subtype.coe_eq_of_eq_mk ha']
  rcases oreDivMulChar' r₁ (r₃ * (ra * sb)) s₁ (s₂ * sa * sb) with ⟨rc, sc, hc, hc'⟩
  rw [hc']
  rw [oreDiv_add_char (s₂ * sa * sb) (s₂ * sa * sb * sc) 1 sc (by simp)]
  rw [OreLocalization.expand' (r₂ * ↑sa + r₃ * ra) (s₂ * sa) (sb * sc)]
  conv_lhs =>
    

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
ra : R
sa : ↥S
ha : ↑s₂ * ↑sa = ↑s₃ * ra
rb : R
sb : ↥S
hb : r₂ * ↑sa * ↑sb = ↑s₁ * rb
hs₃rasb : ↑s₃ * (ra * ↑sb) ∈ S
ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * ↑sb)
rc : R
sc : ↥S
hc : r₃ * (ra * ↑sb) * ↑sc = ↑s₁ * rc
hc' : r₁ /ₒ s₁ * (r₃ * (ra * ↑sb) /ₒ (s₂ * sa * sb)) = r₁ * rc /ₒ (s₂ * sa * sb * sc)
| r₁ /ₒ s₁ * ((r₂ * ↑sa + r₃ * ra) * ↑(sb * sc) /ₒ (s₂ * sa * (sb * sc)))

Next tactic:
congr
protected theorem left_distrib (x y z : R[S⁻¹]) : x * (y + z) = x * y + x * z := by
  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, q⟩
  rw [q]
  clear q
  rw [OreLocalization.expand' r₂ s₂ sa]
  rcases oreDivMulChar' r₁ (r₂ * sa) s₁ (s₂ * sa) with ⟨rb, sb, hb, q⟩
  rw [q]
  clear q
  have hs₃rasb : ↑s₃ * (ra * sb) ∈ S := by
    rw [← mul_assoc, ← ha]
    norm_cast
    apply SetLike.coe_mem
  rw [OreLocalization.expand _ _ _ hs₃rasb]
  have ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * sb) := by simp [ha, ← mul_assoc]
  rw [← Subtype.coe_eq_of_eq_mk ha']
  rcases oreDivMulChar' r₁ (r₃ * (ra * sb)) s₁ (s₂ * sa * sb) with ⟨rc, sc, hc, hc'⟩
  rw [hc']
  rw [oreDiv_add_char (s₂ * sa * sb) (s₂ * sa * sb * sc) 1 sc (by simp)]
  rw [OreLocalization.expand' (r₂ * ↑sa + r₃ * ra) (s₂ * sa) (sb * sc)]
  conv_lhs =>
    congr
    

Proof state:
case 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 : r₂ * ↑sa * ↑sb = ↑s₁ * rb
hs₃rasb : ↑s₃ * (ra * ↑sb) ∈ S
ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * ↑sb)
rc : R
sc : ↥S
hc : r₃ * (ra * ↑sb) * ↑sc = ↑s₁ * rc
hc' : r₁ /ₒ s₁ * (r₃ * (ra * ↑sb) /ₒ (s₂ * sa * sb)) = r₁ * rc /ₒ (s₂ * sa * sb * sc)
| r₁ /ₒ s₁
case 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 : r₂ * ↑sa * ↑sb = ↑s₁ * rb
hs₃rasb : ↑s₃ * (ra * ↑sb) ∈ S
ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * ↑sb)
rc : R
sc : ↥S
hc : r₃ * (ra * ↑sb) * ↑sc = ↑s₁ * rc
hc' : r₁ /ₒ s₁ * (r₃ * (ra * ↑sb) /ₒ (s₂ * sa * sb)) = r₁ * rc /ₒ (s₂ * sa * sb * sc)
| (r₂ * ↑sa + r₃ * ra) * ↑(sb * sc) /ₒ (s₂ * sa * (sb * sc))

Next tactic:
· skip
protected theorem left_distrib (x y z : R[S⁻¹]) : x * (y + z) = x * y + x * z := by
  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, q⟩
  rw [q]
  clear q
  rw [OreLocalization.expand' r₂ s₂ sa]
  rcases oreDivMulChar' r₁ (r₂ * sa) s₁ (s₂ * sa) with ⟨rb, sb, hb, q⟩
  rw [q]
  clear q
  have hs₃rasb : ↑s₃ * (ra * sb) ∈ S := by
    rw [← mul_assoc, ← ha]
    norm_cast
    apply SetLike.coe_mem
  rw [OreLocalization.expand _ _ _ hs₃rasb]
  have ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * sb) := by simp [ha, ← mul_assoc]
  rw [← Subtype.coe_eq_of_eq_mk ha']
  rcases oreDivMulChar' r₁ (r₃ * (ra * sb)) s₁ (s₂ * sa * sb) with ⟨rc, sc, hc, hc'⟩
  rw [hc']
  rw [oreDiv_add_char (s₂ * sa * sb) (s₂ * sa * sb * sc) 1 sc (by simp)]
  rw [OreLocalization.expand' (r₂ * ↑sa + r₃ * ra) (s₂ * sa) (sb * sc)]
  conv_lhs =>
    congr
    · 

Proof state:
case 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 : r₂ * ↑sa * ↑sb = ↑s₁ * rb
hs₃rasb : ↑s₃ * (ra * ↑sb) ∈ S
ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * ↑sb)
rc : R
sc : ↥S
hc : r₃ * (ra * ↑sb) * ↑sc = ↑s₁ * rc
hc' : r₁ /ₒ s₁ * (r₃ * (ra * ↑sb) /ₒ (s₂ * sa * sb)) = r₁ * rc /ₒ (s₂ * sa * sb * sc)
| r₁ /ₒ s₁

Next tactic:
skip
protected theorem left_distrib (x y z : R[S⁻¹]) : x * (y + z) = x * y + x * z := by
  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, q⟩
  rw [q]
  clear q
  rw [OreLocalization.expand' r₂ s₂ sa]
  rcases oreDivMulChar' r₁ (r₂ * sa) s₁ (s₂ * sa) with ⟨rb, sb, hb, q⟩
  rw [q]
  clear q
  have hs₃rasb : ↑s₃ * (ra * sb) ∈ S := by
    rw [← mul_assoc, ← ha]
    norm_cast
    apply SetLike.coe_mem
  rw [OreLocalization.expand _ _ _ hs₃rasb]
  have ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * sb) := by simp [ha, ← mul_assoc]
  rw [← Subtype.coe_eq_of_eq_mk ha']
  rcases oreDivMulChar' r₁ (r₃ * (ra * sb)) s₁ (s₂ * sa * sb) with ⟨rc, sc, hc, hc'⟩
  rw [hc']
  rw [oreDiv_add_char (s₂ * sa * sb) (s₂ * sa * sb * sc) 1 sc (by simp)]
  rw [OreLocalization.expand' (r₂ * ↑sa + r₃ * ra) (s₂ * sa) (sb * sc)]
  conv_lhs =>
    congr
    · skip
    

Proof state:
case 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 : r₂ * ↑sa * ↑sb = ↑s₁ * rb
hs₃rasb : ↑s₃ * (ra * ↑sb) ∈ S
ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * ↑sb)
rc : R
sc : ↥S
hc : r₃ * (ra * ↑sb) * ↑sc = ↑s₁ * rc
hc' : r₁ /ₒ s₁ * (r₃ * (ra * ↑sb) /ₒ (s₂ * sa * sb)) = r₁ * rc /ₒ (s₂ * sa * sb * sc)
| (r₂ * ↑sa + r₃ * ra) * ↑(sb * sc) /ₒ (s₂ * sa * (sb * sc))

Next tactic:
congr
protected theorem left_distrib (x y z : R[S⁻¹]) : x * (y + z) = x * y + x * z := by
  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, q⟩
  rw [q]
  clear q
  rw [OreLocalization.expand' r₂ s₂ sa]
  rcases oreDivMulChar' r₁ (r₂ * sa) s₁ (s₂ * sa) with ⟨rb, sb, hb, q⟩
  rw [q]
  clear q
  have hs₃rasb : ↑s₃ * (ra * sb) ∈ S := by
    rw [← mul_assoc, ← ha]
    norm_cast
    apply SetLike.coe_mem
  rw [OreLocalization.expand _ _ _ hs₃rasb]
  have ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * sb) := by simp [ha, ← mul_assoc]
  rw [← Subtype.coe_eq_of_eq_mk ha']
  rcases oreDivMulChar' r₁ (r₃ * (ra * sb)) s₁ (s₂ * sa * sb) with ⟨rc, sc, hc, hc'⟩
  rw [hc']
  rw [oreDiv_add_char (s₂ * sa * sb) (s₂ * sa * sb * sc) 1 sc (by simp)]
  rw [OreLocalization.expand' (r₂ * ↑sa + r₃ * ra) (s₂ * sa) (sb * sc)]
  conv_lhs =>
    congr
    · skip
    congr
    

Proof state:
case a.r
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 : r₂ * ↑sa * ↑sb = ↑s₁ * rb
hs₃rasb : ↑s₃ * (ra * ↑sb) ∈ S
ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * ↑sb)
rc : R
sc : ↥S
hc : r₃ * (ra * ↑sb) * ↑sc = ↑s₁ * rc
hc' : r₁ /ₒ s₁ * (r₃ * (ra * ↑sb) /ₒ (s₂ * sa * sb)) = r₁ * rc /ₒ (s₂ * sa * sb * sc)
| (r₂ * ↑sa + r₃ * ra) * ↑(sb * sc)
case a.s
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 : r₂ * ↑sa * ↑sb = ↑s₁ * rb
hs₃rasb : ↑s₃ * (ra * ↑sb) ∈ S
ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * ↑sb)
rc : R
sc : ↥S
hc : r₃ * (ra * ↑sb) * ↑sc = ↑s₁ * rc
hc' : r₁ /ₒ s₁ * (r₃ * (ra * ↑sb) /ₒ (s₂ * sa * sb)) = r₁ * rc /ₒ (s₂ * sa * sb * sc)
| s₂ * sa * (sb * sc)

Next tactic:
rw [add_mul, S.coe_mul, ← mul_assoc, hb, ← mul_assoc, mul_assoc r₃, hc, mul_assoc, ← mul_add]
protected theorem left_distrib (x y z : R[S⁻¹]) : x * (y + z) = x * y + x * z := by
  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, q⟩
  rw [q]
  clear q
  rw [OreLocalization.expand' r₂ s₂ sa]
  rcases oreDivMulChar' r₁ (r₂ * sa) s₁ (s₂ * sa) with ⟨rb, sb, hb, q⟩
  rw [q]
  clear q
  have hs₃rasb : ↑s₃ * (ra * sb) ∈ S := by
    rw [← mul_assoc, ← ha]
    norm_cast
    apply SetLike.coe_mem
  rw [OreLocalization.expand _ _ _ hs₃rasb]
  have ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * sb) := by simp [ha, ← mul_assoc]
  rw [← Subtype.coe_eq_of_eq_mk ha']
  rcases oreDivMulChar' r₁ (r₃ * (ra * sb)) s₁ (s₂ * sa * sb) with ⟨rc, sc, hc, hc'⟩
  rw [hc']
  rw [oreDiv_add_char (s₂ * sa * sb) (s₂ * sa * sb * sc) 1 sc (by simp)]
  rw [OreLocalization.expand' (r₂ * ↑sa + r₃ * ra) (s₂ * sa) (sb * sc)]
  conv_lhs =>
    congr
    · skip
    congr
    rw [add_mul, S.coe_mul, ← mul_assoc, hb, ← mul_assoc, mul_assoc r₃, hc, mul_assoc, ← mul_add]
  

Proof state:
case c.c.c.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 : r₂ * ↑sa * ↑sb = ↑s₁ * rb
hs₃rasb : ↑s₃ * (ra * ↑sb) ∈ S
ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * ↑sb)
rc : R
sc : ↥S
hc : r₃ * (ra * ↑sb) * ↑sc = ↑s₁ * rc
hc' : r₁ /ₒ s₁ * (r₃ * (ra * ↑sb) /ₒ (s₂ * sa * sb)) = r₁ * rc /ₒ (s₂ * sa * sb * sc)
⊢ r₁ /ₒ s₁ * (↑s₁ * (rb * ↑sc + rc) /ₒ (s₂ * sa * (sb * sc))) = (r₁ * rb * ↑sc + r₁ * rc * 1) /ₒ (s₂ * sa * sb * sc)

Next tactic:
rw [OreLocalization.mul_cancel']
protected theorem left_distrib (x y z : R[S⁻¹]) : x * (y + z) = x * y + x * z := by
  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, q⟩
  rw [q]
  clear q
  rw [OreLocalization.expand' r₂ s₂ sa]
  rcases oreDivMulChar' r₁ (r₂ * sa) s₁ (s₂ * sa) with ⟨rb, sb, hb, q⟩
  rw [q]
  clear q
  have hs₃rasb : ↑s₃ * (ra * sb) ∈ S := by
    rw [← mul_assoc, ← ha]
    norm_cast
    apply SetLike.coe_mem
  rw [OreLocalization.expand _ _ _ hs₃rasb]
  have ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * sb) := by simp [ha, ← mul_assoc]
  rw [← Subtype.coe_eq_of_eq_mk ha']
  rcases oreDivMulChar' r₁ (r₃ * (ra * sb)) s₁ (s₂ * sa * sb) with ⟨rc, sc, hc, hc'⟩
  rw [hc']
  rw [oreDiv_add_char (s₂ * sa * sb) (s₂ * sa * sb * sc) 1 sc (by simp)]
  rw [OreLocalization.expand' (r₂ * ↑sa + r₃ * ra) (s₂ * sa) (sb * sc)]
  conv_lhs =>
    congr
    · skip
    congr
    rw [add_mul, S.coe_mul, ← mul_assoc, hb, ← mul_assoc, mul_assoc r₃, hc, mul_assoc, ← mul_add]
  rw [OreLocalization.mul_cancel']
  

Proof state:
case c.c.c.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 : r₂ * ↑sa * ↑sb = ↑s₁ * rb
hs₃rasb : ↑s₃ * (ra * ↑sb) ∈ S
ha' : ↑(s₂ * sa * sb) = ↑s₃ * (ra * ↑sb)
rc : R
sc : ↥S
hc : r₃ * (ra * ↑sb) * ↑sc = ↑s₁ * rc
hc' : r₁ /ₒ s₁ * (r₃ * (ra * ↑sb) /ₒ (s₂ * sa * sb)) = r₁ * rc /ₒ (s₂ * sa * sb * sc)
⊢ r₁ * (rb * ↑sc + rc) /ₒ (s₂ * sa * (sb * sc)) = (r₁ * rb * ↑sc + r₁ * rc * 1) /ₒ (s₂ * sa * sb * sc)

Next tactic:
simp only [mul_one, Submonoid.coe_mul, mul_add, ← mul_assoc]
theorem right_distrib (x y z : R[S⁻¹]) : (x + y) * z = x * z + y * z := by
  

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

Next tactic:
induction' x using OreLocalization.ind with r₁ s₁
theorem right_distrib (x y z : R[S⁻¹]) : (x + y) * z = x * z + y * z := by
  induction' x using OreLocalization.ind with r₁ s₁
  

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

Next tactic:
induction' y using OreLocalization.ind with r₂ s₂
theorem right_distrib (x y z : R[S⁻¹]) : (x + y) * z = x * z + y * z := by
  induction' x using OreLocalization.ind with r₁ s₁
  induction' y using OreLocalization.ind with r₂ s₂
  

Proof state:
case c.c
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
z : OreLocalization R S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
⊢ (r₁ /ₒ s₁ + r₂ /ₒ s₂) * z = r₁ /ₒ s₁ * z + r₂ /ₒ s₂ * z

Next tactic:
induction' z using OreLocalization.ind with r₃ s₃
theorem right_distrib (x y z : R[S⁻¹]) : (x + y) * z = x * z + y * z := by
  induction' x using OreLocalization.ind with r₁ s₁
  induction' y using OreLocalization.ind with r₂ s₂
  induction' z using OreLocalization.ind with r₃ s₃
  

Proof state:
case c.c.c
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
⊢ (r₁ /ₒ s₁ + r₂ /ₒ s₂) * (r₃ /ₒ s₃) = r₁ /ₒ s₁ * (r₃ /ₒ s₃) + r₂ /ₒ s₂ * (r₃ /ₒ s₃)

Next tactic:
rcases oreDivAddChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩
theorem right_distrib (x y z : R[S⁻¹]) : (x + y) * z = x * z + y * z := by
  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'⟩; 

Proof state:
case c.c.c.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
ha' : r₁ /ₒ s₁ + r₂ /ₒ s₂ = (r₁ * ↑sa + r₂ * ra) /ₒ (s₁ * sa)
⊢ (r₁ /ₒ s₁ + r₂ /ₒ s₂) * (r₃ /ₒ s₃) = r₁ /ₒ s₁ * (r₃ /ₒ s₃) + r₂ /ₒ s₂ * (r₃ /ₒ s₃)

Next tactic:
rw [ha']
theorem right_distrib (x y z : R[S⁻¹]) : (x + y) * z = x * z + y * z := by
  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']; 

Proof state:
case c.c.c.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
ha' : r₁ /ₒ s₁ + r₂ /ₒ s₂ = (r₁ * ↑sa + r₂ * ra) /ₒ (s₁ * sa)
⊢ (r₁ * ↑sa + r₂ * ra) /ₒ (s₁ * sa) * (r₃ /ₒ s₃) = r₁ /ₒ s₁ * (r₃ /ₒ s₃) + r₂ /ₒ s₂ * (r₃ /ₒ s₃)

Next tactic:
clear ha'
theorem right_distrib (x y z : R[S⁻¹]) : (x + y) * z = x * z + y * z := by
  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'; 

Proof state:
case c.c.c.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
⊢ (r₁ * ↑sa + r₂ * ra) /ₒ (s₁ * sa) * (r₃ /ₒ s₃) = r₁ /ₒ s₁ * (r₃ /ₒ s₃) + r₂ /ₒ s₂ * (r₃ /ₒ s₃)

Next tactic:
norm_cast at ha
theorem right_distrib (x y z : R[S⁻¹]) : (x + y) * z = x * z + y * z := by
  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'; norm_cast at ha
  

Proof state:
case c.c.c.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
⊢ (r₁ * ↑sa + r₂ * ra) /ₒ (s₁ * sa) * (r₃ /ₒ s₃) = r₁ /ₒ s₁ * (r₃ /ₒ s₃) + r₂ /ₒ s₂ * (r₃ /ₒ s₃)

Next tactic:
rw [OreLocalization.expand' r₁ s₁ sa]
theorem right_distrib (x y z : R[S⁻¹]) : (x + y) * z = x * z + y * z := by
  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'; norm_cast at ha
  rw [OreLocalization.expand' r₁ s₁ sa]
  

Proof state:
case c.c.c.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
⊢ (r₁ * ↑sa + r₂ * ra) /ₒ (s₁ * sa) * (r₃ /ₒ s₃) = r₁ * ↑sa /ₒ (s₁ * sa) * (r₃ /ₒ s₃) + r₂ /ₒ s₂ * (r₃ /ₒ s₃)

Next tactic:
rw [OreLocalization.expand r₂ s₂ ra (by rw [← ha]; apply SetLike.coe_mem)]
theorem right_distrib (x y z : R[S⁻¹]) : (x + y) * z = x * z + y * z := by
  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'; norm_cast at ha
  rw [OreLocalization.expand' r₁ s₁ sa]
  rw [OreLocalization.expand r₂ s₂ ra (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
ra : R
sa : ↥S
ha : ↑(s₁ * sa) = ↑s₂ * ra
⊢ ↑s₂ * ra ∈ S

Next tactic:
rw [← ha]
theorem right_distrib (x y z : R[S⁻¹]) : (x + y) * z = x * z + y * z := by
  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'; norm_cast at ha
  rw [OreLocalization.expand' r₁ s₁ sa]
  rw [OreLocalization.expand r₂ s₂ ra (by rw [← ha]; 

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
ra : R
sa : ↥S
ha : ↑(s₁ * sa) = ↑s₂ * ra
⊢ ↑(s₁ * sa) ∈ S

Next tactic:
apply SetLike.coe_mem
theorem right_distrib (x y z : R[S⁻¹]) : (x + y) * z = x * z + y * z := by
  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'; norm_cast at ha
  rw [OreLocalization.expand' r₁ s₁ sa]
  rw [OreLocalization.expand r₂ s₂ ra (by rw [← ha]; apply SetLike.coe_mem)]
  

Proof state:
case c.c.c.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
⊢ (r₁ * ↑sa + r₂ * ra) /ₒ (s₁ * sa) * (r₃ /ₒ s₃) =
    r₁ * ↑sa /ₒ (s₁ * sa) * (r₃ /ₒ s₃) + r₂ * ra /ₒ { val := ↑s₂ * ra, property := (_ : ↑s₂ * ra ∈ S) } * (r₃ /ₒ s₃)

Next tactic:
rw [← Subtype.coe_eq_of_eq_mk ha]
theorem right_distrib (x y z : R[S⁻¹]) : (x + y) * z = x * z + y * z := by
  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'; norm_cast at ha
  rw [OreLocalization.expand' r₁ s₁ sa]
  rw [OreLocalization.expand r₂ s₂ ra (by rw [← ha]; apply SetLike.coe_mem)]
  rw [← Subtype.coe_eq_of_eq_mk ha]
  

Proof state:
case c.c.c.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
⊢ (r₁ * ↑sa + r₂ * ra) /ₒ (s₁ * sa) * (r₃ /ₒ s₃) =
    r₁ * ↑sa /ₒ (s₁ * sa) * (r₃ /ₒ s₃) + r₂ * ra /ₒ (s₁ * sa) * (r₃ /ₒ s₃)

Next tactic:
repeat rw [oreDiv_mul_oreDiv]
theorem right_distrib (x y z : R[S⁻¹]) : (x + y) * z = x * z + y * z := by
  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'; norm_cast at ha
  rw [OreLocalization.expand' r₁ s₁ sa]
  rw [OreLocalization.expand r₂ s₂ ra (by rw [← ha]; apply SetLike.coe_mem)]
  rw [← Subtype.coe_eq_of_eq_mk ha]
  repeat 

Proof state:
case c.c.c.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
⊢ (r₁ * ↑sa + r₂ * ra) /ₒ (s₁ * sa) * (r₃ /ₒ s₃) =
    r₁ * ↑sa /ₒ (s₁ * sa) * (r₃ /ₒ s₃) + r₂ * ra /ₒ (s₁ * sa) * (r₃ /ₒ s₃)

Next tactic:
rw [oreDiv_mul_oreDiv]