Theorem: OreLocalization.add''_char
File: Mathlib/RingTheory/OreLocalization/Basic.lean

tactic: simp only [add'']
state_before: R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
⊢ OreLocalization.add'' r₁ s₁ r₂ s₂ = (r₁ * ↑sb + r₂ * rb) /ₒ (s₁ * sb)

tactic: have ha := ore_eq (s₁ : R) s₂
state_before: R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
⊢ (r₁ * ↑(oreDenom (↑s₁) s₂) + r₂ * oreNum (↑s₁) s₂) /ₒ (s₁ * oreDenom (↑s₁) s₂) = (r₁ * ↑sb + r₂ * rb) /ₒ (s₁ * sb)

tactic: set! ra := oreNum (s₁ : R) s₂ with h
state_before: R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
⊢ (r₁ * ↑(oreDenom (↑s₁) s₂) + r₂ * oreNum (↑s₁) s₂) /ₒ (s₁ * oreDenom (↑s₁) s₂) = (r₁ * ↑sb + r₂ * rb) /ₒ (s₁ * sb)

tactic: rw [← h] at *
state_before: R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
h : ra = oreNum (↑s₁) s₂
⊢ (r₁ * ↑(oreDenom (↑s₁) s₂) + r₂ * oreNum (↑s₁) s₂) /ₒ (s₁ * oreDenom (↑s₁) s₂) = (r₁ * ↑sb + r₂ * rb) /ₒ (s₁ * sb)

tactic: clear h
state_before: R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
h : ra = ra
⊢ (r₁ * ↑(oreDenom (↑s₁) s₂) + r₂ * ra) /ₒ (s₁ * oreDenom (↑s₁) s₂) = (r₁ * ↑sb + r₂ * rb) /ₒ (s₁ * sb)

tactic: set! sa := oreDenom (s₁ : R) s₂ with h
state_before: R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
⊢ (r₁ * ↑(oreDenom (↑s₁) s₂) + r₂ * ra) /ₒ (s₁ * oreDenom (↑s₁) s₂) = (r₁ * ↑sb + r₂ * rb) /ₒ (s₁ * sb)

