-- Mathlib/Algebra/Group/Pi/Lemmas.lean
theorem Pi.mulSingle_mul_mulSingle_eq_mulSingle_mul_mulSingle {M : Type*} [CommMonoid M]
    {k l m n : I} {u v : M} (hu : u ≠ 1) (hv : v ≠ 1) :
    (mulSingle k u : I → M) * mulSingle l v = mulSingle m u * mulSingle n v ↔
      k = m ∧ l = n ∨ u = v ∧ k = n ∧ l = m ∨ u * v = 1 ∧ k = l ∧ m = n

Proof state:
case refine_1
I : Type u
inst✝¹ : DecidableEq I
M : Type u_3
inst✝ : CommMonoid M
k l m n : I
u v : M
hu : u ≠ 1
hv : v ≠ 1
h : mulSingle k u * mulSingle l v = mulSingle m u * mulSingle n v
hk : (mulSingle k u * mulSingle l v) k = (mulSingle m u * mulSingle n v) k
hl : (mulSingle k u * mulSingle l v) l = (mulSingle m u * mulSingle n v) l
hm : (mulSingle m u * mulSingle n v) m = (mulSingle k u * mulSingle l v) m
hn : (mulSingle m u * mulSingle n v) n = (mulSingle k u * mulSingle l v) n
⊢ k = m ∧ l = n ∨ u = v ∧ k = n ∧ l = m ∨ u * v = 1 ∧ k = l ∧ m = n

Tactic:
simp only [mul_apply, mulSingle_apply, if_pos rfl] at hk hl hm hn

Result:
case refine_1
I : Type u
inst✝¹ : DecidableEq I
M : Type u_3
inst✝ : CommMonoid M
k l m n : I
u v : M
hu : u ≠ 1
hv : v ≠ 1
h : mulSingle k u * mulSingle l v = mulSingle m u * mulSingle n v
hk : ((if True then u else 1) * if k = l then v else 1) = (if k = m then u else 1) * if k = n then v else 1
hl : ((if l = k then u else 1) * if True then v else 1) = (if l = m then u else 1) * if l = n then v else 1
hm : ((if True then u else 1) * if m = n then v else 1) = (if m = k then u else 1) * if m = l then v else 1
hn : ((if n = m then u else 1) * if True then v else 1) = (if n = k then u else 1) * if n = l then v else 1
⊢ k = m ∧ l = n ∨ u = v ∧ k = n ∧ l = m ∨ u * v = 1 ∧ k = l ∧ m = n

Proof state:
case refine_1.inl.inl
I : Type u
inst✝¹ : DecidableEq I
M : Type u_3
inst✝ : CommMonoid M
k n : I
u v : M
hu : u ≠ 1
hv : v ≠ 1
h : mulSingle k u * mulSingle k v = mulSingle k u * mulSingle n v
hk : ((if True then u else 1) * if k = k then v else 1) = (if k = k then u else 1) * if k = n then v else 1
hl : ((if k = k then u else 1) * if True then v else 1) = (if k = k then u else 1) * if k = n then v else 1
hm : ((if True then u else 1) * if k = n then v else 1) = (if k = k then u else 1) * if k = k then v else 1
hn : ((if n = k then u else 1) * if True then v else 1) = (if n = k then u else 1) * if n = k then v else 1
hln : k ≠ n
⊢ v = 1

Tactic:
rwa [if_neg hln.symm, if_neg hln.symm, one_mul, one_mul] at hn

Result:
no goals

Proof state:
case refine_1.inr.inr
I : Type u
inst✝¹ : DecidableEq I
M : Type u_3
inst✝ : CommMonoid M
k m n : I
u v : M
hu : u ≠ 1
hv : v ≠ 1
hkm : k ≠ m
hmn : m ≠ n
h : mulSingle k u * mulSingle m v = mulSingle m u * mulSingle n v
hk : ((if True then u else 1) * if k = m then v else 1) = (if k = m then u else 1) * if k = n then v else 1
hl : ((if m = k then u else 1) * if True then v else 1) = (if m = m then u else 1) * if m = n then v else 1
hm : (if True then u else 1) = if m = m then v else 1
hn : ((if n = m then u else 1) * if True then v else 1) = (if n = k then u else 1) * if n = m then v else 1
⊢ k = m ∧ m = n ∨ u = v ∧ k = n ∧ m = m ∨ u * v = 1 ∧ k = m ∧ m = n

