l3lab/ntp-mathlib huggingface dataset:
@[to_additive]
theorem mul_eq_one_iff_eq_inv : a * b = 1 ↔ a = b⁻¹ :=
  ⟨eq_inv_of_mul_eq_one_left, fun h ↦ by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
h : a = b⁻¹
⊢ a * b = 1

Next tactic:
rw [h, mul_left_inv]
@[to_additive]
theorem mul_eq_one_iff_inv_eq : a * b = 1 ↔ a⁻¹ = b :=
  by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
⊢ a * b = 1 ↔ a⁻¹ = b

Next tactic:
rw [mul_eq_one_iff_eq_inv, inv_eq_iff_eq_inv]
@[to_additive]
theorem eq_mul_inv_iff_mul_eq : a = b * c⁻¹ ↔ a * c = b :=
  ⟨fun h ↦ by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
h : a = b * c⁻¹
⊢ a * c = b

Next tactic:
rw [h, inv_mul_cancel_right]
@[to_additive]
theorem eq_mul_inv_iff_mul_eq : a = b * c⁻¹ ↔ a * c = b :=
  ⟨fun h ↦ by rw [h, inv_mul_cancel_right], fun h ↦ by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
h : a * c = b
⊢ a = b * c⁻¹

Next tactic:
rw [← h, mul_inv_cancel_right]
@[to_additive]
theorem eq_inv_mul_iff_mul_eq : a = b⁻¹ * c ↔ b * a = c :=
  ⟨fun h ↦ by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
h : a = b⁻¹ * c
⊢ b * a = c

Next tactic:
rw [h, mul_inv_cancel_left]
@[to_additive]
theorem eq_inv_mul_iff_mul_eq : a = b⁻¹ * c ↔ b * a = c :=
  ⟨fun h ↦ by rw [h, mul_inv_cancel_left], fun h ↦ by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
h : b * a = c
⊢ a = b⁻¹ * c

Next tactic:
rw [← h, inv_mul_cancel_left]
@[to_additive]
theorem inv_mul_eq_iff_eq_mul : a⁻¹ * b = c ↔ b = a * c :=
  ⟨fun h ↦ by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
h : a⁻¹ * b = c
⊢ b = a * c

Next tactic:
rw [← h, mul_inv_cancel_left]
@[to_additive]
theorem inv_mul_eq_iff_eq_mul : a⁻¹ * b = c ↔ b = a * c :=
  ⟨fun h ↦ by rw [← h, mul_inv_cancel_left], fun h ↦ by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
h : b = a * c
⊢ a⁻¹ * b = c

Next tactic:
rw [h, inv_mul_cancel_left]
@[to_additive]
theorem mul_inv_eq_iff_eq_mul : a * b⁻¹ = c ↔ a = c * b :=
  ⟨fun h ↦ by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
h : a * b⁻¹ = c
⊢ a = c * b

Next tactic:
rw [← h, inv_mul_cancel_right]
@[to_additive]
theorem mul_inv_eq_iff_eq_mul : a * b⁻¹ = c ↔ a = c * b :=
  ⟨fun h ↦ by rw [← h, inv_mul_cancel_right], fun h ↦ by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
h : a = c * b
⊢ a * b⁻¹ = c

Next tactic:
rw [h, mul_inv_cancel_right]
@[to_additive]
theorem mul_inv_eq_one : a * b⁻¹ = 1 ↔ a = b := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
⊢ a * b⁻¹ = 1 ↔ a = b

Next tactic:
rw [mul_eq_one_iff_eq_inv, inv_inv]
@[to_additive]
theorem inv_mul_eq_one : a⁻¹ * b = 1 ↔ a = b := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
⊢ a⁻¹ * b = 1 ↔ a = b

Next tactic:
rw [mul_eq_one_iff_eq_inv, inv_inj]
@[to_additive]
theorem div_left_injective : Function.Injective fun a ↦ a / b := by
  -- FIXME this could be by `simpa`, but it fails. This is probably a bug in `simpa`.
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
⊢ Injective fun a => a / b

Next tactic:
simp only [div_eq_mul_inv]
@[to_additive]
theorem div_left_injective : Function.Injective fun a ↦ a / b := by
  -- FIXME this could be by `simpa`, but it fails. This is probably a bug in `simpa`.
  simp only [div_eq_mul_inv]
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
⊢ Injective fun a => a * b⁻¹

