-- Mathlib/GroupTheory/MonoidLocalization/MonoidWithZero.lean
theorem leftCancelMulZero_of_le_isLeftRegular
    (f : LocalizationWithZeroMap S N) [IsLeftCancelMulZero M]
    (h : ∀ ⦃x⦄, x ∈ S → IsLeftRegular x) : IsLeftCancelMulZero N

Proof state:
M : Type u_1
inst✝² : CommMonoidWithZero M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoidWithZero N
f : S.LocalizationWithZeroMap N
inst✝ : IsLeftCancelMulZero M
h : ∀ ⦃x : M⦄, x ∈ S → IsLeftRegular x
fl : S.LocalizationMap N := f.toLocalizationMap
g : M →* N := f.toMap
a z w : N
ha : a ≠ 0
hazw : a * z = a * w
b : M × ↥S
hb : a * fl.toMap ↑b.2 = fl.toMap b.1
x : M × ↥S
hx : z * fl.toMap ↑x.2 = fl.toMap x.1
y : M × ↥S
hy : w * fl.toMap ↑y.2 = fl.toMap y.1
b1ne0 : b.1 ≠ 0
⊢ g b.1 * g (↑y.2 * x.1) = g (b.1 * (↑y.2 * x.1))

Tactic:
rw [← map_mul g]

Result:
no goals

Proof state:
case h
M : Type u_1
inst✝² : CommMonoidWithZero M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoidWithZero N
f : S.LocalizationWithZeroMap N
inst✝ : IsLeftCancelMulZero M
h : ∀ ⦃x : M⦄, x ∈ S → IsLeftRegular x
fl : S.LocalizationMap N := f.toLocalizationMap
g : M →* N := f.toMap
a z w : N
ha : a ≠ 0
hazw : a * z = a * w
b : M × ↥S
hb : a * fl.toMap ↑b.2 = fl.toMap b.1
x : M × ↥S
hx : z * fl.toMap ↑x.2 = fl.toMap x.1
y : M × ↥S
hy : w * fl.toMap ↑y.2 = fl.toMap y.1
⊢ ↑y.2 * x.1 = ↑x.2 * y.1