Tactic:
rw [if_neg hkm, if_neg hkm, one_mul, mul_one] at hk

Result:
case refine_1.inr.inr
I : Type u
inst✝¹ : DecidableEq I
M : Type u_3
inst✝ : CommMonoid M
k m n : I
u v : M
hu : u ≠ 1
hv : v ≠ 1
hkm : k ≠ m
hmn : m ≠ n
h : mulSingle k u * mulSingle m v = mulSingle m u * mulSingle n v
hk : (if True then u else 1) = if k = n then v else 1
hl : ((if m = k then u else 1) * if True then v else 1) = (if m = m then u else 1) * if m = n then v else 1
hm : (if True then u else 1) = if m = m then v else 1
hn : ((if n = m then u else 1) * if True then v else 1) = (if n = k then u else 1) * if n = m then v else 1
⊢ k = m ∧ m = n ∨ u = v ∧ k = n ∧ m = m ∨ u * v = 1 ∧ k = m ∧ m = n

Proof state:
case refine_2.inl.intro
I : Type u
inst✝¹ : DecidableEq I
M : Type u_3
inst✝ : CommMonoid M
k l : I
u v : M
hu : u ≠ 1
hv : v ≠ 1
⊢ mulSingle k u * mulSingle l v = mulSingle k u * mulSingle l v

Tactic:
rfl

Result:
no goals

Proof state:
case refine_2.inr.inl.intro.intro
I : Type u
inst✝¹ : DecidableEq I
M : Type u_3
inst✝ : CommMonoid M
k l : I
u : M
hu hv : u ≠ 1
⊢ mulSingle k u * mulSingle l u = mulSingle l u * mulSingle k u

Tactic:
apply mul_comm

Result:
no goals

Proof state:
case refine_1.inr.inl.inl
I : Type u
inst✝¹ : DecidableEq I
M : Type u_3
inst✝ : CommMonoid M
k m : I
u v : M
hu : u ≠ 1
hv : v ≠ 1
hkm : k ≠ m
h : mulSingle k u * mulSingle k v = mulSingle m u * mulSingle m v
hk : ((if True then u else 1) * if k = k then v else 1) = (if k = m then u else 1) * if k = m then v else 1
hl : ((if k = k then u else 1) * if True then v else 1) = (if k = m then u else 1) * if k = m then v else 1
hm : (if True then u else 1) * v = 1
hn : ((if m = m then u else 1) * if True then v else 1) = (if m = k then u else 1) * if m = k then v else 1
⊢ k = m ∧ k = m ∨ u = v ∧ k = m ∧ k = m ∨ u * v = 1 ∧ k = k ∧ m = m

Tactic:
exact Or.inr (Or.inr ⟨hm, rfl, rfl⟩)

Result:
no goals

Proof state:
case refine_2
I : Type u
inst✝¹ : DecidableEq I
M : Type u_3
inst✝ : CommMonoid M
k l m n : I
u v : M
hu : u ≠ 1
hv : v ≠ 1
⊢ k = m ∧ l = n ∨ u = v ∧ k = n ∧ l = m ∨ u * v = 1 ∧ k = l ∧ m = n →
    mulSingle k u * mulSingle l v = mulSingle m u * mulSingle n v

Tactic:
rintro (⟨rfl, rfl⟩ | ⟨rfl, rfl, rfl⟩ | ⟨h, rfl, rfl⟩)

Result:
case refine_2.inl.intro
I : Type u
inst✝¹ : DecidableEq I
M : Type u_3
inst✝ : CommMonoid M
k l : I
u v : M
hu : u ≠ 1
hv : v ≠ 1
⊢ mulSingle k u * mulSingle l v = mulSingle k u * mulSingle l v

case refine_2.inr.inl.intro.intro
I : Type u
inst✝¹ : DecidableEq I
M : Type u_3
inst✝ : CommMonoid M
k l : I
u : M
hu hv : u ≠ 1
⊢ mulSingle k u * mulSingle l u = mulSingle l u * mulSingle k u

case refine_2.inr.inr.intro.intro
I : Type u
inst✝¹ : DecidableEq I
M : Type u_3
inst✝ : CommMonoid M
k m : I
u v : M
hu : u ≠ 1
hv : v ≠ 1
h : u * v = 1
⊢ mulSingle k u * mulSingle k v = mulSingle m u * mulSingle m v