Next tactic:
exact fun a a' h ↦ mul_left_injective b⁻¹ h
@[to_additive]
theorem div_right_injective : Function.Injective fun a ↦ b / a := by
  -- FIXME see above
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
⊢ Injective fun a => b / a

Next tactic:
simp only [div_eq_mul_inv]
@[to_additive]
theorem div_right_injective : Function.Injective fun a ↦ b / a := by
  -- FIXME see above
  simp only [div_eq_mul_inv]
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
⊢ Injective fun a => b * a⁻¹

Next tactic:
exact fun a a' h ↦ inv_injective (mul_right_injective b h)
@[to_additive (attr := simp) sub_add_cancel]
theorem div_mul_cancel' (a b : G) : a / b * b = a :=
  by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a✝ b✝ c d a b : G
⊢ a / b * b = a

Next tactic:
rw [div_eq_mul_inv, inv_mul_cancel_right a b]
@[to_additive (attr := simp) sub_self]
theorem div_self' (a : G) : a / a = 1 := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a✝ b c d a : G
⊢ a / a = 1

Next tactic:
rw [div_eq_mul_inv, mul_right_inv a]
@[to_additive (attr := simp) add_sub_cancel]
theorem mul_div_cancel'' (a b : G) : a * b / b = a :=
  by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a✝ b✝ c d a b : G
⊢ a * b / b = a