tactic: rw [← h] at *
state_before: R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : { x // x ∈ S } := oreDenom (↑s₁) s₂
h : sa = oreDenom (↑s₁) s₂
⊢ (r₁ * ↑(oreDenom (↑s₁) s₂) + r₂ * ra) /ₒ (s₁ * oreDenom (↑s₁) s₂) = (r₁ * ↑sb + r₂ * rb) /ₒ (s₁ * sb)

tactic: clear h
state_before: R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : { x // x ∈ S } := oreDenom (↑s₁) s₂
h : sa = sa
⊢ (r₁ * ↑sa + r₂ * ra) /ₒ (s₁ * sa) = (r₁ * ↑sb + r₂ * rb) /ₒ (s₁ * sb)

tactic: rcases oreCondition (sa : R) sb with ⟨rc, sc, hc⟩
state_before: R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : { x // x ∈ S } := oreDenom (↑s₁) s₂
⊢ (r₁ * ↑sa + r₂ * ra) /ₒ (s₁ * sa) = (r₁ * ↑sb + r₂ * rb) /ₒ (s₁ * sb)

tactic: have : (s₂ : R) * (rb * rc) = s₂ * (ra * sc) := by
  rw [← mul_assoc, ← hb, mul_assoc, ← hc, ← mul_assoc, ← mul_assoc, ha]
state_before: case mk.mk
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : { x // x ∈ S } := oreDenom (↑s₁) s₂
rc : R
sc : { x // x ∈ S }
hc : ↑sa * ↑sc = ↑sb * rc
⊢ (r₁ * ↑sa + r₂ * ra) /ₒ (s₁ * sa) = (r₁ * ↑sb + r₂ * rb) /ₒ (s₁ * sb)

tactic: rcases ore_left_cancel _ _ s₂ this with ⟨sd, hd⟩
state_before: case mk.mk
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : { x // x ∈ S } := oreDenom (↑s₁) s₂
rc : R
sc : { x // x ∈ S }
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
⊢ (r₁ * ↑sa + r₂ * ra) /ₒ (s₁ * sa) = (r₁ * ↑sb + r₂ * rb) /ₒ (s₁ * sb)

tactic: symm
state_before: case mk.mk.intro
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : { x // x ∈ S } := oreDenom (↑s₁) s₂
rc : R
sc : { x // x ∈ S }
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : { x // x ∈ S }
hd : rb * rc * ↑sd = ra * ↑sc * ↑sd
⊢ (r₁ * ↑sa + r₂ * ra) /ₒ (s₁ * sa) = (r₁ * ↑sb + r₂ * rb) /ₒ (s₁ * sb)

tactic: rw [oreDiv_eq_iff]
state_before: case mk.mk.intro
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : { x // x ∈ S } := oreDenom (↑s₁) s₂
rc : R
sc : { x // x ∈ S }
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : { x // x ∈ S }
hd : rb * rc * ↑sd = ra * ↑sc * ↑sd
⊢ (r₁ * ↑sb + r₂ * rb) /ₒ (s₁ * sb) = (r₁ * ↑sa + r₂ * ra) /ₒ (s₁ * sa)

tactic: use sc * sd
state_before: case mk.mk.intro
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : { x // x ∈ S } := oreDenom (↑s₁) s₂
rc : R
sc : { x // x ∈ S }
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : { x // x ∈ 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

tactic: use rc * sd
state_before: case mk.mk.intro
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : { x // x ∈ S } := oreDenom (↑s₁) s₂
rc : R
sc : { x // x ∈ S }
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : { x // x ∈ 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

tactic: constructor <;> simp only [Submonoid.coe_mul]
state_before: case mk.mk.intro
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : { x // x ∈ S } := oreDenom (↑s₁) s₂
rc : R
sc : { x // x ∈ S }
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : { x // x ∈ 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)

tactic: rw [← mul_assoc, ← hb, mul_assoc, ← hc, ← mul_assoc, ← mul_assoc, ha]
state_before: R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : { x // x ∈ S } := oreDenom (↑s₁) s₂
rc : R
sc : { x // x ∈ S }
hc : ↑sa * ↑sc = ↑sb * rc
⊢ ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)

tactic: noncomm_ring
state_before: case mk.mk.intro.left
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : { x // x ∈ S } := oreDenom (↑s₁) s₂
rc : R
sc : { x // x ∈ S }
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : { x // x ∈ S }
hd : rb * rc * ↑sd = ra * ↑sc * ↑sd
⊢ (r₁ * ↑(oreDenom (↑s₁) s₂) + r₂ * oreNum (↑s₁) s₂) * (↑sc * ↑sd) = (r₁ * ↑sb + r₂ * rb) * (rc * ↑sd)

tactic: rw [← mul_assoc (a := rb), hd, ← mul_assoc (a := (sa : R)), hc]
state_before: case mk.mk.intro.left
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : { x // x ∈ S } := oreDenom (↑s₁) s₂
rc : R
sc : { x // x ∈ S }
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : { x // x ∈ 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))

tactic: noncomm_ring
state_before: case mk.mk.intro.left
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : { x // x ∈ S } := oreDenom (↑s₁) s₂
rc : R
sc : { x // x ∈ S }
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : { x // x ∈ 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)

tactic: rw [mul_assoc (a := (s₁ : R)), ← mul_assoc (a := (sa : R)), hc]
state_before: case mk.mk.intro.right
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : { x // x ∈ S } := oreDenom (↑s₁) s₂
rc : R
sc : { x // x ∈ S }
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : { x // x ∈ S }
hd : rb * rc * ↑sd = ra * ↑sc * ↑sd
⊢ ↑s₁ * ↑(oreDenom (↑s₁) s₂) * (↑sc * ↑sd) = ↑s₁ * ↑sb * (rc * ↑sd)

tactic: noncomm_ring
state_before: case mk.mk.intro.right
R : Type u_1
inst✝¹ : Semiring R
S : Submonoid R
inst✝ : OreSet S
r₁ : R
s₁ : { x // x ∈ S }
r₂ : R
s₂ : { x // x ∈ S }
rb : R
sb : { x // x ∈ S }
hb : ↑s₁ * ↑sb = ↑s₂ * rb
ha : ↑s₁ * ↑(oreDenom (↑s₁) s₂) = ↑s₂ * oreNum (↑s₁) s₂
ra : R := oreNum (↑s₁) s₂
sa : { x // x ∈ S } := oreDenom (↑s₁) s₂
rc : R
sc : { x // x ∈ S }
hc : ↑sa * ↑sc = ↑sb * rc
this : ↑s₂ * (rb * rc) = ↑s₂ * (ra * ↑sc)
sd : { x // x ∈ S }
hd : rb * rc * ↑sd = ra * ↑sc * ↑sd
⊢ ↑s₁ * (↑sb * rc * ↑sd) = ↑s₁ * ↑sb * (rc * ↑sd)