l3lab/ntp-mathlib huggingface dataset:
lemma isInt_ediv {a b q m a' : ℤ} {b' r : ℕ}
    (ha : IsInt a a') (hb : IsNat b b')
    (hm : q * b' = m) (h : r + m = a') (h₂ : Nat.blt r b' = true) :
    IsInt (a / b) q := ⟨by
  obtain ⟨⟨rfl⟩, ⟨rfl⟩⟩ := ha, hb
  simp only [Nat.blt_eq] at h₂; simp only [← h, ← hm, Int.cast_id]
  rw [Int.add_mul_ediv_right _ _ (Int.ofNat_ne_zero.2 ((Nat.zero_le ..).trans_lt h₂).ne')]
  rw [Int.ediv_eq_zero_of_lt, zero_add] <;> [simp; 

Proof state:
case mk.mk.H2
a q m : ℤ
b' r : ℕ
hm : q * ↑b' = m
h : ↑r + m = a
h₂ : r < b'
⊢ ↑r < ↑b'

Next tactic:
simpa using h₂
lemma isInt_ediv_neg {a b q : ℤ} (h : IsInt (a / -b) q) (hq : -q = q') : IsInt (a / b) q' :=
  ⟨by 

Proof state:
q' a b q : ℤ
h : IsInt (a / -b) q
hq : -q = q'
⊢ a / b = ↑q'

Next tactic:
rw [Int.cast_id, ← hq, ← @Int.cast_id q, ← h.out, ← Int.ediv_neg, Int.neg_neg]
lemma isNat_neg_of_isNegNat {a : ℤ} {b : ℕ} (h : IsInt a (.negOfNat b)) : IsNat (-a) b :=
  ⟨by 

Proof state:
a : ℤ
b : ℕ
h : IsInt a (Int.negOfNat b)
⊢ -a = ↑b

Next tactic:
simp [h.out]
lemma isInt_emod_zero : ∀ {a b r : ℤ}, IsInt a r → IsNat b (nat_lit 0) → IsInt (a % b) r
  | _, _, _, e, ⟨rfl⟩ => by 

Proof state:
x✝¹ x✝ : ℤ
e : IsInt x✝¹ x✝
⊢ IsInt (x✝¹ % ↑0) x✝

Next tactic:
simp [e]
lemma isInt_emod {a b q m a' : ℤ} {b' r : ℕ}
    (ha : IsInt a a') (hb : IsNat b b')
    (hm : q * b' = m) (h : r + m = a') (h₂ : Nat.blt r b' = true) :
    IsNat (a % b) r := ⟨by
  

Proof state:
a b q m a' : ℤ
b' r : ℕ
ha : IsInt a a'
hb : IsNat b b'
hm : q * ↑b' = m
h : ↑r + m = a'
h₂ : Nat.blt r b' = true
⊢ a % b = ↑r

Next tactic:
obtain ⟨⟨rfl⟩, ⟨rfl⟩⟩ := ha, hb
lemma isInt_emod {a b q m a' : ℤ} {b' r : ℕ}
    (ha : IsInt a a') (hb : IsNat b b')
    (hm : q * b' = m) (h : r + m = a') (h₂ : Nat.blt r b' = true) :
    IsNat (a % b) r := ⟨by
  obtain ⟨⟨rfl⟩, ⟨rfl⟩⟩ := ha, hb
  

Proof state:
case mk.mk
a q m : ℤ
b' r : ℕ
hm : q * ↑b' = m
h₂ : Nat.blt r b' = true
h : ↑r + m = a
⊢ a % ↑b' = ↑r

Next tactic:
simp only [← h, ← hm, Int.add_mul_emod_self]
lemma isInt_emod {a b q m a' : ℤ} {b' r : ℕ}
    (ha : IsInt a a') (hb : IsNat b b')
    (hm : q * b' = m) (h : r + m = a') (h₂ : Nat.blt r b' = true) :
    IsNat (a % b) r := ⟨by
  obtain ⟨⟨rfl⟩, ⟨rfl⟩⟩ := ha, hb
  simp only [← h, ← hm, Int.add_mul_emod_self]
  

Proof state:
case mk.mk
a q m : ℤ
b' r : ℕ
hm : q * ↑b' = m
h₂ : Nat.blt r b' = true
h : ↑r + m = a
⊢ ↑r % ↑b' = ↑r

Next tactic:
rw [Int.emod_eq_of_lt] <;> [simp; simpa using h₂]
lemma isInt_emod {a b q m a' : ℤ} {b' r : ℕ}
    (ha : IsInt a a') (hb : IsNat b b')
    (hm : q * b' = m) (h : r + m = a') (h₂ : Nat.blt r b' = true) :
    IsNat (a % b) r := ⟨by
  obtain ⟨⟨rfl⟩, ⟨rfl⟩⟩ := ha, hb
  simp only [← h, ← hm, Int.add_mul_emod_self]
  

Proof state:
case mk.mk
a q m : ℤ
b' r : ℕ
hm : q * ↑b' = m
h₂ : Nat.blt r b' = true
h : ↑r + m = a
⊢ ↑r % ↑b' = ↑r

Next tactic:
rw [Int.emod_eq_of_lt]
lemma isInt_emod {a b q m a' : ℤ} {b' r : ℕ}
    (ha : IsInt a a') (hb : IsNat b b')
    (hm : q * b' = m) (h : r + m = a') (h₂ : Nat.blt r b' = true) :
    IsNat (a % b) r := ⟨by
  obtain ⟨⟨rfl⟩, ⟨rfl⟩⟩ := ha, hb
  simp only [← h, ← hm, Int.add_mul_emod_self]
  rw [Int.emod_eq_of_lt] <;> [

Proof state:
case mk.mk.H1
a q m : ℤ
b' r : ℕ
hm : q * ↑b' = m
h₂ : Nat.blt r b' = true
h : ↑r + m = a
⊢ 0 ≤ ↑r

Next tactic:
simp
lemma isInt_emod {a b q m a' : ℤ} {b' r : ℕ}
    (ha : IsInt a a') (hb : IsNat b b')
    (hm : q * b' = m) (h : r + m = a') (h₂ : Nat.blt r b' = true) :
    IsNat (a % b) r := ⟨by
  obtain ⟨⟨rfl⟩, ⟨rfl⟩⟩ := ha, hb
  simp only [← h, ← hm, Int.add_mul_emod_self]
  rw [Int.emod_eq_of_lt] <;> [simp; 

Proof state:
case mk.mk.H2
a q m : ℤ
b' r : ℕ
hm : q * ↑b' = m
h₂ : Nat.blt r b' = true
h : ↑r + m = a
⊢ ↑r < ↑b'

Next tactic:
simpa using h₂
lemma isInt_emod_neg {a b : ℤ} {r : ℕ} (h : IsNat (a % -b) r) : IsNat (a % b) r :=
  ⟨by 

Proof state:
a b : ℤ
r : ℕ
h : IsNat (a % -b) r
⊢ a % b = ↑r

Next tactic:
rw [← Int.emod_neg, h.out]
theorem isInt_dvd_false : {a b : ℤ} → {a' b' : ℤ} →
    IsInt a a' → IsInt b b' → Int.mod b' a' != 0 → ¬a ∣ b
  | _, _, _, _, ⟨rfl⟩, ⟨rfl⟩, e => mt Int.mod_eq_zero_of_dvd (by 

Proof state:
n✝¹ n✝ : ℤ
e : (Int.mod n✝ n✝¹ != 0) = true
⊢ ¬Int.mod ↑n✝ ↑n✝¹ = 0

Next tactic:
simpa using e
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    

Proof state:
n : ℕ
⊢ ∀ (a b c : QuaternionGroup n), a * b * c = a * (b * c)

Next tactic:
rintro (i | i) (j | j) (k | k)
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> 

Proof state:
case a.a.a
n : ℕ
i j k : ZMod (2 * n)
⊢ a i * a j * a k = a i * (a j * a k)

Next tactic:
simp only [(· * ·), mul]
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> 

Proof state:
case a.a.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ a i * a j * xa k = a i * (a j * xa k)

Next tactic:
simp only [(· * ·), mul]
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> 

Proof state:
case a.xa.a
n : ℕ
i j k : ZMod (2 * n)
⊢ a i * xa j * a k = a i * (xa j * a k)

Next tactic:
simp only [(· * ·), mul]
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> 

Proof state:
case a.xa.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ a i * xa j * xa k = a i * (xa j * xa k)

Next tactic:
simp only [(· * ·), mul]
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> 

Proof state:
case xa.a.a
n : ℕ
i j k : ZMod (2 * n)
⊢ xa i * a j * a k = xa i * (a j * a k)

Next tactic:
simp only [(· * ·), mul]
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> 

Proof state:
case xa.a.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ xa i * a j * xa k = xa i * (a j * xa k)

Next tactic:
simp only [(· * ·), mul]
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> 

Proof state:
case xa.xa.a
n : ℕ
i j k : ZMod (2 * n)
⊢ xa i * xa j * a k = xa i * (xa j * a k)

Next tactic:
simp only [(· * ·), mul]
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> 

Proof state:
case xa.xa.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ xa i * xa j * xa k = xa i * (xa j * xa k)

Next tactic:
simp only [(· * ·), mul]
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> 

Proof state:
case a.a.a
n : ℕ
i j k : ZMod (2 * n)
⊢ a (i + j + k) = a (i + (j + k))

Next tactic:
ring_nf
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> 

Proof state:
case a.a.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ xa (k - (i + j)) = xa (k - j - i)

Next tactic:
ring_nf
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> 

Proof state:
case a.xa.a
n : ℕ
i j k : ZMod (2 * n)
⊢ xa (j - i + k) = xa (j + k - i)

Next tactic:
ring_nf
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> 

Proof state:
case a.xa.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ a (↑n + k - (j - i)) = a (i + (↑n + k - j))

Next tactic:
ring_nf
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> 

Proof state:
case xa.a.a
n : ℕ
i j k : ZMod (2 * n)
⊢ xa (i + j + k) = xa (i + (j + k))

Next tactic:
ring_nf
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> 

Proof state:
case xa.a.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ a (↑n + k - (i + j)) = a (↑n + (k - j) - i)

Next tactic:
ring_nf
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> 

Proof state:
case xa.xa.a
n : ℕ
i j k : ZMod (2 * n)
⊢ a (↑n + j - i + k) = a (↑n + (j + k) - i)

Next tactic:
ring_nf
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> 

Proof state:
case xa.xa.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ xa (k - (↑n + j - i)) = xa (i + (↑n + k - j))

Next tactic:
ring_nf
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> ring_nf
    

Proof state:
case xa.xa.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ xa (k + (-↑n - j) + i) = xa (k + (↑n - j) + i)

Next tactic:
congr
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> ring_nf
    congr
    

Proof state:
case xa.xa.xa.e_a.e_a.e_a.e_a
n : ℕ
i j k : ZMod (2 * n)
⊢ -↑n = ↑n

Next tactic:
calc
      -(n : ZMod (2 * n)) = 0 - n := by rw [zero_sub]
      _ = 2 * n - n := by norm_cast; simp
      _ = n := by ring
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> ring_nf
    congr
    calc
      -(n : ZMod (2 * n)) = 0 - n := by 

Proof state:
n : ℕ
i j k : ZMod (2 * n)
⊢ -↑n = 0 - ↑n

Next tactic:
rw [zero_sub]
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> ring_nf
    congr
    calc
      -(n : ZMod (2 * n)) = 0 - n := by rw [zero_sub]
      _ = 2 * n - n := by 

Proof state:
n : ℕ
i j k : ZMod (2 * n)
⊢ 0 - ↑n = 2 * ↑n - ↑n

Next tactic:
norm_cast
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> ring_nf
    congr
    calc
      -(n : ZMod (2 * n)) = 0 - n := by rw [zero_sub]
      _ = 2 * n - n := by norm_cast; 

Proof state:
n : ℕ
i j k : ZMod (2 * n)
⊢ ↑(Int.subNatNat 0 n) = ↑(Int.subNatNat (2 * n) n)

Next tactic:
simp
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> ring_nf
    congr
    calc
      -(n : ZMod (2 * n)) = 0 - n := by rw [zero_sub]
      _ = 2 * n - n := by norm_cast; simp
      _ = n := by 

Proof state:
n : ℕ
i j k : ZMod (2 * n)
⊢ 2 * ↑n - ↑n = ↑n

Next tactic:
ring
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> ring_nf
    congr
    calc
      -(n : ZMod (2 * n)) = 0 - n := by rw [zero_sub]
      _ = 2 * n - n := by norm_cast; simp
      _ = n := by ring
  one := one
  one_mul := by
    

Proof state:
n : ℕ
⊢ ∀ (a : QuaternionGroup n), 1 * a = a

Next tactic:
rintro (i | i)
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> ring_nf
    congr
    calc
      -(n : ZMod (2 * n)) = 0 - n := by rw [zero_sub]
      _ = 2 * n - n := by norm_cast; simp
      _ = n := by ring
  one := one
  one_mul := by
    rintro (i | i)
    · 

Proof state:
case a
n : ℕ
i : ZMod (2 * n)
⊢ 1 * a i = a i

Next tactic:
exact congr_arg a (zero_add i)
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> ring_nf
    congr
    calc
      -(n : ZMod (2 * n)) = 0 - n := by rw [zero_sub]
      _ = 2 * n - n := by norm_cast; simp
      _ = n := by ring
  one := one
  one_mul := by
    rintro (i | i)
    · exact congr_arg a (zero_add i)
    · 

Proof state:
case xa
n : ℕ
i : ZMod (2 * n)
⊢ 1 * xa i = xa i

Next tactic:
exact congr_arg xa (sub_zero i)
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> ring_nf
    congr
    calc
      -(n : ZMod (2 * n)) = 0 - n := by rw [zero_sub]
      _ = 2 * n - n := by norm_cast; simp
      _ = n := by ring
  one := one
  one_mul := by
    rintro (i | i)
    · exact congr_arg a (zero_add i)
    · exact congr_arg xa (sub_zero i)
  mul_one := by
    

Proof state:
n : ℕ
⊢ ∀ (a : QuaternionGroup n), a * 1 = a

Next tactic:
rintro (i | i)
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> ring_nf
    congr
    calc
      -(n : ZMod (2 * n)) = 0 - n := by rw [zero_sub]
      _ = 2 * n - n := by norm_cast; simp
      _ = n := by ring
  one := one
  one_mul := by
    rintro (i | i)
    · exact congr_arg a (zero_add i)
    · exact congr_arg xa (sub_zero i)
  mul_one := by
    rintro (i | i)
    · 

Proof state:
case a
n : ℕ
i : ZMod (2 * n)
⊢ a i * 1 = a i

Next tactic:
exact congr_arg a (add_zero i)
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> ring_nf
    congr
    calc
      -(n : ZMod (2 * n)) = 0 - n := by rw [zero_sub]
      _ = 2 * n - n := by norm_cast; simp
      _ = n := by ring
  one := one
  one_mul := by
    rintro (i | i)
    · exact congr_arg a (zero_add i)
    · exact congr_arg xa (sub_zero i)
  mul_one := by
    rintro (i | i)
    · exact congr_arg a (add_zero i)
    · 

Proof state:
case xa
n : ℕ
i : ZMod (2 * n)
⊢ xa i * 1 = xa i

Next tactic:
exact congr_arg xa (add_zero i)
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> ring_nf
    congr
    calc
      -(n : ZMod (2 * n)) = 0 - n := by rw [zero_sub]
      _ = 2 * n - n := by norm_cast; simp
      _ = n := by ring
  one := one
  one_mul := by
    rintro (i | i)
    · exact congr_arg a (zero_add i)
    · exact congr_arg xa (sub_zero i)
  mul_one := by
    rintro (i | i)
    · exact congr_arg a (add_zero i)
    · exact congr_arg xa (add_zero i)
  inv := inv
  mul_left_inv := by
    

Proof state:
n : ℕ
⊢ ∀ (a : QuaternionGroup n), a⁻¹ * a = 1

Next tactic:
rintro (i | i)
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> ring_nf
    congr
    calc
      -(n : ZMod (2 * n)) = 0 - n := by rw [zero_sub]
      _ = 2 * n - n := by norm_cast; simp
      _ = n := by ring
  one := one
  one_mul := by
    rintro (i | i)
    · exact congr_arg a (zero_add i)
    · exact congr_arg xa (sub_zero i)
  mul_one := by
    rintro (i | i)
    · exact congr_arg a (add_zero i)
    · exact congr_arg xa (add_zero i)
  inv := inv
  mul_left_inv := by
    rintro (i | i)
    · 

Proof state:
case a
n : ℕ
i : ZMod (2 * n)
⊢ (a i)⁻¹ * a i = 1

Next tactic:
exact congr_arg a (neg_add_self i)
/-- The group structure on `QuaternionGroup n`.
-/
instance : Group (QuaternionGroup n) where
  mul := mul
  mul_assoc := by
    rintro (i | i) (j | j) (k | k) <;> simp only [(· * ·), mul] <;> ring_nf
    congr
    calc
      -(n : ZMod (2 * n)) = 0 - n := by rw [zero_sub]
      _ = 2 * n - n := by norm_cast; simp
      _ = n := by ring
  one := one
  one_mul := by
    rintro (i | i)
    · exact congr_arg a (zero_add i)
    · exact congr_arg xa (sub_zero i)
  mul_one := by
    rintro (i | i)
    · exact congr_arg a (add_zero i)
    · exact congr_arg xa (add_zero i)
  inv := inv
  mul_left_inv := by
    rintro (i | i)
    · exact congr_arg a (neg_add_self i)
    · 

Proof state:
case xa
n : ℕ
i : ZMod (2 * n)
⊢ (xa i)⁻¹ * xa i = 1

Next tactic:
exact congr_arg a (sub_self (n + i))
private def fintypeHelper : Sum (ZMod (2 * n)) (ZMod (2 * n)) ≃ QuaternionGroup n where
  invFun i :=
    match i with
    | a j => Sum.inl j
    | xa j => Sum.inr j
  toFun i :=
    match i with
    | Sum.inl j => a j
    | Sum.inr j => xa j
  left_inv := by 

Proof state:
n : ℕ
⊢ Function.LeftInverse
    (fun i =>
      match i with
      | a j => Sum.inl j
      | xa j => Sum.inr j)
    fun i =>
    match i with
    | Sum.inl j => a j
    | Sum.inr j => xa j

Next tactic:
rintro (x | x)
private def fintypeHelper : Sum (ZMod (2 * n)) (ZMod (2 * n)) ≃ QuaternionGroup n where
  invFun i :=
    match i with
    | a j => Sum.inl j
    | xa j => Sum.inr j
  toFun i :=
    match i with
    | Sum.inl j => a j
    | Sum.inr j => xa j
  left_inv := by rintro (x | x) <;> 

Proof state:
case inl
n : ℕ
x : ZMod (2 * n)
⊢ (fun i =>
        match i with
        | a j => Sum.inl j
        | xa j => Sum.inr j)
      ((fun i =>
          match i with
          | Sum.inl j => a j
          | Sum.inr j => xa j)
        (Sum.inl x)) =
    Sum.inl x

Next tactic:
rfl
private def fintypeHelper : Sum (ZMod (2 * n)) (ZMod (2 * n)) ≃ QuaternionGroup n where
  invFun i :=
    match i with
    | a j => Sum.inl j
    | xa j => Sum.inr j
  toFun i :=
    match i with
    | Sum.inl j => a j
    | Sum.inr j => xa j
  left_inv := by rintro (x | x) <;> 

Proof state:
case inr
n : ℕ
x : ZMod (2 * n)
⊢ (fun i =>
        match i with
        | a j => Sum.inl j
        | xa j => Sum.inr j)
      ((fun i =>
          match i with
          | Sum.inl j => a j
          | Sum.inr j => xa j)
        (Sum.inr x)) =
    Sum.inr x

Next tactic:
rfl
private def fintypeHelper : Sum (ZMod (2 * n)) (ZMod (2 * n)) ≃ QuaternionGroup n where
  invFun i :=
    match i with
    | a j => Sum.inl j
    | xa j => Sum.inr j
  toFun i :=
    match i with
    | Sum.inl j => a j
    | Sum.inr j => xa j
  left_inv := by rintro (x | x) <;> rfl
  right_inv := by 

Proof state:
n : ℕ
⊢ Function.RightInverse
    (fun i =>
      match i with
      | a j => Sum.inl j
      | xa j => Sum.inr j)
    fun i =>
    match i with
    | Sum.inl j => a j
    | Sum.inr j => xa j

Next tactic:
rintro (x | x)
private def fintypeHelper : Sum (ZMod (2 * n)) (ZMod (2 * n)) ≃ QuaternionGroup n where
  invFun i :=
    match i with
    | a j => Sum.inl j
    | xa j => Sum.inr j
  toFun i :=
    match i with
    | Sum.inl j => a j
    | Sum.inr j => xa j
  left_inv := by rintro (x | x) <;> rfl
  right_inv := by rintro (x | x) <;> 

Proof state:
case a
n : ℕ
x : ZMod (2 * n)
⊢ (fun i =>
        match i with
        | Sum.inl j => a j
        | Sum.inr j => xa j)
      ((fun i =>
          match i with
          | a j => Sum.inl j
          | xa j => Sum.inr j)
        (a x)) =
    a x

Next tactic:
rfl
private def fintypeHelper : Sum (ZMod (2 * n)) (ZMod (2 * n)) ≃ QuaternionGroup n where
  invFun i :=
    match i with
    | a j => Sum.inl j
    | xa j => Sum.inr j
  toFun i :=
    match i with
    | Sum.inl j => a j
    | Sum.inr j => xa j
  left_inv := by rintro (x | x) <;> rfl
  right_inv := by rintro (x | x) <;> 

Proof state:
case xa
n : ℕ
x : ZMod (2 * n)
⊢ (fun i =>
        match i with
        | Sum.inl j => a j
        | Sum.inr j => xa j)
      ((fun i =>
          match i with
          | a j => Sum.inl j
          | xa j => Sum.inr j)
        (xa x)) =
    xa x

Next tactic:
rfl
/-- The special case that more or less by definition `QuaternionGroup 0` is isomorphic to the
infinite dihedral group. -/
def quaternionGroupZeroEquivDihedralGroupZero : QuaternionGroup 0 ≃* DihedralGroup 0 where
  toFun i :=
    -- Porting note: Originally `QuaternionGroup.recOn i DihedralGroup.r DihedralGroup.sr`
    match i with
    | a j => DihedralGroup.r j
    | xa j => DihedralGroup.sr j
  invFun i :=
    match i with
    | DihedralGroup.r j => a j
    | DihedralGroup.sr j => xa j
  left_inv := by 

Proof state:
n : ℕ
⊢ Function.LeftInverse
    (fun i =>
      match i with
      | DihedralGroup.r j => a j
      | DihedralGroup.sr j => xa j)
    fun i =>
    match i with
    | a j => DihedralGroup.r j
    | xa j => DihedralGroup.sr j

Next tactic:
rintro (k | k)
/-- The special case that more or less by definition `QuaternionGroup 0` is isomorphic to the
infinite dihedral group. -/
def quaternionGroupZeroEquivDihedralGroupZero : QuaternionGroup 0 ≃* DihedralGroup 0 where
  toFun i :=
    -- Porting note: Originally `QuaternionGroup.recOn i DihedralGroup.r DihedralGroup.sr`
    match i with
    | a j => DihedralGroup.r j
    | xa j => DihedralGroup.sr j
  invFun i :=
    match i with
    | DihedralGroup.r j => a j
    | DihedralGroup.sr j => xa j
  left_inv := by rintro (k | k) <;> 

Proof state:
case a
n : ℕ
k : ZMod (2 * 0)
⊢ (fun i =>
        match i with
        | DihedralGroup.r j => a j
        | DihedralGroup.sr j => xa j)
      ((fun i =>
          match i with
          | a j => DihedralGroup.r j
          | xa j => DihedralGroup.sr j)
        (a k)) =
    a k

Next tactic:
rfl
/-- The special case that more or less by definition `QuaternionGroup 0` is isomorphic to the
infinite dihedral group. -/
def quaternionGroupZeroEquivDihedralGroupZero : QuaternionGroup 0 ≃* DihedralGroup 0 where
  toFun i :=
    -- Porting note: Originally `QuaternionGroup.recOn i DihedralGroup.r DihedralGroup.sr`
    match i with
    | a j => DihedralGroup.r j
    | xa j => DihedralGroup.sr j
  invFun i :=
    match i with
    | DihedralGroup.r j => a j
    | DihedralGroup.sr j => xa j
  left_inv := by rintro (k | k) <;> 

Proof state:
case xa
n : ℕ
k : ZMod (2 * 0)
⊢ (fun i =>
        match i with
        | DihedralGroup.r j => a j
        | DihedralGroup.sr j => xa j)
      ((fun i =>
          match i with
          | a j => DihedralGroup.r j
          | xa j => DihedralGroup.sr j)
        (xa k)) =
    xa k

Next tactic:
rfl
/-- The special case that more or less by definition `QuaternionGroup 0` is isomorphic to the
infinite dihedral group. -/
def quaternionGroupZeroEquivDihedralGroupZero : QuaternionGroup 0 ≃* DihedralGroup 0 where
  toFun i :=
    -- Porting note: Originally `QuaternionGroup.recOn i DihedralGroup.r DihedralGroup.sr`
    match i with
    | a j => DihedralGroup.r j
    | xa j => DihedralGroup.sr j
  invFun i :=
    match i with
    | DihedralGroup.r j => a j
    | DihedralGroup.sr j => xa j
  left_inv := by rintro (k | k) <;> rfl
  right_inv := by 

Proof state:
n : ℕ
⊢ Function.RightInverse
    (fun i =>
      match i with
      | DihedralGroup.r j => a j
      | DihedralGroup.sr j => xa j)
    fun i =>
    match i with
    | a j => DihedralGroup.r j
    | xa j => DihedralGroup.sr j

Next tactic:
rintro (k | k)