Next tactic:
rw [div_eq_mul_inv, mul_inv_cancel_right a b]
@[to_additive (attr := simp) sub_add_cancel'']
theorem div_mul_cancel''' (a b : G) : a / (b * a) = b⁻¹ := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a✝ b✝ c d a b : G
⊢ a / (b * a) = b⁻¹

Next tactic:
rw [← inv_div, mul_div_cancel'']
@[to_additive (attr := simp)]
theorem mul_div_mul_right_eq_div (a b c : G) : a * c / (b * c) = a / b := by
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a✝ b✝ c✝ d a b c : G
⊢ a * c / (b * c) = a / b

Next tactic:
rw [div_mul_eq_div_div_swap]
@[to_additive (attr := simp)]
theorem mul_div_mul_right_eq_div (a b c : G) : a * c / (b * c) = a / b := by
  rw [div_mul_eq_div_div_swap]; 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a✝ b✝ c✝ d a b c : G
⊢ a * c / c / b = a / b

Next tactic:
simp only [mul_left_inj, eq_self_iff_true, mul_div_cancel'']
@[to_additive eq_sub_of_add_eq]
theorem eq_div_of_mul_eq' (h : a * c = b) : a = b / c := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
h : a * c = b
⊢ a = b / c

Next tactic:
simp [← h]
@[to_additive sub_eq_of_eq_add]
theorem div_eq_of_eq_mul'' (h : a = c * b) : a / b = c := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
h : a = c * b
⊢ a / b = c

Next tactic:
simp [h]
@[to_additive]
theorem eq_mul_of_div_eq (h : a / c = b) : a = b * c := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
h : a / c = b
⊢ a = b * c

Next tactic:
simp [← h]
@[to_additive]
theorem mul_eq_of_eq_div (h : a = c / b) : a * b = c := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
h : a = c / b
⊢ a * b = c

Next tactic:
simp [h]
@[to_additive (attr := simp)]
theorem div_left_inj : b / a = c / a ↔ b = c := by
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
⊢ b / a = c / a ↔ b = c

Next tactic:
rw [div_eq_mul_inv, div_eq_mul_inv]
@[to_additive (attr := simp)]
theorem div_left_inj : b / a = c / a ↔ b = c := by
  rw [div_eq_mul_inv, div_eq_mul_inv]
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
⊢ b * a⁻¹ = c * a⁻¹ ↔ b = c

Next tactic:
exact mul_left_inj _
@[to_additive (attr := simp) sub_add_sub_cancel]
theorem div_mul_div_cancel' (a b c : G) : a / b * (b / c) = a / c :=
  by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a✝ b✝ c✝ d a b c : G
⊢ a / b * (b / c) = a / c

Next tactic:
rw [← mul_div_assoc, div_mul_cancel']
@[to_additive (attr := simp) sub_sub_sub_cancel_right]
theorem div_div_div_cancel_right' (a b c : G) : a / c / (b / c) = a / b := by
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a✝ b✝ c✝ d a b c : G
⊢ a / c / (b / c) = a / b

Next tactic:
rw [← inv_div c b, div_inv_eq_mul, div_mul_div_cancel']
@[to_additive]
theorem div_eq_one : a / b = 1 ↔ a = b :=
  ⟨eq_of_div_eq_one, fun h ↦ by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
h : a = b
⊢ a / b = 1

Next tactic:
rw [h, div_self']
@[to_additive (attr := simp)]
theorem div_eq_self : a / b = a ↔ b = 1 := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
⊢ a / b = a ↔ b = 1

Next tactic:
rw [div_eq_mul_inv, mul_right_eq_self, inv_eq_one]
@[to_additive eq_sub_iff_add_eq]
theorem eq_div_iff_mul_eq' : a = b / c ↔ a * c = b := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
⊢ a = b / c ↔ a * c = b

Next tactic:
rw [div_eq_mul_inv, eq_mul_inv_iff_mul_eq]
@[to_additive]
theorem div_eq_iff_eq_mul : a / b = c ↔ a = c * b := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
⊢ a / b = c ↔ a = c * b

Next tactic:
rw [div_eq_mul_inv, mul_inv_eq_iff_eq_mul]
@[to_additive]
theorem eq_iff_eq_of_div_eq_div (H : a / b = c / d) : a = b ↔ c = d :=
  by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
H : a / b = c / d
⊢ a = b ↔ c = d

Next tactic:
rw [← div_eq_one, H, div_eq_one]
@[to_additive]
theorem exists_npow_eq_one_of_zpow_eq_one {n : ℤ} (hn : n ≠ 0) {x : G} (h : x ^ n = 1) :
    ∃ n : ℕ, 0 < n ∧ x ^ n = 1 := by
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d : G
n : ℤ
hn : n ≠ 0
x : G
h : x ^ n = 1
⊢ ∃ n, 0 < n ∧ x ^ n = 1

Next tactic:
cases' n with n n
@[to_additive]
theorem exists_npow_eq_one_of_zpow_eq_one {n : ℤ} (hn : n ≠ 0) {x : G} (h : x ^ n = 1) :
    ∃ n : ℕ, 0 < n ∧ x ^ n = 1 := by
  cases' n with n n
  · 

Proof state:
case ofNat
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d x : G
n : ℕ
hn : Int.ofNat n ≠ 0
h : x ^ Int.ofNat n = 1
⊢ ∃ n, 0 < n ∧ x ^ n = 1

Next tactic:
simp only [Int.ofNat_eq_coe] at h
@[to_additive]
theorem exists_npow_eq_one_of_zpow_eq_one {n : ℤ} (hn : n ≠ 0) {x : G} (h : x ^ n = 1) :
    ∃ n : ℕ, 0 < n ∧ x ^ n = 1 := by
  cases' n with n n
  · simp only [Int.ofNat_eq_coe] at h
    

Proof state:
case ofNat
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d x : G
n : ℕ
hn : Int.ofNat n ≠ 0
h : x ^ ↑n = 1
⊢ ∃ n, 0 < n ∧ x ^ n = 1

Next tactic:
rw [zpow_ofNat] at h
@[to_additive]
theorem exists_npow_eq_one_of_zpow_eq_one {n : ℤ} (hn : n ≠ 0) {x : G} (h : x ^ n = 1) :
    ∃ n : ℕ, 0 < n ∧ x ^ n = 1 := by
  cases' n with n n
  · simp only [Int.ofNat_eq_coe] at h
    rw [zpow_ofNat] at h
    

Proof state:
case ofNat
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d x : G
n : ℕ
hn : Int.ofNat n ≠ 0
h : x ^ n = 1
⊢ ∃ n, 0 < n ∧ x ^ n = 1

Next tactic:
refine' ⟨n, Nat.pos_of_ne_zero fun n0 ↦ hn ?_, h⟩
@[to_additive]
theorem exists_npow_eq_one_of_zpow_eq_one {n : ℤ} (hn : n ≠ 0) {x : G} (h : x ^ n = 1) :
    ∃ n : ℕ, 0 < n ∧ x ^ n = 1 := by
  cases' n with n n
  · simp only [Int.ofNat_eq_coe] at h
    rw [zpow_ofNat] at h
    refine' ⟨n, Nat.pos_of_ne_zero fun n0 ↦ hn ?_, h⟩
    

Proof state:
case ofNat
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d x : G
n : ℕ
hn : Int.ofNat n ≠ 0
h : x ^ n = 1
n0 : n = 0
⊢ Int.ofNat n = 0

Next tactic:
rw [n0]
@[to_additive]
theorem exists_npow_eq_one_of_zpow_eq_one {n : ℤ} (hn : n ≠ 0) {x : G} (h : x ^ n = 1) :
    ∃ n : ℕ, 0 < n ∧ x ^ n = 1 := by
  cases' n with n n
  · simp only [Int.ofNat_eq_coe] at h
    rw [zpow_ofNat] at h
    refine' ⟨n, Nat.pos_of_ne_zero fun n0 ↦ hn ?_, h⟩
    rw [n0]
    

Proof state:
case ofNat
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d x : G
n : ℕ
hn : Int.ofNat n ≠ 0
h : x ^ n = 1
n0 : n = 0
⊢ Int.ofNat 0 = 0

Next tactic:
rfl
@[to_additive]
theorem exists_npow_eq_one_of_zpow_eq_one {n : ℤ} (hn : n ≠ 0) {x : G} (h : x ^ n = 1) :
    ∃ n : ℕ, 0 < n ∧ x ^ n = 1 := by
  cases' n with n n
  · simp only [Int.ofNat_eq_coe] at h
    rw [zpow_ofNat] at h
    refine' ⟨n, Nat.pos_of_ne_zero fun n0 ↦ hn ?_, h⟩
    rw [n0]
    rfl
  · 

Proof state:
case negSucc
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d x : G
n : ℕ
hn : Int.negSucc n ≠ 0
h : x ^ Int.negSucc n = 1
⊢ ∃ n, 0 < n ∧ x ^ n = 1

Next tactic:
rw [zpow_negSucc, inv_eq_one] at h
@[to_additive]
theorem exists_npow_eq_one_of_zpow_eq_one {n : ℤ} (hn : n ≠ 0) {x : G} (h : x ^ n = 1) :
    ∃ n : ℕ, 0 < n ∧ x ^ n = 1 := by
  cases' n with n n
  · simp only [Int.ofNat_eq_coe] at h
    rw [zpow_ofNat] at h
    refine' ⟨n, Nat.pos_of_ne_zero fun n0 ↦ hn ?_, h⟩
    rw [n0]
    rfl
  · rw [zpow_negSucc, inv_eq_one] at h
    

Proof state:
case negSucc
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : Group G
a b c d x : G
n : ℕ
hn : Int.negSucc n ≠ 0
h : x ^ (n + 1) = 1
⊢ ∃ n, 0 < n ∧ x ^ n = 1

Next tactic:
refine' ⟨n + 1, n.succ_pos, h⟩
@[to_additive]
theorem div_eq_of_eq_mul' {a b c : G} (h : a = b * c) : a / b = c := by
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a✝ b✝ c✝ d a b c : G
h : a = b * c
⊢ a / b = c

Next tactic:
rw [h, div_eq_mul_inv, mul_comm, inv_mul_cancel_left]
@[to_additive (attr := simp)]
theorem mul_div_mul_left_eq_div (a b c : G) : c * a / (c * b) = a / b := by
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a✝ b✝ c✝ d a b c : G
⊢ c * a / (c * b) = a / b

Next tactic:
rw [div_eq_mul_inv, mul_inv_rev, mul_comm b⁻¹ c⁻¹, mul_comm c a, mul_assoc, ← mul_assoc c,
    mul_right_inv, one_mul, div_eq_mul_inv]
@[to_additive eq_sub_of_add_eq']
theorem eq_div_of_mul_eq'' (h : c * a = b) : a = b / c := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a b c d : G
h : c * a = b
⊢ a = b / c

Next tactic:
simp [h.symm]
@[to_additive]
theorem eq_mul_of_div_eq' (h : a / b = c) : a = b * c := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a b c d : G
h : a / b = c
⊢ a = b * c

Next tactic:
simp [h.symm]
@[to_additive]
theorem mul_eq_of_eq_div' (h : b = c / a) : a * b = c := by
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a b c d : G
h : b = c / a
⊢ a * b = c

Next tactic:
rw [h, div_eq_mul_inv, mul_comm c, mul_inv_cancel_left]
@[to_additive sub_sub_self]
theorem div_div_self' (a b : G) : a / (a / b) = b := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a✝ b✝ c d a b : G
⊢ a / (a / b) = b

Next tactic:
simpa using mul_inv_cancel_left a b
@[to_additive]
theorem div_eq_div_mul_div (a b c : G) : a / b = c / b * (a / c) := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a✝ b✝ c✝ d a b c : G
⊢ a / b = c / b * (a / c)

Next tactic:
simp [mul_left_comm c]
@[to_additive (attr := simp)]
theorem div_div_cancel_left (a b : G) : a / b / a = b⁻¹ := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a✝ b✝ c d a b : G
⊢ a / b / a = b⁻¹

Next tactic:
simp
@[to_additive eq_sub_iff_add_eq']
theorem eq_div_iff_mul_eq'' : a = b / c ↔ c * a = b := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a b c d : G
⊢ a = b / c ↔ c * a = b

Next tactic:
rw [eq_div_iff_mul_eq', mul_comm]
@[to_additive]
theorem div_eq_iff_eq_mul' : a / b = c ↔ a = b * c := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a b c d : G
⊢ a / b = c ↔ a = b * c

Next tactic:
rw [div_eq_iff_eq_mul, mul_comm]
@[to_additive (attr := simp) add_sub_cancel']
theorem mul_div_cancel''' (a b : G) : a * b / a = b := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a✝ b✝ c d a b : G
⊢ a * b / a = b

