l3lab/ntp-mathlib huggingface dataset:
/-- The multiplication on the Ore localization of monoids. -/
protected def mul : R[S⁻¹] → R[S⁻¹] → R[S⁻¹] :=
  lift₂Expand mul' fun r₂ p s₂ hp r₁ r s₁ hr => by
    have h₁ := ore_eq r₁ s₂
    set r₁' := oreNum r₁ s₂
    set s₂' := oreDenom r₁ s₂
    rcases oreCondition (↑s₂ * r₁') ⟨s₂ * p, hp⟩ with ⟨p', s_star, h₂⟩
    dsimp at h₂
    rcases oreCondition r (s₂' * s_star) with ⟨p_flat, s_flat, h₃⟩
    simp only [S.coe_mul] at h₃
    have : r₁ * r * s_flat = s₂ * p * (p' * p_flat) := by
      rw [← mul_assoc, ← h₂, ← h₁, mul_assoc, h₃]
      simp only [mul_assoc]
    rw [mul'_char (r₂ * p) (r₁ * r) ⟨↑s₂ * p, hp⟩ ⟨↑s₁ * r, hr⟩ _ _ this]
    clear this
    have hsssp : ↑s₁ * ↑s₂' * ↑s_star * p_flat ∈ S := by
      rw [mul_assoc, mul_assoc, ← mul_assoc (s₂' : R), ← h₃, ← mul_assoc]
      exact S.mul_mem hr (SetLike.coe_mem s_flat)
    have : (⟨↑s₁ * r, hr⟩ : S) * s_flat = ⟨s₁ * s₂' * s_star * p_flat, hsssp⟩ := by
      ext
      simp only [Submonoid.coe_mul]
      rw [mul_assoc, h₃, ← mul_assoc, ← mul_assoc]
    rw [this]
    

Proof state:
case mk.mk.mk.mk
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r₂ p : R
s₂ : ↥S
hp : ↑s₂ * p ∈ S
r₁ r : R
s₁ : ↥S
hr : ↑s₁ * r ∈ S
r₁' : R := oreNum r₁ s₂
s₂' : ↥S := oreDenom r₁ s₂
h₁ : r₁ * ↑s₂' = ↑s₂ * r₁'
p' : R
s_star : ↥S
h₂ : ↑s₂ * oreNum r₁ s₂ * ↑s_star = ↑s₂ * p * p'
p_flat : R
s_flat : ↥S
h₃ : r * ↑s_flat = ↑(oreDenom r₁ s₂) * ↑s_star * p_flat
hsssp : ↑s₁ * ↑s₂' * ↑s_star * p_flat ∈ S
this : { val := ↑s₁ * r, property := hr } * s_flat = { val := ↑s₁ * ↑s₂' * ↑s_star * p_flat, property := hsssp }
⊢ OreLocalization.mul' r₂ s₂ r₁ s₁ =
    r₂ * p * (p' * p_flat) /ₒ { val := ↑s₁ * ↑s₂' * ↑s_star * p_flat, property := hsssp }

Next tactic:
clear this
/-- The multiplication on the Ore localization of monoids. -/
protected def mul : R[S⁻¹] → R[S⁻¹] → R[S⁻¹] :=
  lift₂Expand mul' fun r₂ p s₂ hp r₁ r s₁ hr => by
    have h₁ := ore_eq r₁ s₂
    set r₁' := oreNum r₁ s₂
    set s₂' := oreDenom r₁ s₂
    rcases oreCondition (↑s₂ * r₁') ⟨s₂ * p, hp⟩ with ⟨p', s_star, h₂⟩
    dsimp at h₂
    rcases oreCondition r (s₂' * s_star) with ⟨p_flat, s_flat, h₃⟩
    simp only [S.coe_mul] at h₃
    have : r₁ * r * s_flat = s₂ * p * (p' * p_flat) := by
      rw [← mul_assoc, ← h₂, ← h₁, mul_assoc, h₃]
      simp only [mul_assoc]
    rw [mul'_char (r₂ * p) (r₁ * r) ⟨↑s₂ * p, hp⟩ ⟨↑s₁ * r, hr⟩ _ _ this]
    clear this
    have hsssp : ↑s₁ * ↑s₂' * ↑s_star * p_flat ∈ S := by
      rw [mul_assoc, mul_assoc, ← mul_assoc (s₂' : R), ← h₃, ← mul_assoc]
      exact S.mul_mem hr (SetLike.coe_mem s_flat)
    have : (⟨↑s₁ * r, hr⟩ : S) * s_flat = ⟨s₁ * s₂' * s_star * p_flat, hsssp⟩ := by
      ext
      simp only [Submonoid.coe_mul]
      rw [mul_assoc, h₃, ← mul_assoc, ← mul_assoc]
    rw [this]
    clear this
    

Proof state:
case mk.mk.mk.mk
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r₂ p : R
s₂ : ↥S
hp : ↑s₂ * p ∈ S
r₁ r : R
s₁ : ↥S
hr : ↑s₁ * r ∈ S
r₁' : R := oreNum r₁ s₂
s₂' : ↥S := oreDenom r₁ s₂
h₁ : r₁ * ↑s₂' = ↑s₂ * r₁'
p' : R
s_star : ↥S
h₂ : ↑s₂ * oreNum r₁ s₂ * ↑s_star = ↑s₂ * p * p'
p_flat : R
s_flat : ↥S
h₃ : r * ↑s_flat = ↑(oreDenom r₁ s₂) * ↑s_star * p_flat
hsssp : ↑s₁ * ↑s₂' * ↑s_star * p_flat ∈ S
⊢ OreLocalization.mul' r₂ s₂ r₁ s₁ =
    r₂ * p * (p' * p_flat) /ₒ { val := ↑s₁ * ↑s₂' * ↑s_star * p_flat, property := hsssp }

Next tactic:
rcases ore_left_cancel (p * p') (r₁' * (s_star : R)) s₂ (by simp [← mul_assoc, h₂])
      with ⟨s₂'', h₂''⟩
/-- The multiplication on the Ore localization of monoids. -/
protected def mul : R[S⁻¹] → R[S⁻¹] → R[S⁻¹] :=
  lift₂Expand mul' fun r₂ p s₂ hp r₁ r s₁ hr => by
    have h₁ := ore_eq r₁ s₂
    set r₁' := oreNum r₁ s₂
    set s₂' := oreDenom r₁ s₂
    rcases oreCondition (↑s₂ * r₁') ⟨s₂ * p, hp⟩ with ⟨p', s_star, h₂⟩
    dsimp at h₂
    rcases oreCondition r (s₂' * s_star) with ⟨p_flat, s_flat, h₃⟩
    simp only [S.coe_mul] at h₃
    have : r₁ * r * s_flat = s₂ * p * (p' * p_flat) := by
      rw [← mul_assoc, ← h₂, ← h₁, mul_assoc, h₃]
      simp only [mul_assoc]
    rw [mul'_char (r₂ * p) (r₁ * r) ⟨↑s₂ * p, hp⟩ ⟨↑s₁ * r, hr⟩ _ _ this]
    clear this
    have hsssp : ↑s₁ * ↑s₂' * ↑s_star * p_flat ∈ S := by
      rw [mul_assoc, mul_assoc, ← mul_assoc (s₂' : R), ← h₃, ← mul_assoc]
      exact S.mul_mem hr (SetLike.coe_mem s_flat)
    have : (⟨↑s₁ * r, hr⟩ : S) * s_flat = ⟨s₁ * s₂' * s_star * p_flat, hsssp⟩ := by
      ext
      simp only [Submonoid.coe_mul]
      rw [mul_assoc, h₃, ← mul_assoc, ← mul_assoc]
    rw [this]
    clear this
    rcases ore_left_cancel (p * p') (r₁' * (s_star : R)) s₂ (by 

Proof state:
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r₂ p : R
s₂ : ↥S
hp : ↑s₂ * p ∈ S
r₁ r : R
s₁ : ↥S
hr : ↑s₁ * r ∈ S
r₁' : R := oreNum r₁ s₂
s₂' : ↥S := oreDenom r₁ s₂
h₁ : r₁ * ↑s₂' = ↑s₂ * r₁'
p' : R
s_star : ↥S
h₂ : ↑s₂ * oreNum r₁ s₂ * ↑s_star = ↑s₂ * p * p'
p_flat : R
s_flat : ↥S
h₃ : r * ↑s_flat = ↑(oreDenom r₁ s₂) * ↑s_star * p_flat
hsssp : ↑s₁ * ↑s₂' * ↑s_star * p_flat ∈ S
⊢ ↑s₂ * (p * p') = ↑s₂ * (r₁' * ↑s_star)

Next tactic:
simp [← mul_assoc, h₂]
/-- The multiplication on the Ore localization of monoids. -/
protected def mul : R[S⁻¹] → R[S⁻¹] → R[S⁻¹] :=
  lift₂Expand mul' fun r₂ p s₂ hp r₁ r s₁ hr => by
    have h₁ := ore_eq r₁ s₂
    set r₁' := oreNum r₁ s₂
    set s₂' := oreDenom r₁ s₂
    rcases oreCondition (↑s₂ * r₁') ⟨s₂ * p, hp⟩ with ⟨p', s_star, h₂⟩
    dsimp at h₂
    rcases oreCondition r (s₂' * s_star) with ⟨p_flat, s_flat, h₃⟩
    simp only [S.coe_mul] at h₃
    have : r₁ * r * s_flat = s₂ * p * (p' * p_flat) := by
      rw [← mul_assoc, ← h₂, ← h₁, mul_assoc, h₃]
      simp only [mul_assoc]
    rw [mul'_char (r₂ * p) (r₁ * r) ⟨↑s₂ * p, hp⟩ ⟨↑s₁ * r, hr⟩ _ _ this]
    clear this
    have hsssp : ↑s₁ * ↑s₂' * ↑s_star * p_flat ∈ S := by
      rw [mul_assoc, mul_assoc, ← mul_assoc (s₂' : R), ← h₃, ← mul_assoc]
      exact S.mul_mem hr (SetLike.coe_mem s_flat)
    have : (⟨↑s₁ * r, hr⟩ : S) * s_flat = ⟨s₁ * s₂' * s_star * p_flat, hsssp⟩ := by
      ext
      simp only [Submonoid.coe_mul]
      rw [mul_assoc, h₃, ← mul_assoc, ← mul_assoc]
    rw [this]
    clear this
    rcases ore_left_cancel (p * p') (r₁' * (s_star : R)) s₂ (by simp [← mul_assoc, h₂])
      with ⟨s₂'', h₂''⟩
    

Proof state:
case mk.mk.mk.mk.intro
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r₂ p : R
s₂ : ↥S
hp : ↑s₂ * p ∈ S
r₁ r : R
s₁ : ↥S
hr : ↑s₁ * r ∈ S
r₁' : R := oreNum r₁ s₂
s₂' : ↥S := oreDenom r₁ s₂
h₁ : r₁ * ↑s₂' = ↑s₂ * r₁'
p' : R
s_star : ↥S
h₂ : ↑s₂ * oreNum r₁ s₂ * ↑s_star = ↑s₂ * p * p'
p_flat : R
s_flat : ↥S
h₃ : r * ↑s_flat = ↑(oreDenom r₁ s₂) * ↑s_star * p_flat
hsssp : ↑s₁ * ↑s₂' * ↑s_star * p_flat ∈ S
s₂'' : ↥S
h₂'' : p * p' * ↑s₂'' = r₁' * ↑s_star * ↑s₂''
⊢ OreLocalization.mul' r₂ s₂ r₁ s₁ =
    r₂ * p * (p' * p_flat) /ₒ { val := ↑s₁ * ↑s₂' * ↑s_star * p_flat, property := hsssp }

Next tactic:
rw [← mul_assoc, mul_assoc r₂, OreLocalization.eq_of_num_factor_eq h₂'']
/-- The multiplication on the Ore localization of monoids. -/
protected def mul : R[S⁻¹] → R[S⁻¹] → R[S⁻¹] :=
  lift₂Expand mul' fun r₂ p s₂ hp r₁ r s₁ hr => by
    have h₁ := ore_eq r₁ s₂
    set r₁' := oreNum r₁ s₂
    set s₂' := oreDenom r₁ s₂
    rcases oreCondition (↑s₂ * r₁') ⟨s₂ * p, hp⟩ with ⟨p', s_star, h₂⟩
    dsimp at h₂
    rcases oreCondition r (s₂' * s_star) with ⟨p_flat, s_flat, h₃⟩
    simp only [S.coe_mul] at h₃
    have : r₁ * r * s_flat = s₂ * p * (p' * p_flat) := by
      rw [← mul_assoc, ← h₂, ← h₁, mul_assoc, h₃]
      simp only [mul_assoc]
    rw [mul'_char (r₂ * p) (r₁ * r) ⟨↑s₂ * p, hp⟩ ⟨↑s₁ * r, hr⟩ _ _ this]
    clear this
    have hsssp : ↑s₁ * ↑s₂' * ↑s_star * p_flat ∈ S := by
      rw [mul_assoc, mul_assoc, ← mul_assoc (s₂' : R), ← h₃, ← mul_assoc]
      exact S.mul_mem hr (SetLike.coe_mem s_flat)
    have : (⟨↑s₁ * r, hr⟩ : S) * s_flat = ⟨s₁ * s₂' * s_star * p_flat, hsssp⟩ := by
      ext
      simp only [Submonoid.coe_mul]
      rw [mul_assoc, h₃, ← mul_assoc, ← mul_assoc]
    rw [this]
    clear this
    rcases ore_left_cancel (p * p') (r₁' * (s_star : R)) s₂ (by simp [← mul_assoc, h₂])
      with ⟨s₂'', h₂''⟩
    rw [← mul_assoc, mul_assoc r₂, OreLocalization.eq_of_num_factor_eq h₂'']
    

Proof state:
case mk.mk.mk.mk.intro
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r₂ p : R
s₂ : ↥S
hp : ↑s₂ * p ∈ S
r₁ r : R
s₁ : ↥S
hr : ↑s₁ * r ∈ S
r₁' : R := oreNum r₁ s₂
s₂' : ↥S := oreDenom r₁ s₂
h₁ : r₁ * ↑s₂' = ↑s₂ * r₁'
p' : R
s_star : ↥S
h₂ : ↑s₂ * oreNum r₁ s₂ * ↑s_star = ↑s₂ * p * p'
p_flat : R
s_flat : ↥S
h₃ : r * ↑s_flat = ↑(oreDenom r₁ s₂) * ↑s_star * p_flat
hsssp : ↑s₁ * ↑s₂' * ↑s_star * p_flat ∈ S
s₂'' : ↥S
h₂'' : p * p' * ↑s₂'' = r₁' * ↑s_star * ↑s₂''
⊢ OreLocalization.mul' r₂ s₂ r₁ s₁ =
    r₂ * (r₁' * ↑s_star) * p_flat /ₒ { val := ↑s₁ * ↑s₂' * ↑s_star * p_flat, property := hsssp }

Next tactic:
norm_cast at hsssp ⊢
/-- The multiplication on the Ore localization of monoids. -/
protected def mul : R[S⁻¹] → R[S⁻¹] → R[S⁻¹] :=
  lift₂Expand mul' fun r₂ p s₂ hp r₁ r s₁ hr => by
    have h₁ := ore_eq r₁ s₂
    set r₁' := oreNum r₁ s₂
    set s₂' := oreDenom r₁ s₂
    rcases oreCondition (↑s₂ * r₁') ⟨s₂ * p, hp⟩ with ⟨p', s_star, h₂⟩
    dsimp at h₂
    rcases oreCondition r (s₂' * s_star) with ⟨p_flat, s_flat, h₃⟩
    simp only [S.coe_mul] at h₃
    have : r₁ * r * s_flat = s₂ * p * (p' * p_flat) := by
      rw [← mul_assoc, ← h₂, ← h₁, mul_assoc, h₃]
      simp only [mul_assoc]
    rw [mul'_char (r₂ * p) (r₁ * r) ⟨↑s₂ * p, hp⟩ ⟨↑s₁ * r, hr⟩ _ _ this]
    clear this
    have hsssp : ↑s₁ * ↑s₂' * ↑s_star * p_flat ∈ S := by
      rw [mul_assoc, mul_assoc, ← mul_assoc (s₂' : R), ← h₃, ← mul_assoc]
      exact S.mul_mem hr (SetLike.coe_mem s_flat)
    have : (⟨↑s₁ * r, hr⟩ : S) * s_flat = ⟨s₁ * s₂' * s_star * p_flat, hsssp⟩ := by
      ext
      simp only [Submonoid.coe_mul]
      rw [mul_assoc, h₃, ← mul_assoc, ← mul_assoc]
    rw [this]
    clear this
    rcases ore_left_cancel (p * p') (r₁' * (s_star : R)) s₂ (by simp [← mul_assoc, h₂])
      with ⟨s₂'', h₂''⟩
    rw [← mul_assoc, mul_assoc r₂, OreLocalization.eq_of_num_factor_eq h₂'']
    norm_cast at hsssp ⊢
    

Proof state:
case mk.mk.mk.mk.intro
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r₂ p : R
s₂ : ↥S
hp : ↑s₂ * p ∈ S
r₁ r : R
s₁ : ↥S
hr : ↑s₁ * r ∈ S
r₁' : R := oreNum r₁ s₂
s₂' : ↥S := oreDenom r₁ s₂
h₁ : r₁ * ↑s₂' = ↑s₂ * r₁'
p' : R
s_star : ↥S
h₂ : ↑s₂ * oreNum r₁ s₂ * ↑s_star = ↑s₂ * p * p'
p_flat : R
s_flat : ↥S
h₃ : r * ↑s_flat = ↑(oreDenom r₁ s₂) * ↑s_star * p_flat
hsssp : ↑(s₁ * s₂' * s_star) * p_flat ∈ S
s₂'' : ↥S
h₂'' : p * p' * ↑s₂'' = r₁' * ↑s_star * ↑s₂''
⊢ OreLocalization.mul' r₂ s₂ r₁ s₁ =
    r₂ * (r₁' * ↑s_star) * p_flat /ₒ
      { val := ↑(s₁ * s₂' * s_star) * p_flat, property := (_ : (fun x => x ∈ S) (↑(s₁ * s₂' * s_star) * p_flat)) }

Next tactic:
rw [← OreLocalization.expand _ _ _ hsssp, ← mul_assoc]
/-- The multiplication on the Ore localization of monoids. -/
protected def mul : R[S⁻¹] → R[S⁻¹] → R[S⁻¹] :=
  lift₂Expand mul' fun r₂ p s₂ hp r₁ r s₁ hr => by
    have h₁ := ore_eq r₁ s₂
    set r₁' := oreNum r₁ s₂
    set s₂' := oreDenom r₁ s₂
    rcases oreCondition (↑s₂ * r₁') ⟨s₂ * p, hp⟩ with ⟨p', s_star, h₂⟩
    dsimp at h₂
    rcases oreCondition r (s₂' * s_star) with ⟨p_flat, s_flat, h₃⟩
    simp only [S.coe_mul] at h₃
    have : r₁ * r * s_flat = s₂ * p * (p' * p_flat) := by
      rw [← mul_assoc, ← h₂, ← h₁, mul_assoc, h₃]
      simp only [mul_assoc]
    rw [mul'_char (r₂ * p) (r₁ * r) ⟨↑s₂ * p, hp⟩ ⟨↑s₁ * r, hr⟩ _ _ this]
    clear this
    have hsssp : ↑s₁ * ↑s₂' * ↑s_star * p_flat ∈ S := by
      rw [mul_assoc, mul_assoc, ← mul_assoc (s₂' : R), ← h₃, ← mul_assoc]
      exact S.mul_mem hr (SetLike.coe_mem s_flat)
    have : (⟨↑s₁ * r, hr⟩ : S) * s_flat = ⟨s₁ * s₂' * s_star * p_flat, hsssp⟩ := by
      ext
      simp only [Submonoid.coe_mul]
      rw [mul_assoc, h₃, ← mul_assoc, ← mul_assoc]
    rw [this]
    clear this
    rcases ore_left_cancel (p * p') (r₁' * (s_star : R)) s₂ (by simp [← mul_assoc, h₂])
      with ⟨s₂'', h₂''⟩
    rw [← mul_assoc, mul_assoc r₂, OreLocalization.eq_of_num_factor_eq h₂'']
    norm_cast at hsssp ⊢
    rw [← OreLocalization.expand _ _ _ hsssp, ← mul_assoc]
    

Proof state:
case mk.mk.mk.mk.intro
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r₂ p : R
s₂ : ↥S
hp : ↑s₂ * p ∈ S
r₁ r : R
s₁ : ↥S
hr : ↑s₁ * r ∈ S
r₁' : R := oreNum r₁ s₂
s₂' : ↥S := oreDenom r₁ s₂
h₁ : r₁ * ↑s₂' = ↑s₂ * r₁'
p' : R
s_star : ↥S
h₂ : ↑s₂ * oreNum r₁ s₂ * ↑s_star = ↑s₂ * p * p'
p_flat : R
s_flat : ↥S
h₃ : r * ↑s_flat = ↑(oreDenom r₁ s₂) * ↑s_star * p_flat
hsssp : ↑(s₁ * s₂' * s_star) * p_flat ∈ S
s₂'' : ↥S
h₂'' : p * p' * ↑s₂'' = r₁' * ↑s_star * ↑s₂''
⊢ OreLocalization.mul' r₂ s₂ r₁ s₁ = r₂ * r₁' * ↑s_star /ₒ (s₁ * s₂' * s_star)

Next tactic:
apply OreLocalization.expand
@[simp]
protected theorem div_eq_one' {r : R} (hr : r ∈ S) : r /ₒ ⟨r, hr⟩ = 1 := by
  

Proof state:
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r : R
hr : r ∈ S
⊢ r /ₒ { val := r, property := hr } = 1

Next tactic:
rw [OreLocalization.one_def, oreDiv_eq_iff]
@[simp]
protected theorem div_eq_one' {r : R} (hr : r ∈ S) : r /ₒ ⟨r, hr⟩ = 1 := by
  rw [OreLocalization.one_def, oreDiv_eq_iff]
  

Proof state:
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r : R
hr : r ∈ S
⊢ ∃ u v, 1 * ↑u = r * v ∧ ↑1 * ↑u = ↑{ val := r, property := hr } * v

Next tactic:
exact ⟨⟨r, hr⟩, 1, by simp, by simp⟩
@[simp]
protected theorem div_eq_one' {r : R} (hr : r ∈ S) : r /ₒ ⟨r, hr⟩ = 1 := by
  rw [OreLocalization.one_def, oreDiv_eq_iff]
  exact ⟨⟨r, hr⟩, 1, by 

Proof state:
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r : R
hr : r ∈ S
⊢ 1 * ↑{ val := r, property := hr } = r * 1

Next tactic:
simp
@[simp]
protected theorem div_eq_one' {r : R} (hr : r ∈ S) : r /ₒ ⟨r, hr⟩ = 1 := by
  rw [OreLocalization.one_def, oreDiv_eq_iff]
  exact ⟨⟨r, hr⟩, 1, by simp, by 

Proof state:
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r : R
hr : r ∈ S
⊢ ↑1 * ↑{ val := r, property := hr } = ↑{ val := r, property := hr } * 1

Next tactic:
simp
protected theorem one_mul (x : R[S⁻¹]) : 1 * x = x := by
  

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

Next tactic:
induction' x using OreLocalization.ind with r s
protected theorem one_mul (x : R[S⁻¹]) : 1 * x = x := by
  induction' x using OreLocalization.ind with r s
  

Proof state:
case c
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r : R
s : ↥S
⊢ 1 * (r /ₒ s) = r /ₒ s

Next tactic:
simp [OreLocalization.one_def, oreDiv_mul_char (1 : R) r (1 : S) s r 1 (by simp)]
protected theorem one_mul (x : R[S⁻¹]) : 1 * x = x := by
  induction' x using OreLocalization.ind with r s
  simp [OreLocalization.one_def, oreDiv_mul_char (1 : R) r (1 : S) s r 1 (by 

Proof state:
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r : R
s : ↥S
⊢ r * ↑1 = ↑1 * r

Next tactic:
simp
protected theorem mul_one (x : R[S⁻¹]) : x * 1 = x := by
  

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

Next tactic:
induction' x using OreLocalization.ind with r s
protected theorem mul_one (x : R[S⁻¹]) : x * 1 = x := by
  induction' x using OreLocalization.ind with r s
  

Proof state:
case c
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r : R
s : ↥S
⊢ r /ₒ s * 1 = r /ₒ s

Next tactic:
simp [OreLocalization.one_def, oreDiv_mul_char r 1 s 1 1 s (by simp)]
protected theorem mul_one (x : R[S⁻¹]) : x * 1 = x := by
  induction' x using OreLocalization.ind with r s
  simp [OreLocalization.one_def, oreDiv_mul_char r 1 s 1 1 s (by 

Proof state:
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r : R
s : ↥S
⊢ 1 * ↑s = ↑s * 1

Next tactic:
simp
protected theorem mul_assoc (x y z : R[S⁻¹]) : x * y * z = x * (y * z) := by
  -- Porting note: `assoc_rw` was not ported yet
  

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

Next tactic:
induction' x using OreLocalization.ind with r₁ s₁
protected theorem mul_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₁
  

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

Next tactic:
induction' y using OreLocalization.ind with r₂ s₂
protected theorem mul_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₂
  

Proof state:
case c.c
R : Type u_1
inst✝¹ : Monoid 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₁ * (r₂ /ₒ s₂ * z)

Next tactic:
induction' z using OreLocalization.ind with r₃ s₃
protected theorem mul_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₃
  

Proof state:
case c.c.c
R : Type u_1
inst✝¹ : Monoid 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₃))

Next tactic:
rcases oreDivMulChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩
protected theorem mul_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 oreDivMulChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; 

Proof state:
case c.c.c.mk.mk.intro
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
r₃ : R
s₃ : ↥S
ra : R
sa : ↥S
ha : r₂ * ↑sa = ↑s₁ * ra
ha' : r₁ /ₒ s₁ * (r₂ /ₒ s₂) = r₁ * ra /ₒ (s₂ * sa)
⊢ r₁ /ₒ s₁ * (r₂ /ₒ s₂) * (r₃ /ₒ s₃) = r₁ /ₒ s₁ * (r₂ /ₒ s₂ * (r₃ /ₒ s₃))

Next tactic:
rw [ha']
protected theorem mul_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 oreDivMulChar' 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✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
r₃ : R
s₃ : ↥S
ra : R
sa : ↥S
ha : r₂ * ↑sa = ↑s₁ * ra
ha' : r₁ /ₒ s₁ * (r₂ /ₒ s₂) = r₁ * ra /ₒ (s₂ * sa)
⊢ r₁ * ra /ₒ (s₂ * sa) * (r₃ /ₒ s₃) = r₁ /ₒ s₁ * (r₂ /ₒ s₂ * (r₃ /ₒ s₃))

Next tactic:
clear ha'
protected theorem mul_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 oreDivMulChar' 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✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
r₃ : R
s₃ : ↥S
ra : R
sa : ↥S
ha : r₂ * ↑sa = ↑s₁ * ra
⊢ r₁ * ra /ₒ (s₂ * sa) * (r₃ /ₒ s₃) = r₁ /ₒ s₁ * (r₂ /ₒ s₂ * (r₃ /ₒ s₃))

Next tactic:
rcases oreDivMulChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩
protected theorem mul_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 oreDivMulChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivMulChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; 

Proof state:
case c.c.c.mk.mk.intro.mk.mk.intro
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
r₃ : R
s₃ : ↥S
ra : R
sa : ↥S
ha : r₂ * ↑sa = ↑s₁ * ra
rb : R
sb : ↥S
hb : r₃ * ↑sb = ↑s₂ * rb
hb' : r₂ /ₒ s₂ * (r₃ /ₒ s₃) = r₂ * rb /ₒ (s₃ * sb)
⊢ r₁ * ra /ₒ (s₂ * sa) * (r₃ /ₒ s₃) = r₁ /ₒ s₁ * (r₂ /ₒ s₂ * (r₃ /ₒ s₃))

Next tactic:
rw [hb']
protected theorem mul_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 oreDivMulChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivMulChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; 

Proof state:
case c.c.c.mk.mk.intro.mk.mk.intro
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
r₃ : R
s₃ : ↥S
ra : R
sa : ↥S
ha : r₂ * ↑sa = ↑s₁ * ra
rb : R
sb : ↥S
hb : r₃ * ↑sb = ↑s₂ * rb
hb' : r₂ /ₒ s₂ * (r₃ /ₒ s₃) = r₂ * rb /ₒ (s₃ * sb)
⊢ r₁ * ra /ₒ (s₂ * sa) * (r₃ /ₒ s₃) = r₁ /ₒ s₁ * (r₂ * rb /ₒ (s₃ * sb))

Next tactic:
clear hb'
protected theorem mul_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 oreDivMulChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivMulChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb'
  

Proof state:
case c.c.c.mk.mk.intro.mk.mk.intro
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
r₃ : R
s₃ : ↥S
ra : R
sa : ↥S
ha : r₂ * ↑sa = ↑s₁ * ra
rb : R
sb : ↥S
hb : r₃ * ↑sb = ↑s₂ * rb
⊢ r₁ * ra /ₒ (s₂ * sa) * (r₃ /ₒ s₃) = r₁ /ₒ s₁ * (r₂ * rb /ₒ (s₃ * sb))

Next tactic:
rcases oreCondition rb sa with ⟨rc, sc, hc⟩
protected theorem mul_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 oreDivMulChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivMulChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb'
  rcases oreCondition rb sa with ⟨rc, sc, hc⟩
  

Proof state:
case c.c.c.mk.mk.intro.mk.mk.intro.mk.mk
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
r₃ : R
s₃ : ↥S
ra : R
sa : ↥S
ha : r₂ * ↑sa = ↑s₁ * ra
rb : R
sb : ↥S
hb : r₃ * ↑sb = ↑s₂ * rb
rc : R
sc : ↥S
hc : rb * ↑sc = ↑sa * rc
⊢ r₁ * ra /ₒ (s₂ * sa) * (r₃ /ₒ s₃) = r₁ /ₒ s₁ * (r₂ * rb /ₒ (s₃ * sb))

Next tactic:
rw [oreDiv_mul_char (r₁ * ra) r₃ (s₂ * sa) s₃ rc (sb * sc)
      (by
        simp only [Submonoid.coe_mul]
        rw [← mul_assoc, hb, mul_assoc, hc, ← mul_assoc])]
protected theorem mul_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 oreDivMulChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha'
  rcases oreDivMulChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb'
  rcases oreCondition rb sa with ⟨rc, sc, hc⟩
  rw [oreDiv_mul_char (r₁ * ra) r₃ (s₂ * sa) s₃ rc (sb * sc)
      (by
        

Proof state:
R : Type u_1
inst✝¹ : Monoid R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : ↥S
r₂ : R
s₂ : ↥S
r₃ : R
s₃ : ↥S
ra : R
sa : ↥S
ha : r₂ * ↑sa = ↑s₁ * ra
rb : R
sb : ↥S
hb : r₃ * ↑sb = ↑s₂ * rb
rc : R
sc : ↥S
hc : rb * ↑sc = ↑sa * rc
⊢ r₃ * ↑(sb * sc) = ↑(s₂ * sa) * rc

Next tactic:
simp only [Submonoid.coe_mul]