l3lab/ntp-mathlib huggingface dataset:
theorem normSq_def' : normSq a = a.1 ^ 2 + a.2 ^ 2 + a.3 ^ 2 + a.4 ^ 2 := by
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
r x y z : R
a b c : ℍ[R]
⊢ normSq a = a.re ^ 2 + a.imI ^ 2 + a.imJ ^ 2 + a.imK ^ 2

Next tactic:
simp only [normSq_def, sq, mul_neg, sub_neg_eq_add, mul_re, star_re, star_imI, star_imJ,
    star_imK]
theorem normSq_coe : normSq (x : ℍ[R]) = x ^ 2 := by
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
r x y z : R
a b c : ℍ[R]
⊢ normSq ↑x = x ^ 2

Next tactic:
rw [normSq_def, star_coe, ← coe_mul, coe_re, sq]
@[simp]
theorem normSq_star : normSq (star a) = normSq a := by 

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
r x y z : R
a b c : ℍ[R]
⊢ normSq (star a) = normSq a

Next tactic:
simp [normSq_def']
@[norm_cast]
theorem normSq_nat_cast (n : ℕ) : normSq (n : ℍ[R]) = (n : R) ^ 2 := by
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
r x y z : R
a b c : ℍ[R]
n : ℕ
⊢ normSq ↑n = ↑n ^ 2

Next tactic:
rw [← coe_nat_cast, normSq_coe]
@[norm_cast]
theorem normSq_int_cast (z : ℤ) : normSq (z : ℍ[R]) = (z : R) ^ 2 := by
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
r x y z✝ : R
a b c : ℍ[R]
z : ℤ
⊢ normSq ↑z = ↑z ^ 2

Next tactic:
rw [← coe_int_cast, normSq_coe]
@[simp]
theorem normSq_neg : normSq (-a) = normSq a := by 

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
r x y z : R
a b c : ℍ[R]
⊢ normSq (-a) = normSq a

Next tactic:
simp only [normSq_def, star_neg, neg_mul_neg]
theorem self_mul_star : a * star a = normSq a := by 

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
r x y z : R
a b c : ℍ[R]
⊢ a * star a = ↑(normSq a)

Next tactic:
rw [mul_star_eq_coe, normSq_def]
theorem star_mul_self : star a * a = normSq a := by 

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
r x y z : R
a b c : ℍ[R]
⊢ star a * a = ↑(normSq a)

Next tactic:
rw [star_comm_self, self_mul_star]
theorem im_sq : a.im ^ 2 = -normSq a.im := by
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
r x y z : R
a b c : ℍ[R]
⊢ im a ^ 2 = -↑(normSq (im a))

Next tactic:
simp_rw [sq, ← star_mul_self, im_star, neg_mul, neg_neg]
theorem coe_normSq_add : normSq (a + b) = normSq a + a * star b + b * star a + normSq b := by
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
r x y z : R
a b c : ℍ[R]
⊢ ↑(normSq (a + b)) = ↑(normSq a) + a * star b + b * star a + ↑(normSq b)

Next tactic:
simp only [star_add, ← self_mul_star, mul_add, add_mul, add_assoc, add_left_comm]
theorem normSq_smul (r : R) (q : ℍ[R]) : normSq (r • q) = r ^ 2 * normSq q := by
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
r✝ x y z : R
a b c : ℍ[R]
r : R
q : ℍ[R]
⊢ normSq (r • q) = r ^ 2 * normSq q

Next tactic:
simp only [normSq_def', smul_re, smul_imI, smul_imJ, smul_imK, mul_pow, mul_add, smul_eq_mul]
theorem normSq_add (a b : ℍ[R]) : normSq (a + b) = normSq a + normSq b + 2 * (a * star b).re :=
  calc
    normSq (a + b) = normSq a + (a * star b).re + ((b * star a).re + normSq b) := by
      

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
r x y z : R
a✝ b✝ c a b : ℍ[R]
⊢ normSq (a + b) = normSq a + (a * star b).re + ((b * star a).re + normSq b)

Next tactic:
simp_rw [normSq_def, star_add, add_mul, mul_add, add_re]
theorem normSq_add (a b : ℍ[R]) : normSq (a + b) = normSq a + normSq b + 2 * (a * star b).re :=
  calc
    normSq (a + b) = normSq a + (a * star b).re + ((b * star a).re + normSq b) := by
      simp_rw [normSq_def, star_add, add_mul, mul_add, add_re]
    _ = normSq a + normSq b + ((a * star b).re + (b * star a).re) := by 

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
r x y z : R
a✝ b✝ c a b : ℍ[R]
⊢ normSq a + (a * star b).re + ((b * star a).re + normSq b) = normSq a + normSq b + ((a * star b).re + (b * star a).re)

Next tactic:
abel
theorem normSq_add (a b : ℍ[R]) : normSq (a + b) = normSq a + normSq b + 2 * (a * star b).re :=
  calc
    normSq (a + b) = normSq a + (a * star b).re + ((b * star a).re + normSq b) := by
      simp_rw [normSq_def, star_add, add_mul, mul_add, add_re]
    _ = normSq a + normSq b + ((a * star b).re + (b * star a).re) := by abel
    _ = normSq a + normSq b + 2 * (a * star b).re := by
      

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
r x y z : R
a✝ b✝ c a b : ℍ[R]
⊢ normSq a + normSq b + ((a * star b).re + (b * star a).re) = normSq a + normSq b + 2 * (a * star b).re

Next tactic:
rw [← add_re, ← star_mul_star a b, self_add_star', coe_re]
@[simp]
theorem normSq_eq_zero : normSq a = 0 ↔ a = 0 := by
  

Proof state:
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
⊢ normSq a = 0 ↔ a = 0

Next tactic:
refine' ⟨fun h => _, fun h => h.symm ▸ normSq.map_zero⟩
@[simp]
theorem normSq_eq_zero : normSq a = 0 ↔ a = 0 := by
  refine' ⟨fun h => _, fun h => h.symm ▸ normSq.map_zero⟩
  

Proof state:
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : normSq a = 0
⊢ a = 0

Next tactic:
rw [normSq_def', add_eq_zero_iff', add_eq_zero_iff', add_eq_zero_iff'] at h
@[simp]
theorem normSq_eq_zero : normSq a = 0 ↔ a = 0 := by
  refine' ⟨fun h => _, fun h => h.symm ▸ normSq.map_zero⟩
  rw [normSq_def', add_eq_zero_iff', add_eq_zero_iff', add_eq_zero_iff'] at h
  

Proof state:
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : ((a.re ^ 2 = 0 ∧ a.imI ^ 2 = 0) ∧ a.imJ ^ 2 = 0) ∧ a.imK ^ 2 = 0
⊢ a = 0
case ha
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : (a.re ^ 2 + a.imI ^ 2 = 0 ∧ a.imJ ^ 2 = 0) ∧ a.imK ^ 2 = 0
⊢ 0 ≤ a.re ^ 2
case hb
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : (a.re ^ 2 + a.imI ^ 2 = 0 ∧ a.imJ ^ 2 = 0) ∧ a.imK ^ 2 = 0
⊢ 0 ≤ a.imI ^ 2
case ha
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : a.re ^ 2 + a.imI ^ 2 + a.imJ ^ 2 = 0 ∧ a.imK ^ 2 = 0
⊢ 0 ≤ a.re ^ 2 + a.imI ^ 2
case hb
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : a.re ^ 2 + a.imI ^ 2 + a.imJ ^ 2 = 0 ∧ a.imK ^ 2 = 0
⊢ 0 ≤ a.imJ ^ 2
case ha
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : a.re ^ 2 + a.imI ^ 2 + a.imJ ^ 2 + a.imK ^ 2 = 0
⊢ 0 ≤ a.re ^ 2 + a.imI ^ 2 + a.imJ ^ 2
case hb
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : a.re ^ 2 + a.imI ^ 2 + a.imJ ^ 2 + a.imK ^ 2 = 0
⊢ 0 ≤ a.imK ^ 2

Next tactic:
exact ext a 0 (pow_eq_zero h.1.1.1) (pow_eq_zero h.1.1.2) (pow_eq_zero h.1.2) (pow_eq_zero h.2)
@[simp]
theorem normSq_eq_zero : normSq a = 0 ↔ a = 0 := by
  refine' ⟨fun h => _, fun h => h.symm ▸ normSq.map_zero⟩
  rw [normSq_def', add_eq_zero_iff', add_eq_zero_iff', add_eq_zero_iff'] at h
  exact ext a 0 (pow_eq_zero h.1.1.1) (pow_eq_zero h.1.1.2) (pow_eq_zero h.1.2) (pow_eq_zero h.2)
  

Proof state:
case ha
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : (a.re ^ 2 + a.imI ^ 2 = 0 ∧ a.imJ ^ 2 = 0) ∧ a.imK ^ 2 = 0
⊢ 0 ≤ a.re ^ 2
case hb
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : (a.re ^ 2 + a.imI ^ 2 = 0 ∧ a.imJ ^ 2 = 0) ∧ a.imK ^ 2 = 0
⊢ 0 ≤ a.imI ^ 2
case ha
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : a.re ^ 2 + a.imI ^ 2 + a.imJ ^ 2 = 0 ∧ a.imK ^ 2 = 0
⊢ 0 ≤ a.re ^ 2 + a.imI ^ 2
case hb
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : a.re ^ 2 + a.imI ^ 2 + a.imJ ^ 2 = 0 ∧ a.imK ^ 2 = 0
⊢ 0 ≤ a.imJ ^ 2
case ha
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : a.re ^ 2 + a.imI ^ 2 + a.imJ ^ 2 + a.imK ^ 2 = 0
⊢ 0 ≤ a.re ^ 2 + a.imI ^ 2 + a.imJ ^ 2
case hb
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : a.re ^ 2 + a.imI ^ 2 + a.imJ ^ 2 + a.imK ^ 2 = 0
⊢ 0 ≤ a.imK ^ 2

Next tactic:
all_goals apply_rules [sq_nonneg, add_nonneg]
@[simp]
theorem normSq_eq_zero : normSq a = 0 ↔ a = 0 := by
  refine' ⟨fun h => _, fun h => h.symm ▸ normSq.map_zero⟩
  rw [normSq_def', add_eq_zero_iff', add_eq_zero_iff', add_eq_zero_iff'] at h
  exact ext a 0 (pow_eq_zero h.1.1.1) (pow_eq_zero h.1.1.2) (pow_eq_zero h.1.2) (pow_eq_zero h.2)
  all_goals 

Proof state:
case ha
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : (a.re ^ 2 + a.imI ^ 2 = 0 ∧ a.imJ ^ 2 = 0) ∧ a.imK ^ 2 = 0
⊢ 0 ≤ a.re ^ 2

Next tactic:
apply_rules [sq_nonneg, add_nonneg]
@[simp]
theorem normSq_eq_zero : normSq a = 0 ↔ a = 0 := by
  refine' ⟨fun h => _, fun h => h.symm ▸ normSq.map_zero⟩
  rw [normSq_def', add_eq_zero_iff', add_eq_zero_iff', add_eq_zero_iff'] at h
  exact ext a 0 (pow_eq_zero h.1.1.1) (pow_eq_zero h.1.1.2) (pow_eq_zero h.1.2) (pow_eq_zero h.2)
  all_goals 

Proof state:
case hb
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : (a.re ^ 2 + a.imI ^ 2 = 0 ∧ a.imJ ^ 2 = 0) ∧ a.imK ^ 2 = 0
⊢ 0 ≤ a.imI ^ 2

Next tactic:
apply_rules [sq_nonneg, add_nonneg]
@[simp]
theorem normSq_eq_zero : normSq a = 0 ↔ a = 0 := by
  refine' ⟨fun h => _, fun h => h.symm ▸ normSq.map_zero⟩
  rw [normSq_def', add_eq_zero_iff', add_eq_zero_iff', add_eq_zero_iff'] at h
  exact ext a 0 (pow_eq_zero h.1.1.1) (pow_eq_zero h.1.1.2) (pow_eq_zero h.1.2) (pow_eq_zero h.2)
  all_goals 

Proof state:
case ha
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : a.re ^ 2 + a.imI ^ 2 + a.imJ ^ 2 = 0 ∧ a.imK ^ 2 = 0
⊢ 0 ≤ a.re ^ 2 + a.imI ^ 2

Next tactic:
apply_rules [sq_nonneg, add_nonneg]
@[simp]
theorem normSq_eq_zero : normSq a = 0 ↔ a = 0 := by
  refine' ⟨fun h => _, fun h => h.symm ▸ normSq.map_zero⟩
  rw [normSq_def', add_eq_zero_iff', add_eq_zero_iff', add_eq_zero_iff'] at h
  exact ext a 0 (pow_eq_zero h.1.1.1) (pow_eq_zero h.1.1.2) (pow_eq_zero h.1.2) (pow_eq_zero h.2)
  all_goals 

Proof state:
case hb
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : a.re ^ 2 + a.imI ^ 2 + a.imJ ^ 2 = 0 ∧ a.imK ^ 2 = 0
⊢ 0 ≤ a.imJ ^ 2

Next tactic:
apply_rules [sq_nonneg, add_nonneg]
@[simp]
theorem normSq_eq_zero : normSq a = 0 ↔ a = 0 := by
  refine' ⟨fun h => _, fun h => h.symm ▸ normSq.map_zero⟩
  rw [normSq_def', add_eq_zero_iff', add_eq_zero_iff', add_eq_zero_iff'] at h
  exact ext a 0 (pow_eq_zero h.1.1.1) (pow_eq_zero h.1.1.2) (pow_eq_zero h.1.2) (pow_eq_zero h.2)
  all_goals 

Proof state:
case ha
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : a.re ^ 2 + a.imI ^ 2 + a.imJ ^ 2 + a.imK ^ 2 = 0
⊢ 0 ≤ a.re ^ 2 + a.imI ^ 2 + a.imJ ^ 2

Next tactic:
apply_rules [sq_nonneg, add_nonneg]
@[simp]
theorem normSq_eq_zero : normSq a = 0 ↔ a = 0 := by
  refine' ⟨fun h => _, fun h => h.symm ▸ normSq.map_zero⟩
  rw [normSq_def', add_eq_zero_iff', add_eq_zero_iff', add_eq_zero_iff'] at h
  exact ext a 0 (pow_eq_zero h.1.1.1) (pow_eq_zero h.1.1.2) (pow_eq_zero h.1.2) (pow_eq_zero h.2)
  all_goals 

Proof state:
case hb
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
h : a.re ^ 2 + a.imI ^ 2 + a.imJ ^ 2 + a.imK ^ 2 = 0
⊢ 0 ≤ a.imK ^ 2

Next tactic:
apply_rules [sq_nonneg, add_nonneg]
@[simp]
theorem normSq_nonneg : 0 ≤ normSq a := by
  

Proof state:
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
⊢ 0 ≤ normSq a

Next tactic:
rw [normSq_def']
@[simp]
theorem normSq_nonneg : 0 ≤ normSq a := by
  rw [normSq_def']
  

Proof state:
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
⊢ 0 ≤ a.re ^ 2 + a.imI ^ 2 + a.imJ ^ 2 + a.imK ^ 2

Next tactic:
apply_rules [sq_nonneg, add_nonneg]
instance : NoZeroDivisors ℍ[R] where
  eq_zero_or_eq_zero_of_mul_eq_zero {a b} hab :=
    have : normSq a * normSq b = 0 := by 

Proof state:
R : Type u_1
inst✝ : LinearOrderedCommRing R
a✝ a b : ℍ[R]
hab : a * b = 0
⊢ normSq a * normSq b = 0

Next tactic:
rwa [← map_mul, normSq_eq_zero]
theorem sq_eq_normSq : a ^ 2 = normSq a ↔ a = a.re := by
  

Proof state:
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
⊢ a ^ 2 = ↑(normSq a) ↔ a = ↑a.re

Next tactic:
rw [← star_eq_self, ← star_mul_self, sq, mul_eq_mul_right_iff, eq_comm]
theorem sq_eq_normSq : a ^ 2 = normSq a ↔ a = a.re := by
  rw [← star_eq_self, ← star_mul_self, sq, mul_eq_mul_right_iff, eq_comm]
  

Proof state:
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
⊢ star a = a ∨ a = 0 ↔ star a = a

Next tactic:
exact or_iff_left_of_imp fun ha ↦ ha.symm ▸ star_zero _
theorem sq_eq_neg_normSq : a ^ 2 = -normSq a ↔ a.re = 0 := by
  

Proof state:
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
⊢ a ^ 2 = -↑(normSq a) ↔ a.re = 0

Next tactic:
simp_rw [← star_eq_neg]
theorem sq_eq_neg_normSq : a ^ 2 = -normSq a ↔ a.re = 0 := by
  simp_rw [← star_eq_neg]
  

Proof state:
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
⊢ a ^ 2 = -↑(normSq a) ↔ star a = -a

Next tactic:
obtain rfl | hq0 := eq_or_ne a 0
theorem sq_eq_neg_normSq : a ^ 2 = -normSq a ↔ a.re = 0 := by
  simp_rw [← star_eq_neg]
  obtain rfl | hq0 := eq_or_ne a 0
  · 

Proof state:
case inl
R : Type u_1
inst✝ : LinearOrderedCommRing R
⊢ 0 ^ 2 = -↑(normSq 0) ↔ star 0 = -0

Next tactic:
simp
theorem sq_eq_neg_normSq : a ^ 2 = -normSq a ↔ a.re = 0 := by
  simp_rw [← star_eq_neg]
  obtain rfl | hq0 := eq_or_ne a 0
  · simp
  · 

Proof state:
case inr
R : Type u_1
inst✝ : LinearOrderedCommRing R
a : ℍ[R]
hq0 : a ≠ 0
⊢ a ^ 2 = -↑(normSq a) ↔ star a = -a

Next tactic:
rw [← star_mul_self, ← mul_neg, ← neg_sq, sq, mul_left_inj' (neg_ne_zero.mpr hq0), eq_comm]
instance instGroupWithZero : GroupWithZero ℍ[R] :=
  { Quaternion.instNontrivial,
    (by 

Proof state:
R : Type u_1
inst✝ : LinearOrderedField R
a b : ℍ[R]
src✝ : Nontrivial ℍ[R] := instNontrivial
⊢ MonoidWithZero ℍ[R]

Next tactic:
infer_instance
instance instGroupWithZero : GroupWithZero ℍ[R] :=
  { Quaternion.instNontrivial,
    (by infer_instance : MonoidWithZero ℍ[R]) with
    inv := Inv.inv
    inv_zero := by 

Proof state:
R : Type u_1
inst✝ : LinearOrderedField R
a b : ℍ[R]
src✝¹ : Nontrivial ℍ[R] := instNontrivial
src✝ : MonoidWithZero ℍ[R] := inferInstance
⊢ 0⁻¹ = 0

Next tactic:
rw [instInv_inv, star_zero, smul_zero]
instance instGroupWithZero : GroupWithZero ℍ[R] :=
  { Quaternion.instNontrivial,
    (by infer_instance : MonoidWithZero ℍ[R]) with
    inv := Inv.inv
    inv_zero := by rw [instInv_inv, star_zero, smul_zero]
    mul_inv_cancel := fun a ha => by
      -- porting note: the aliased definition confuse TC search
      

Proof state:
R : Type u_1
inst✝ : LinearOrderedField R
a✝ b : ℍ[R]
src✝¹ : Nontrivial ℍ[R] := instNontrivial
src✝ : MonoidWithZero ℍ[R] := inferInstance
a : ℍ[R]
ha : a ≠ 0
⊢ a * a⁻¹ = 1

Next tactic:
letI : Semiring ℍ[R] := inferInstanceAs (Semiring ℍ[R,-1,-1])
instance instGroupWithZero : GroupWithZero ℍ[R] :=
  { Quaternion.instNontrivial,
    (by infer_instance : MonoidWithZero ℍ[R]) with
    inv := Inv.inv
    inv_zero := by rw [instInv_inv, star_zero, smul_zero]
    mul_inv_cancel := fun a ha => by
      -- porting note: the aliased definition confuse TC search
      letI : Semiring ℍ[R] := inferInstanceAs (Semiring ℍ[R,-1,-1])
      

Proof state:
R : Type u_1
inst✝ : LinearOrderedField R
a✝ b : ℍ[R]
src✝¹ : Nontrivial ℍ[R] := instNontrivial
src✝ : MonoidWithZero ℍ[R] := inferInstance
a : ℍ[R]
ha : a ≠ 0
this : Semiring ℍ[R] := inferInstanceAs (Semiring ℍ[R,-1,-1])
⊢ a * a⁻¹ = 1

Next tactic:
rw [instInv_inv, Algebra.mul_smul_comm (normSq a)⁻¹ a (star a), self_mul_star, smul_coe,
        inv_mul_cancel (normSq_ne_zero.2 ha), coe_one]
instance : DivisionRing ℍ[R] :=
  { Quaternion.instGroupWithZero,
    Quaternion.instRing with
    ratCast_mk := fun n d hd h => by
      

Proof state:
R : Type u_1
inst✝ : LinearOrderedField R
a b : ℍ[R]
src✝¹ : GroupWithZero ℍ[R] := instGroupWithZero
src✝ : Ring ℍ[R] := instRing
n : ℤ
d : ℕ
hd : d ≠ 0
h : Nat.Coprime (Int.natAbs n) d
⊢ ↑(Rat.mk' n d) = ↑n * (↑d)⁻¹

Next tactic:
rw [← coe_rat_cast, Rat.cast_mk', coe_mul, coe_int_cast, coe_inv, coe_nat_cast]
instance : DivisionRing ℍ[R] :=
  { Quaternion.instGroupWithZero,
    Quaternion.instRing with
    ratCast_mk := fun n d hd h => by
      rw [← coe_rat_cast, Rat.cast_mk', coe_mul, coe_int_cast, coe_inv, coe_nat_cast]
    qsmul := (· • ·)
    qsmul_eq_mul' := fun q x => by
      

Proof state:
R : Type u_1
inst✝ : LinearOrderedField R
a b : ℍ[R]
src✝¹ : GroupWithZero ℍ[R] := instGroupWithZero
src✝ : Ring ℍ[R] := instRing
q : ℚ
x : ℍ[R]
⊢ (fun x x_1 => x • x_1) q x = ↑q * x

Next tactic:
rw [← coe_rat_cast, coe_mul_eq_smul]
instance : DivisionRing ℍ[R] :=
  { Quaternion.instGroupWithZero,
    Quaternion.instRing with
    ratCast_mk := fun n d hd h => by
      rw [← coe_rat_cast, Rat.cast_mk', coe_mul, coe_int_cast, coe_inv, coe_nat_cast]
    qsmul := (· • ·)
    qsmul_eq_mul' := fun q x => by
      rw [← coe_rat_cast, coe_mul_eq_smul]
      

Proof state:
R : Type u_1
inst✝ : LinearOrderedField R
a b : ℍ[R]
src✝¹ : GroupWithZero ℍ[R] := instGroupWithZero
src✝ : Ring ℍ[R] := instRing
q : ℚ
x : ℍ[R]
⊢ (fun x x_1 => x • x_1) q x = ↑q • x

Next tactic:
ext
instance : DivisionRing ℍ[R] :=
  { Quaternion.instGroupWithZero,
    Quaternion.instRing with
    ratCast_mk := fun n d hd h => by
      rw [← coe_rat_cast, Rat.cast_mk', coe_mul, coe_int_cast, coe_inv, coe_nat_cast]
    qsmul := (· • ·)
    qsmul_eq_mul' := fun q x => by
      rw [← coe_rat_cast, coe_mul_eq_smul]
      ext <;> 

Proof state:
case a
R : Type u_1
inst✝ : LinearOrderedField R
a b : ℍ[R]
src✝¹ : GroupWithZero ℍ[R] := instGroupWithZero
src✝ : Ring ℍ[R] := instRing
q : ℚ
x : ℍ[R]
⊢ ((fun x x_1 => x • x_1) q x).re = (↑q • x).re

Next tactic:
exact DivisionRing.qsmul_eq_mul' _ _
instance : DivisionRing ℍ[R] :=
  { Quaternion.instGroupWithZero,
    Quaternion.instRing with
    ratCast_mk := fun n d hd h => by
      rw [← coe_rat_cast, Rat.cast_mk', coe_mul, coe_int_cast, coe_inv, coe_nat_cast]
    qsmul := (· • ·)
    qsmul_eq_mul' := fun q x => by
      rw [← coe_rat_cast, coe_mul_eq_smul]
      ext <;> 

Proof state:
case a
R : Type u_1
inst✝ : LinearOrderedField R
a b : ℍ[R]
src✝¹ : GroupWithZero ℍ[R] := instGroupWithZero
src✝ : Ring ℍ[R] := instRing
q : ℚ
x : ℍ[R]
⊢ ((fun x x_1 => x • x_1) q x).imI = (↑q • x).imI

Next tactic:
exact DivisionRing.qsmul_eq_mul' _ _
instance : DivisionRing ℍ[R] :=
  { Quaternion.instGroupWithZero,
    Quaternion.instRing with
    ratCast_mk := fun n d hd h => by
      rw [← coe_rat_cast, Rat.cast_mk', coe_mul, coe_int_cast, coe_inv, coe_nat_cast]
    qsmul := (· • ·)
    qsmul_eq_mul' := fun q x => by
      rw [← coe_rat_cast, coe_mul_eq_smul]
      ext <;> 

Proof state:
case a
R : Type u_1
inst✝ : LinearOrderedField R
a b : ℍ[R]
src✝¹ : GroupWithZero ℍ[R] := instGroupWithZero
src✝ : Ring ℍ[R] := instRing
q : ℚ
x : ℍ[R]
⊢ ((fun x x_1 => x • x_1) q x).imJ = (↑q • x).imJ

Next tactic:
exact DivisionRing.qsmul_eq_mul' _ _
instance : DivisionRing ℍ[R] :=
  { Quaternion.instGroupWithZero,
    Quaternion.instRing with
    ratCast_mk := fun n d hd h => by
      rw [← coe_rat_cast, Rat.cast_mk', coe_mul, coe_int_cast, coe_inv, coe_nat_cast]
    qsmul := (· • ·)
    qsmul_eq_mul' := fun q x => by
      rw [← coe_rat_cast, coe_mul_eq_smul]
      ext <;> 

Proof state:
case a
R : Type u_1
inst✝ : LinearOrderedField R
a b : ℍ[R]
src✝¹ : GroupWithZero ℍ[R] := instGroupWithZero
src✝ : Ring ℍ[R] := instRing
q : ℚ
x : ℍ[R]
⊢ ((fun x x_1 => x • x_1) q x).imK = (↑q • x).imK

Next tactic:
exact DivisionRing.qsmul_eq_mul' _ _
@[norm_cast]
theorem normSq_rat_cast (q : ℚ) : normSq (q : ℍ[R]) = (q : ℍ[R]) ^ 2 := by
  

Proof state:
R : Type u_1
inst✝ : LinearOrderedField R
a b : ℍ[R]
q : ℚ
⊢ ↑(normSq ↑q) = ↑q ^ 2

Next tactic:
rw [← coe_rat_cast, normSq_coe, coe_pow]
private theorem pow_four [Infinite R] : #R ^ 4 = #R :=
  power_nat_eq (aleph0_le_mk R) <| by 

Proof state:
R : Type u_1
c₁ c₂ : R
inst✝ : Infinite R
⊢ 1 ≤ 4

Next tactic:
decide
/-- The cardinality of a quaternion algebra, as a type. -/
theorem mk_quaternionAlgebra : #(ℍ[R,c₁,c₂]) = #R ^ 4 := by
  

Proof state:
R : Type u_1
c₁ c₂ : R
⊢ #ℍ[R,c₁,c₂] = #R ^ 4

Next tactic:
rw [mk_congr (QuaternionAlgebra.equivProd c₁ c₂)]
/-- The cardinality of a quaternion algebra, as a type. -/
theorem mk_quaternionAlgebra : #(ℍ[R,c₁,c₂]) = #R ^ 4 := by
  rw [mk_congr (QuaternionAlgebra.equivProd c₁ c₂)]
  

Proof state:
R : Type u_1
c₁ c₂ : R
⊢ #(R × R × R × R) = #R ^ 4

Next tactic:
simp only [mk_prod, lift_id]
/-- The cardinality of a quaternion algebra, as a type. -/
theorem mk_quaternionAlgebra : #(ℍ[R,c₁,c₂]) = #R ^ 4 := by
  rw [mk_congr (QuaternionAlgebra.equivProd c₁ c₂)]
  simp only [mk_prod, lift_id]
  

Proof state:
R : Type u_1
c₁ c₂ : R
⊢ #R * (#R * (#R * #R)) = #R ^ 4

Next tactic:
ring
@[simp]
theorem mk_quaternionAlgebra_of_infinite [Infinite R] : #(ℍ[R,c₁,c₂]) = #R := by
  

Proof state:
R : Type u_1
c₁ c₂ : R
inst✝ : Infinite R
⊢ #ℍ[R,c₁,c₂] = #R

Next tactic:
rw [mk_quaternionAlgebra, pow_four]
/-- The cardinality of a quaternion algebra, as a set. -/
theorem mk_univ_quaternionAlgebra : #(Set.univ : Set ℍ[R,c₁,c₂]) = #R ^ 4 := by
  

Proof state:
R : Type u_1
c₁ c₂ : R
⊢ #↑Set.univ = #R ^ 4

Next tactic:
rw [mk_univ, mk_quaternionAlgebra]
theorem mk_univ_quaternionAlgebra_of_infinite [Infinite R] :
    #(Set.univ : Set ℍ[R,c₁,c₂]) = #R := by 

Proof state:
R : Type u_1
c₁ c₂ : R
inst✝ : Infinite R
⊢ #↑Set.univ = #R

Next tactic:
rw [mk_univ_quaternionAlgebra, pow_four]
/-- The functor sending each quiver to its path category. -/
@[simps]
def free : Quiv.{v, u} ⥤ Cat.{max u v, u}
    where
  obj V := Cat.of (Paths V)
  map F :=
    { obj := fun X => F.obj X
      map := fun f => F.mapPath f
      map_comp := fun f g => F.mapPath_comp f g }
  map_id V := by
    

Proof state:
V : Quiv
⊢ { obj := fun V => of (Paths ↑V),
          map := fun {X Y} F =>
            Functor.mk { obj := fun X_1 => F.obj X_1, map := fun {X_1 Y_1} f => Prefunctor.mapPath F f } }.map
      (𝟙 V) =
    𝟙
      ({ obj := fun V => of (Paths ↑V),
            map := fun {X Y} F =>
              Functor.mk { obj := fun X_1 => F.obj X_1, map := fun {X_1 Y_1} f => Prefunctor.mapPath F f } }.obj
        V)

Next tactic:
change (show Paths V ⥤ _ from _) = _
/-- The functor sending each quiver to its path category. -/
@[simps]
def free : Quiv.{v, u} ⥤ Cat.{max u v, u}
    where
  obj V := Cat.of (Paths V)
  map F :=
    { obj := fun X => F.obj X
      map := fun f => F.mapPath f
      map_comp := fun f g => F.mapPath_comp f g }
  map_id V := by
    change (show Paths V ⥤ _ from _) = _
    

Proof state:
V : Quiv
⊢ (let_fun this :=
      { obj := fun V => of (Paths ↑V),
            map := fun {X Y} F =>
              Functor.mk { obj := fun X_1 => F.obj X_1, map := fun {X_1 Y_1} f => Prefunctor.mapPath F f } }.map
        (𝟙 V);
    this) =
    𝟙
      ({ obj := fun V => of (Paths ↑V),
            map := fun {X Y} F =>
              Functor.mk { obj := fun X_1 => F.obj X_1, map := fun {X_1 Y_1} f => Prefunctor.mapPath F f } }.obj
        V)

Next tactic:
ext