Tactic:
have b1ne0 : b.1 ≠ 0 := by
  intro hb1
  have m0 : (LocalizationMap.toMap fl) 0 = 0 := f.map_zero'
  have a0 : a * (LocalizationMap.toMap fl) b.2 = 0 ↔ a = 0 :=
    (f.toLocalizationMap.map_units' b.2).mul_left_eq_zero
  rw [hb1, m0, a0] at hb
  exact ha hb

Result:
case h
M : Type u_1
inst✝² : CommMonoidWithZero M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoidWithZero N
f : S.LocalizationWithZeroMap N
inst✝ : IsLeftCancelMulZero M
h : ∀ ⦃x : M⦄, x ∈ S → IsLeftRegular x
fl : S.LocalizationMap N := f.toLocalizationMap
g : M →* N := f.toMap
a z w : N
ha : a ≠ 0
hazw : a * z = a * w
b : M × ↥S
hb : a * fl.toMap ↑b.2 = fl.toMap b.1
x : M × ↥S
hx : z * fl.toMap ↑x.2 = fl.toMap x.1
y : M × ↥S
hy : w * fl.toMap ↑y.2 = fl.toMap y.1
b1ne0 : b.1 ≠ 0
⊢ ↑y.2 * x.1 = ↑x.2 * y.1

Proof state:
case h
M : Type u_1
inst✝² : CommMonoidWithZero M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoidWithZero N
f : S.LocalizationWithZeroMap N
inst✝ : IsLeftCancelMulZero M
h : ∀ ⦃x : M⦄, x ∈ S → IsLeftRegular x
fl : S.LocalizationMap N := f.toLocalizationMap
g : M →* N := f.toMap
a z w : N
ha : a ≠ 0
hazw : a * z = a * w
b : M × ↥S
hb : a * fl.toMap ↑b.2 = fl.toMap b.1
x : M × ↥S
hx : z * fl.toMap ↑x.2 = fl.toMap x.1
y : M × ↥S
hy : w * fl.toMap ↑y.2 = fl.toMap y.1
b1ne0 : b.1 ≠ 0
⊢ ↑y.2 * x.1 = ↑x.2 * y.1

Tactic:
have main : g (b.1 * (x.2 * y.1)) = g (b.1 * (y.2 * x.1)) :=
  calc
    g (b.1 * (x.2 * y.1)) = g b.1 * (g x.2 * g y.1) := by rw [map_mul g,map_mul g]
    _ = a * g b.2 * (g x.2 * (w * g y.2)) := by rw [hb, hy]
    _ = a * w * g b.2 * (g x.2 * g y.2) := by
      rw [← mul_assoc, ← mul_assoc _ w, mul_comm _ w, mul_assoc w, mul_assoc,
        ← mul_assoc w, ← mul_assoc w, mul_comm w]
    _ = a * z * g b.2 * (g x.2 * g y.2) := by rw [hazw]
    _ = a * g b.2 * (z * g x.2 * g y.2) := by
      rw [mul_assoc a, mul_comm z, ← mul_assoc a, mul_assoc, mul_assoc z]
    _ = g b.1 * g (y.2 * x.1) := by rw [hx, hb, mul_comm (g x.1), ← map_mul g]
    _ = g (b.1 * (y.2 * x.1)) := by rw [← map_mul g]

Result:
case h
M : Type u_1
inst✝² : CommMonoidWithZero M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoidWithZero N
f : S.LocalizationWithZeroMap N
inst✝ : IsLeftCancelMulZero M
h : ∀ ⦃x : M⦄, x ∈ S → IsLeftRegular x
fl : S.LocalizationMap N := f.toLocalizationMap
g : M →* N := f.toMap
a z w : N
ha : a ≠ 0
hazw : a * z = a * w
b : M × ↥S
hb : a * fl.toMap ↑b.2 = fl.toMap b.1
x : M × ↥S
hx : z * fl.toMap ↑x.2 = fl.toMap x.1
y : M × ↥S
hy : w * fl.toMap ↑y.2 = fl.toMap y.1
b1ne0 : b.1 ≠ 0
main : g (b.1 * (↑x.2 * y.1)) = g (b.1 * (↑y.2 * x.1))
⊢ ↑y.2 * x.1 = ↑x.2 * y.1

Proof state:
M : Type u_1
inst✝² : CommMonoidWithZero M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoidWithZero N
f : S.LocalizationWithZeroMap N
inst✝ : IsLeftCancelMulZero M
h : ∀ ⦃x : M⦄, x ∈ S → IsLeftRegular x
fl : S.LocalizationMap N := f.toLocalizationMap
g : M →* N := f.toMap
⊢ IsLeftCancelMulZero N

Tactic:
constructor

Result:
case mul_left_cancel_of_ne_zero
M : Type u_1
inst✝² : CommMonoidWithZero M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoidWithZero N
f : S.LocalizationWithZeroMap N
inst✝ : IsLeftCancelMulZero M
h : ∀ ⦃x : M⦄, x ∈ S → IsLeftRegular x
fl : S.LocalizationMap N := f.toLocalizationMap
g : M →* N := f.toMap
⊢ ∀ {a b c : N}, a ≠ 0 → a * b = a * c → b = c

Proof state:
case mul_left_cancel_of_ne_zero
M : Type u_1
inst✝² : CommMonoidWithZero M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoidWithZero N
f : S.LocalizationWithZeroMap N
inst✝ : IsLeftCancelMulZero M
h : ∀ ⦃x : M⦄, x ∈ S → IsLeftRegular x
fl : S.LocalizationMap N := f.toLocalizationMap
g : M →* N := f.toMap
a z w : N
ha : a ≠ 0
hazw : a * z = a * w
⊢ z = w

Tactic:
obtain ⟨b, hb⟩ := LocalizationMap.surj fl a

Result:
case mul_left_cancel_of_ne_zero.intro
M : Type u_1
inst✝² : CommMonoidWithZero M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoidWithZero N
f : S.LocalizationWithZeroMap N
inst✝ : IsLeftCancelMulZero M
h : ∀ ⦃x : M⦄, x ∈ S → IsLeftRegular x
fl : S.LocalizationMap N := f.toLocalizationMap
g : M →* N := f.toMap
a z w : N
ha : a ≠ 0
hazw : a * z = a * w
b : M × ↥S
hb : a * fl.toMap ↑b.2 = fl.toMap b.1
⊢ z = w

Proof state:
M : Type u_1
inst✝² : CommMonoidWithZero M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoidWithZero N
f : S.LocalizationWithZeroMap N
inst✝ : IsLeftCancelMulZero M
h : ∀ ⦃x : M⦄, x ∈ S → IsLeftRegular x
⊢ IsLeftCancelMulZero N

Tactic:
let fl := f.toLocalizationMap

Result:
M : Type u_1
inst✝² : CommMonoidWithZero M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoidWithZero N
f : S.LocalizationWithZeroMap N
inst✝ : IsLeftCancelMulZero M
h : ∀ ⦃x : M⦄, x ∈ S → IsLeftRegular x
fl : S.LocalizationMap N := f.toLocalizationMap
⊢ IsLeftCancelMulZero N

Proof state:
case mul_left_cancel_of_ne_zero
M : Type u_1
inst✝² : CommMonoidWithZero M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoidWithZero N
f : S.LocalizationWithZeroMap N
inst✝ : IsLeftCancelMulZero M
h : ∀ ⦃x : M⦄, x ∈ S → IsLeftRegular x
fl : S.LocalizationMap N := f.toLocalizationMap
g : M →* N := f.toMap
⊢ ∀ {a b c : N}, a ≠ 0 → a * b = a * c → b = c

Tactic:
intro a z w ha hazw

Result:
case mul_left_cancel_of_ne_zero
M : Type u_1
inst✝² : CommMonoidWithZero M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoidWithZero N
f : S.LocalizationWithZeroMap N
inst✝ : IsLeftCancelMulZero M
h : ∀ ⦃x : M⦄, x ∈ S → IsLeftRegular x
fl : S.LocalizationMap N := f.toLocalizationMap
g : M →* N := f.toMap
a z w : N
ha : a ≠ 0
hazw : a * z = a * w
⊢ z = w

Proof state:
M : Type u_1
inst✝² : CommMonoidWithZero M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoidWithZero N
f : S.LocalizationWithZeroMap N
inst✝ : IsLeftCancelMulZero M
h : ∀ ⦃x : M⦄, x ∈ S → IsLeftRegular x
fl : S.LocalizationMap N := f.toLocalizationMap
⊢ IsLeftCancelMulZero N

Tactic:
let g := f.toMap

Result:
M : Type u_1
inst✝² : CommMonoidWithZero M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoidWithZero N
f : S.LocalizationWithZeroMap N
inst✝ : IsLeftCancelMulZero M
h : ∀ ⦃x : M⦄, x ∈ S → IsLeftRegular x
fl : S.LocalizationMap N := f.toLocalizationMap
g : M →* N := f.toMap
⊢ IsLeftCancelMulZero N