Next tactic:
rw [div_eq_inv_mul, inv_mul_cancel_left]
@[to_additive (attr := simp)]
theorem mul_div_cancel'_right (a b : G) : a * (b / a) = b := by
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a✝ b✝ c d a b : G
⊢ a * (b / a) = b

Next tactic:
rw [← mul_div_assoc, mul_div_cancel''']
@[to_additive (attr := simp) sub_add_cancel']
theorem div_mul_cancel'' (a b : G) : a / (a * b) = b⁻¹ := by 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a✝ b✝ c d a b : G
⊢ a / (a * b) = b⁻¹

Next tactic:
rw [← inv_div, mul_div_cancel''']
@[to_additive]
theorem mul_mul_inv_cancel'_right (a b : G) : a * (b * a⁻¹) = b := by
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a✝ b✝ c d a b : G
⊢ a * (b * a⁻¹) = b

Next tactic:
rw [← div_eq_mul_inv, mul_div_cancel'_right a b]
@[to_additive (attr := simp)]
theorem mul_mul_div_cancel (a b c : G) : a * c * (b / c) = a * b := by
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a✝ b✝ c✝ d a b c : G
⊢ a * c * (b / c) = a * b

Next tactic:
rw [mul_assoc, mul_div_cancel'_right]
@[to_additive (attr := simp)]
theorem div_mul_mul_cancel (a b c : G) : a / c * (b * c) = a * b := by
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a✝ b✝ c✝ d a b c : G
⊢ a / c * (b * c) = a * b

Next tactic:
rw [mul_left_comm, div_mul_cancel', mul_comm]
@[to_additive (attr := simp) sub_add_sub_cancel']
theorem div_mul_div_cancel'' (a b c : G) : a / b * (c / a) = c / b := by
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a✝ b✝ c✝ d a b c : G
⊢ a / b * (c / a) = c / b

Next tactic:
rw [mul_comm]
@[to_additive (attr := simp) sub_add_sub_cancel']
theorem div_mul_div_cancel'' (a b c : G) : a / b * (c / a) = c / b := by
  rw [mul_comm]; 

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a✝ b✝ c✝ d a b c : G
⊢ c / a * (a / b) = c / b

Next tactic:
apply div_mul_div_cancel'
@[to_additive (attr := simp)]
theorem mul_div_div_cancel (a b c : G) : a * b / (a / c) = b * c := by
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a✝ b✝ c✝ d a b c : G
⊢ a * b / (a / c) = b * c

Next tactic:
rw [← div_mul, mul_div_cancel''']
@[to_additive (attr := simp)]
theorem div_div_div_cancel_left (a b c : G) : c / a / (c / b) = b / a := by
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a✝ b✝ c✝ d a b c : G
⊢ c / a / (c / b) = b / a

Next tactic:
rw [← inv_div b c, div_inv_eq_mul, mul_comm, div_mul_div_cancel']
@[to_additive]
theorem div_eq_div_iff_mul_eq_mul : a / b = c / d ↔ a * d = c * b := by
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a b c d : G
⊢ a / b = c / d ↔ a * d = c * b

Next tactic:
rw [div_eq_iff_eq_mul, div_mul_eq_mul_div, eq_comm, div_eq_iff_eq_mul']
@[to_additive]
theorem div_eq_div_iff_mul_eq_mul : a / b = c / d ↔ a * d = c * b := by
  rw [div_eq_iff_eq_mul, div_mul_eq_mul_div, eq_comm, div_eq_iff_eq_mul']
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a b c d : G
⊢ c * b = d * a ↔ a * d = c * b

Next tactic:
simp only [mul_comm, eq_comm]
@[to_additive]
theorem div_eq_div_iff_div_eq_div : a / b = c / d ↔ a / c = b / d := by
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝ : CommGroup G
a b c d : G
⊢ a / b = c / d ↔ a / c = b / d

Next tactic:
rw [div_eq_iff_eq_mul, div_mul_eq_mul_div, div_eq_iff_eq_mul', mul_div_assoc]
@[to_additive additive_of_symmetric_of_isTotal]
lemma multiplicative_of_symmetric_of_isTotal
    (hsymm : Symmetric p) (hf_swap : ∀ {a b}, p a b → f a b * f b a = 1)
    (hmul : ∀ {a b c}, r a b → r b c → p a b → p b c → p a c → f a c = f a b * f b c)
    {a b c : α} (pab : p a b) (pbc : p b c) (pac : p a c) : f a c = f a b * f b c := by
  

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝¹ : Monoid β
p r : α → α → Prop
inst✝ : IsTotal α r
f : α → α → β
hsymm : Symmetric p
hf_swap : ∀ {a b : α}, p a b → f a b * f b a = 1
hmul : ∀ {a b c : α}, r a b → r b c → p a b → p b c → p a c → f a c = f a b * f b c
a b c : α
pab : p a b
pbc : p b c
pac : p a c
⊢ f a c = f a b * f b c

Next tactic:
have hmul' : ∀ {b c}, r b c → p a b → p b c → p a c → f a c = f a b * f b c := by
    intros b c rbc pab pbc pac
    obtain rab | rba := total_of r a b
    · exact hmul rab rbc pab pbc pac
    rw [← one_mul (f a c), ← hf_swap pab, mul_assoc]
    obtain rac | rca := total_of r a c
    · rw [hmul rba rac (hsymm pab) pac pbc]
    · rw [hmul rbc rca pbc (hsymm pac) (hsymm pab), mul_assoc, hf_swap (hsymm pac), mul_one]
@[to_additive additive_of_symmetric_of_isTotal]
lemma multiplicative_of_symmetric_of_isTotal
    (hsymm : Symmetric p) (hf_swap : ∀ {a b}, p a b → f a b * f b a = 1)
    (hmul : ∀ {a b c}, r a b → r b c → p a b → p b c → p a c → f a c = f a b * f b c)
    {a b c : α} (pab : p a b) (pbc : p b c) (pac : p a c) : f a c = f a b * f b c := by
  have hmul' : ∀ {b c}, r b c → p a b → p b c → p a c → f a c = f a b * f b c := by
    

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝¹ : Monoid β
p r : α → α → Prop
inst✝ : IsTotal α r
f : α → α → β
hsymm : Symmetric p
hf_swap : ∀ {a b : α}, p a b → f a b * f b a = 1
hmul : ∀ {a b c : α}, r a b → r b c → p a b → p b c → p a c → f a c = f a b * f b c
a b c : α
pab : p a b
pbc : p b c
pac : p a c
⊢ ∀ {b c : α}, r b c → p a b → p b c → p a c → f a c = f a b * f b c

Next tactic:
intros b c rbc pab pbc pac
@[to_additive additive_of_symmetric_of_isTotal]
lemma multiplicative_of_symmetric_of_isTotal
    (hsymm : Symmetric p) (hf_swap : ∀ {a b}, p a b → f a b * f b a = 1)
    (hmul : ∀ {a b c}, r a b → r b c → p a b → p b c → p a c → f a c = f a b * f b c)
    {a b c : α} (pab : p a b) (pbc : p b c) (pac : p a c) : f a c = f a b * f b c := by
  have hmul' : ∀ {b c}, r b c → p a b → p b c → p a c → f a c = f a b * f b c := by
    intros b c rbc pab pbc pac
    

Proof state:
α : Type u_1
β : Type u_2
G : Type u_3
inst✝¹ : Monoid β
p r : α → α → Prop
inst✝ : IsTotal α r
f : α → α → β
hsymm : Symmetric p
hf_swap : ∀ {a b : α}, p a b → f a b * f b a = 1
hmul : ∀ {a b c : α}, r a b → r b c → p a b → p b c → p a c → f a c = f a b * f b c
a b✝ c✝ : α
pab✝ : p a b✝
pbc✝ : p b✝ c✝
pac✝ : p a c✝
b c : α
rbc : r b c
pab : p a b
pbc : p b c
pac : p a c
⊢ f a c = f a b * f b c

Next tactic:
obtain rab | rba := total_of r a b
@[to_additive additive_of_symmetric_of_isTotal]
lemma multiplicative_of_symmetric_of_isTotal
    (hsymm : Symmetric p) (hf_swap : ∀ {a b}, p a b → f a b * f b a = 1)
    (hmul : ∀ {a b c}, r a b → r b c → p a b → p b c → p a c → f a c = f a b * f b c)
    {a b c : α} (pab : p a b) (pbc : p b c) (pac : p a c) : f a c = f a b * f b c := by
  have hmul' : ∀ {b c}, r b c → p a b → p b c → p a c → f a c = f a b * f b c := by
    intros b c rbc pab pbc pac
    obtain rab | rba := total_of r a b
    · 

Proof state:
case inl
α : Type u_1
β : Type u_2
G : Type u_3
inst✝¹ : Monoid β
p r : α → α → Prop
inst✝ : IsTotal α r
f : α → α → β
hsymm : Symmetric p
hf_swap : ∀ {a b : α}, p a b → f a b * f b a = 1
hmul : ∀ {a b c : α}, r a b → r b c → p a b → p b c → p a c → f a c = f a b * f b c
a b✝ c✝ : α
pab✝ : p a b✝
pbc✝ : p b✝ c✝
pac✝ : p a c✝
b c : α
rbc : r b c
pab : p a b
pbc : p b c
pac : p a c
rab : r a b
⊢ f a c = f a b * f b c

Next tactic:
exact hmul rab rbc pab pbc pac
@[to_additive additive_of_symmetric_of_isTotal]
lemma multiplicative_of_symmetric_of_isTotal
    (hsymm : Symmetric p) (hf_swap : ∀ {a b}, p a b → f a b * f b a = 1)
    (hmul : ∀ {a b c}, r a b → r b c → p a b → p b c → p a c → f a c = f a b * f b c)
    {a b c : α} (pab : p a b) (pbc : p b c) (pac : p a c) : f a c = f a b * f b c := by
  have hmul' : ∀ {b c}, r b c → p a b → p b c → p a c → f a c = f a b * f b c := by
    intros b c rbc pab pbc pac
    obtain rab | rba := total_of r a b
    · exact hmul rab rbc pab pbc pac
    

Proof state:
case inr
α : Type u_1
β : Type u_2
G : Type u_3
inst✝¹ : Monoid β
p r : α → α → Prop
inst✝ : IsTotal α r
f : α → α → β
hsymm : Symmetric p
hf_swap : ∀ {a b : α}, p a b → f a b * f b a = 1
hmul : ∀ {a b c : α}, r a b → r b c → p a b → p b c → p a c → f a c = f a b * f b c
a b✝ c✝ : α
pab✝ : p a b✝
pbc✝ : p b✝ c✝
pac✝ : p a c✝
b c : α
rbc : r b c
pab : p a b
pbc : p b c
pac : p a c
rba : r b a
⊢ f a c = f a b * f b c

Next tactic:
rw [← one_mul (f a c), ← hf_swap pab, mul_assoc]