l3lab/ntp-mathlib huggingface dataset:
theorem sMod_mod (p i : ℕ) : sMod p i % (2 ^ p - 1) = sMod p i := by 

Proof state:
p i : ℕ
⊢ sMod p i % (2 ^ p - 1) = sMod p i

Next tactic:
cases i
theorem sMod_mod (p i : ℕ) : sMod p i % (2 ^ p - 1) = sMod p i := by cases i <;> 

Proof state:
case zero
p : ℕ
⊢ sMod p zero % (2 ^ p - 1) = sMod p zero

Next tactic:
simp [sMod]
theorem sMod_mod (p i : ℕ) : sMod p i % (2 ^ p - 1) = sMod p i := by cases i <;> 

Proof state:
case succ
p n✝ : ℕ
⊢ sMod p (succ n✝) % (2 ^ p - 1) = sMod p (succ n✝)

Next tactic:
simp [sMod]
theorem sMod_lt (p : ℕ) (hp : p ≠ 0) (i : ℕ) : sMod p i < 2 ^ p - 1 := by
  

Proof state:
p : ℕ
hp : p ≠ 0
i : ℕ
⊢ sMod p i < 2 ^ p - 1

Next tactic:
rw [← sMod_mod]
theorem sMod_lt (p : ℕ) (hp : p ≠ 0) (i : ℕ) : sMod p i < 2 ^ p - 1 := by
  rw [← sMod_mod]
  

Proof state:
p : ℕ
hp : p ≠ 0
i : ℕ
⊢ sMod p i % (2 ^ p - 1) < 2 ^ p - 1

Next tactic:
refine (Int.emod_lt _ (mersenne_int_ne_zero p hp)).trans_eq ?_
theorem sMod_lt (p : ℕ) (hp : p ≠ 0) (i : ℕ) : sMod p i < 2 ^ p - 1 := by
  rw [← sMod_mod]
  refine (Int.emod_lt _ (mersenne_int_ne_zero p hp)).trans_eq ?_
  

Proof state:
p : ℕ
hp : p ≠ 0
i : ℕ
⊢ |2 ^ p - 1| = 2 ^ p - 1

Next tactic:
exact abs_of_nonneg (mersenne_int_pos hp).le
theorem sZMod_eq_s (p' : ℕ) (i : ℕ) : sZMod (p' + 2) i = (s i : ZMod (2 ^ (p' + 2) - 1)) := by
  

Proof state:
p' i : ℕ
⊢ sZMod (p' + 2) i = ↑(s i)

Next tactic:
induction' i with i ih
theorem sZMod_eq_s (p' : ℕ) (i : ℕ) : sZMod (p' + 2) i = (s i : ZMod (2 ^ (p' + 2) - 1)) := by
  induction' i with i ih
  · 

Proof state:
case zero
p' : ℕ
⊢ sZMod (p' + 2) zero = ↑(s zero)

Next tactic:
dsimp [s, sZMod]
theorem sZMod_eq_s (p' : ℕ) (i : ℕ) : sZMod (p' + 2) i = (s i : ZMod (2 ^ (p' + 2) - 1)) := by
  induction' i with i ih
  · dsimp [s, sZMod]
    

Proof state:
case zero
p' : ℕ
⊢ 4 = ↑4

Next tactic:
norm_num
theorem sZMod_eq_s (p' : ℕ) (i : ℕ) : sZMod (p' + 2) i = (s i : ZMod (2 ^ (p' + 2) - 1)) := by
  induction' i with i ih
  · dsimp [s, sZMod]
    norm_num
  · 

Proof state:
case succ
p' i : ℕ
ih : sZMod (p' + 2) i = ↑(s i)
⊢ sZMod (p' + 2) (succ i) = ↑(s (succ i))

Next tactic:
push_cast [s, sZMod, ih]
theorem sZMod_eq_s (p' : ℕ) (i : ℕ) : sZMod (p' + 2) i = (s i : ZMod (2 ^ (p' + 2) - 1)) := by
  induction' i with i ih
  · dsimp [s, sZMod]
    norm_num
  · push_cast [s, sZMod, ih]; 

Proof state:
case succ
p' i : ℕ
ih : sZMod (p' + 2) i = ↑(s i)
⊢ ↑(s i) ^ 2 - 2 = ↑(s i) ^ 2 - 2

Next tactic:
rfl
theorem Int.coe_nat_pow_pred (b p : ℕ) (w : 0 < b) : ((b ^ p - 1 : ℕ) : ℤ) = (b : ℤ) ^ p - 1 := by
  

Proof state:
b p : ℕ
w : 0 < b
⊢ ↑(b ^ p - 1) = ↑b ^ p - 1

Next tactic:
have : 1 ≤ b ^ p := Nat.one_le_pow p b w
theorem Int.coe_nat_pow_pred (b p : ℕ) (w : 0 < b) : ((b ^ p - 1 : ℕ) : ℤ) = (b : ℤ) ^ p - 1 := by
  have : 1 ≤ b ^ p := Nat.one_le_pow p b w
  

Proof state:
b p : ℕ
w : 0 < b
this : 1 ≤ b ^ p
⊢ ↑(b ^ p - 1) = ↑b ^ p - 1

Next tactic:
norm_cast
theorem Int.coe_nat_two_pow_pred (p : ℕ) : ((2 ^ p - 1 : ℕ) : ℤ) = (2 ^ p - 1 : ℤ) :=
  Int.coe_nat_pow_pred 2 p (by 

Proof state:
p : ℕ
⊢ 0 < 2

Next tactic:
decide
theorem sZMod_eq_sMod (p : ℕ) (i : ℕ) : sZMod p i = (sMod p i : ZMod (2 ^ p - 1)) := by
  

Proof state:
p i : ℕ
⊢ sZMod p i = ↑(sMod p i)

Next tactic:
induction i
theorem sZMod_eq_sMod (p : ℕ) (i : ℕ) : sZMod p i = (sMod p i : ZMod (2 ^ p - 1)) := by
  induction i <;> 

Proof state:
case zero
p : ℕ
⊢ sZMod p zero = ↑(sMod p zero)

Next tactic:
push_cast [← Int.coe_nat_two_pow_pred p, sMod, sZMod, *]
theorem sZMod_eq_sMod (p : ℕ) (i : ℕ) : sZMod p i = (sMod p i : ZMod (2 ^ p - 1)) := by
  induction i <;> 

Proof state:
case succ
p n✝ : ℕ
n_ih✝ : sZMod p n✝ = ↑(sMod p n✝)
⊢ sZMod p (succ n✝) = ↑(sMod p (succ n✝))

Next tactic:
push_cast [← Int.coe_nat_two_pow_pred p, sMod, sZMod, *]
theorem sZMod_eq_sMod (p : ℕ) (i : ℕ) : sZMod p i = (sMod p i : ZMod (2 ^ p - 1)) := by
  induction i <;> push_cast [← Int.coe_nat_two_pow_pred p, sMod, sZMod, *] <;> 

Proof state:
case zero
p : ℕ
⊢ 4 = 4

Next tactic:
rfl
theorem sZMod_eq_sMod (p : ℕ) (i : ℕ) : sZMod p i = (sMod p i : ZMod (2 ^ p - 1)) := by
  induction i <;> push_cast [← Int.coe_nat_two_pow_pred p, sMod, sZMod, *] <;> 

Proof state:
case succ
p n✝ : ℕ
n_ih✝ : sZMod p n✝ = ↑(sMod p n✝)
⊢ ↑(sMod p n✝) ^ 2 - 2 = ↑(sMod p n✝) ^ 2 - 2

Next tactic:
rfl
theorem residue_eq_zero_iff_sMod_eq_zero (p : ℕ) (w : 1 < p) :
    lucasLehmerResidue p = 0 ↔ sMod p (p - 2) = 0 := by
  

Proof state:
p : ℕ
w : 1 < p
⊢ lucasLehmerResidue p = 0 ↔ sMod p (p - 2) = 0

Next tactic:
dsimp [lucasLehmerResidue]
theorem residue_eq_zero_iff_sMod_eq_zero (p : ℕ) (w : 1 < p) :
    lucasLehmerResidue p = 0 ↔ sMod p (p - 2) = 0 := by
  dsimp [lucasLehmerResidue]
  

Proof state:
p : ℕ
w : 1 < p
⊢ sZMod p (p - 2) = 0 ↔ sMod p (p - 2) = 0

Next tactic:
rw [sZMod_eq_sMod p]
theorem residue_eq_zero_iff_sMod_eq_zero (p : ℕ) (w : 1 < p) :
    lucasLehmerResidue p = 0 ↔ sMod p (p - 2) = 0 := by
  dsimp [lucasLehmerResidue]
  rw [sZMod_eq_sMod p]
  

Proof state:
p : ℕ
w : 1 < p
⊢ ↑(sMod p (p - 2)) = 0 ↔ sMod p (p - 2) = 0

Next tactic:
constructor
theorem residue_eq_zero_iff_sMod_eq_zero (p : ℕ) (w : 1 < p) :
    lucasLehmerResidue p = 0 ↔ sMod p (p - 2) = 0 := by
  dsimp [lucasLehmerResidue]
  rw [sZMod_eq_sMod p]
  constructor
  · -- We want to use that fact that `0 ≤ s_mod p (p-2) < 2^p - 1`
    -- and `lucas_lehmer_residue p = 0 → 2^p - 1 ∣ s_mod p (p-2)`.
    

Proof state:
case mp
p : ℕ
w : 1 < p
⊢ ↑(sMod p (p - 2)) = 0 → sMod p (p - 2) = 0

Next tactic:
intro h
theorem residue_eq_zero_iff_sMod_eq_zero (p : ℕ) (w : 1 < p) :
    lucasLehmerResidue p = 0 ↔ sMod p (p - 2) = 0 := by
  dsimp [lucasLehmerResidue]
  rw [sZMod_eq_sMod p]
  constructor
  · -- We want to use that fact that `0 ≤ s_mod p (p-2) < 2^p - 1`
    -- and `lucas_lehmer_residue p = 0 → 2^p - 1 ∣ s_mod p (p-2)`.
    intro h
    

Proof state:
case mp
p : ℕ
w : 1 < p
h : ↑(sMod p (p - 2)) = 0
⊢ sMod p (p - 2) = 0

Next tactic:
simp? [ZMod.int_cast_zmod_eq_zero_iff_dvd] at h says
      simp only [ge_iff_le, ZMod.int_cast_zmod_eq_zero_iff_dvd, gt_iff_lt, zero_lt_two, pow_pos,
        cast_pred, cast_pow, cast_ofNat] at h
theorem residue_eq_zero_iff_sMod_eq_zero (p : ℕ) (w : 1 < p) :
    lucasLehmerResidue p = 0 ↔ sMod p (p - 2) = 0 := by
  dsimp [lucasLehmerResidue]
  rw [sZMod_eq_sMod p]
  constructor
  · -- We want to use that fact that `0 ≤ s_mod p (p-2) < 2^p - 1`
    -- and `lucas_lehmer_residue p = 0 → 2^p - 1 ∣ s_mod p (p-2)`.
    intro h
    simp? [ZMod.int_cast_zmod_eq_zero_iff_dvd] at h says
      

Proof state:
case mp
p : ℕ
w : 1 < p
h : ↑(sMod p (p - 2)) = 0
⊢ sMod p (p - 2) = 0

Next tactic:
simp only [ge_iff_le, ZMod.int_cast_zmod_eq_zero_iff_dvd, gt_iff_lt, zero_lt_two, pow_pos,
        cast_pred, cast_pow, cast_ofNat] at h
theorem residue_eq_zero_iff_sMod_eq_zero (p : ℕ) (w : 1 < p) :
    lucasLehmerResidue p = 0 ↔ sMod p (p - 2) = 0 := by
  dsimp [lucasLehmerResidue]
  rw [sZMod_eq_sMod p]
  constructor
  · -- We want to use that fact that `0 ≤ s_mod p (p-2) < 2^p - 1`
    -- and `lucas_lehmer_residue p = 0 → 2^p - 1 ∣ s_mod p (p-2)`.
    intro h
    simp? [ZMod.int_cast_zmod_eq_zero_iff_dvd] at h says
      simp only [ge_iff_le, ZMod.int_cast_zmod_eq_zero_iff_dvd, gt_iff_lt, zero_lt_two, pow_pos,
        cast_pred, cast_pow, cast_ofNat] at h
    

Proof state:
case mp
p : ℕ
w : 1 < p
h : 2 ^ p - 1 ∣ sMod p (p - 2)
⊢ sMod p (p - 2) = 0

Next tactic:
apply Int.eq_zero_of_dvd_of_nonneg_of_lt _ _ h
theorem residue_eq_zero_iff_sMod_eq_zero (p : ℕ) (w : 1 < p) :
    lucasLehmerResidue p = 0 ↔ sMod p (p - 2) = 0 := by
  dsimp [lucasLehmerResidue]
  rw [sZMod_eq_sMod p]
  constructor
  · -- We want to use that fact that `0 ≤ s_mod p (p-2) < 2^p - 1`
    -- and `lucas_lehmer_residue p = 0 → 2^p - 1 ∣ s_mod p (p-2)`.
    intro h
    simp? [ZMod.int_cast_zmod_eq_zero_iff_dvd] at h says
      simp only [ge_iff_le, ZMod.int_cast_zmod_eq_zero_iff_dvd, gt_iff_lt, zero_lt_two, pow_pos,
        cast_pred, cast_pow, cast_ofNat] at h
    apply Int.eq_zero_of_dvd_of_nonneg_of_lt _ _ h <;> 

Proof state:
p : ℕ
w : 1 < p
h : 2 ^ p - 1 ∣ sMod p (p - 2)
⊢ 0 ≤ sMod p (p - 2)

Next tactic:
clear h
theorem residue_eq_zero_iff_sMod_eq_zero (p : ℕ) (w : 1 < p) :
    lucasLehmerResidue p = 0 ↔ sMod p (p - 2) = 0 := by
  dsimp [lucasLehmerResidue]
  rw [sZMod_eq_sMod p]
  constructor
  · -- We want to use that fact that `0 ≤ s_mod p (p-2) < 2^p - 1`
    -- and `lucas_lehmer_residue p = 0 → 2^p - 1 ∣ s_mod p (p-2)`.
    intro h
    simp? [ZMod.int_cast_zmod_eq_zero_iff_dvd] at h says
      simp only [ge_iff_le, ZMod.int_cast_zmod_eq_zero_iff_dvd, gt_iff_lt, zero_lt_two, pow_pos,
        cast_pred, cast_pow, cast_ofNat] at h
    apply Int.eq_zero_of_dvd_of_nonneg_of_lt _ _ h <;> 

Proof state:
p : ℕ
w : 1 < p
h : 2 ^ p - 1 ∣ sMod p (p - 2)
⊢ sMod p (p - 2) < 2 ^ p - 1

Next tactic:
clear h
theorem residue_eq_zero_iff_sMod_eq_zero (p : ℕ) (w : 1 < p) :
    lucasLehmerResidue p = 0 ↔ sMod p (p - 2) = 0 := by
  dsimp [lucasLehmerResidue]
  rw [sZMod_eq_sMod p]
  constructor
  · -- We want to use that fact that `0 ≤ s_mod p (p-2) < 2^p - 1`
    -- and `lucas_lehmer_residue p = 0 → 2^p - 1 ∣ s_mod p (p-2)`.
    intro h
    simp? [ZMod.int_cast_zmod_eq_zero_iff_dvd] at h says
      simp only [ge_iff_le, ZMod.int_cast_zmod_eq_zero_iff_dvd, gt_iff_lt, zero_lt_two, pow_pos,
        cast_pred, cast_pow, cast_ofNat] at h
    apply Int.eq_zero_of_dvd_of_nonneg_of_lt _ _ h <;> clear h
    · 

Proof state:
p : ℕ
w : 1 < p
⊢ 0 ≤ sMod p (p - 2)

Next tactic:
exact sMod_nonneg _ (by positivity) _
theorem residue_eq_zero_iff_sMod_eq_zero (p : ℕ) (w : 1 < p) :
    lucasLehmerResidue p = 0 ↔ sMod p (p - 2) = 0 := by
  dsimp [lucasLehmerResidue]
  rw [sZMod_eq_sMod p]
  constructor
  · -- We want to use that fact that `0 ≤ s_mod p (p-2) < 2^p - 1`
    -- and `lucas_lehmer_residue p = 0 → 2^p - 1 ∣ s_mod p (p-2)`.
    intro h
    simp? [ZMod.int_cast_zmod_eq_zero_iff_dvd] at h says
      simp only [ge_iff_le, ZMod.int_cast_zmod_eq_zero_iff_dvd, gt_iff_lt, zero_lt_two, pow_pos,
        cast_pred, cast_pow, cast_ofNat] at h
    apply Int.eq_zero_of_dvd_of_nonneg_of_lt _ _ h <;> clear h
    · exact sMod_nonneg _ (by 

Proof state:
p : ℕ
w : 1 < p
⊢ p ≠ 0

Next tactic:
positivity
theorem residue_eq_zero_iff_sMod_eq_zero (p : ℕ) (w : 1 < p) :
    lucasLehmerResidue p = 0 ↔ sMod p (p - 2) = 0 := by
  dsimp [lucasLehmerResidue]
  rw [sZMod_eq_sMod p]
  constructor
  · -- We want to use that fact that `0 ≤ s_mod p (p-2) < 2^p - 1`
    -- and `lucas_lehmer_residue p = 0 → 2^p - 1 ∣ s_mod p (p-2)`.
    intro h
    simp? [ZMod.int_cast_zmod_eq_zero_iff_dvd] at h says
      simp only [ge_iff_le, ZMod.int_cast_zmod_eq_zero_iff_dvd, gt_iff_lt, zero_lt_two, pow_pos,
        cast_pred, cast_pow, cast_ofNat] at h
    apply Int.eq_zero_of_dvd_of_nonneg_of_lt _ _ h <;> clear h
    · exact sMod_nonneg _ (by positivity) _
    · 

Proof state:
p : ℕ
w : 1 < p
⊢ sMod p (p - 2) < 2 ^ p - 1

Next tactic:
exact sMod_lt _ (by positivity) _
theorem residue_eq_zero_iff_sMod_eq_zero (p : ℕ) (w : 1 < p) :
    lucasLehmerResidue p = 0 ↔ sMod p (p - 2) = 0 := by
  dsimp [lucasLehmerResidue]
  rw [sZMod_eq_sMod p]
  constructor
  · -- We want to use that fact that `0 ≤ s_mod p (p-2) < 2^p - 1`
    -- and `lucas_lehmer_residue p = 0 → 2^p - 1 ∣ s_mod p (p-2)`.
    intro h
    simp? [ZMod.int_cast_zmod_eq_zero_iff_dvd] at h says
      simp only [ge_iff_le, ZMod.int_cast_zmod_eq_zero_iff_dvd, gt_iff_lt, zero_lt_two, pow_pos,
        cast_pred, cast_pow, cast_ofNat] at h
    apply Int.eq_zero_of_dvd_of_nonneg_of_lt _ _ h <;> clear h
    · exact sMod_nonneg _ (by positivity) _
    · exact sMod_lt _ (by 

Proof state:
p : ℕ
w : 1 < p
⊢ p ≠ 0

Next tactic:
positivity
theorem residue_eq_zero_iff_sMod_eq_zero (p : ℕ) (w : 1 < p) :
    lucasLehmerResidue p = 0 ↔ sMod p (p - 2) = 0 := by
  dsimp [lucasLehmerResidue]
  rw [sZMod_eq_sMod p]
  constructor
  · -- We want to use that fact that `0 ≤ s_mod p (p-2) < 2^p - 1`
    -- and `lucas_lehmer_residue p = 0 → 2^p - 1 ∣ s_mod p (p-2)`.
    intro h
    simp? [ZMod.int_cast_zmod_eq_zero_iff_dvd] at h says
      simp only [ge_iff_le, ZMod.int_cast_zmod_eq_zero_iff_dvd, gt_iff_lt, zero_lt_two, pow_pos,
        cast_pred, cast_pow, cast_ofNat] at h
    apply Int.eq_zero_of_dvd_of_nonneg_of_lt _ _ h <;> clear h
    · exact sMod_nonneg _ (by positivity) _
    · exact sMod_lt _ (by positivity) _
  · 

Proof state:
case mpr
p : ℕ
w : 1 < p
⊢ sMod p (p - 2) = 0 → ↑(sMod p (p - 2)) = 0

Next tactic:
intro h
theorem residue_eq_zero_iff_sMod_eq_zero (p : ℕ) (w : 1 < p) :
    lucasLehmerResidue p = 0 ↔ sMod p (p - 2) = 0 := by
  dsimp [lucasLehmerResidue]
  rw [sZMod_eq_sMod p]
  constructor
  · -- We want to use that fact that `0 ≤ s_mod p (p-2) < 2^p - 1`
    -- and `lucas_lehmer_residue p = 0 → 2^p - 1 ∣ s_mod p (p-2)`.
    intro h
    simp? [ZMod.int_cast_zmod_eq_zero_iff_dvd] at h says
      simp only [ge_iff_le, ZMod.int_cast_zmod_eq_zero_iff_dvd, gt_iff_lt, zero_lt_two, pow_pos,
        cast_pred, cast_pow, cast_ofNat] at h
    apply Int.eq_zero_of_dvd_of_nonneg_of_lt _ _ h <;> clear h
    · exact sMod_nonneg _ (by positivity) _
    · exact sMod_lt _ (by positivity) _
  · intro h
    

Proof state:
case mpr
p : ℕ
w : 1 < p
h : sMod p (p - 2) = 0
⊢ ↑(sMod p (p - 2)) = 0

Next tactic:
rw [h]
theorem residue_eq_zero_iff_sMod_eq_zero (p : ℕ) (w : 1 < p) :
    lucasLehmerResidue p = 0 ↔ sMod p (p - 2) = 0 := by
  dsimp [lucasLehmerResidue]
  rw [sZMod_eq_sMod p]
  constructor
  · -- We want to use that fact that `0 ≤ s_mod p (p-2) < 2^p - 1`
    -- and `lucas_lehmer_residue p = 0 → 2^p - 1 ∣ s_mod p (p-2)`.
    intro h
    simp? [ZMod.int_cast_zmod_eq_zero_iff_dvd] at h says
      simp only [ge_iff_le, ZMod.int_cast_zmod_eq_zero_iff_dvd, gt_iff_lt, zero_lt_two, pow_pos,
        cast_pred, cast_pow, cast_ofNat] at h
    apply Int.eq_zero_of_dvd_of_nonneg_of_lt _ _ h <;> clear h
    · exact sMod_nonneg _ (by positivity) _
    · exact sMod_lt _ (by positivity) _
  · intro h
    rw [h]
    

Proof state:
case mpr
p : ℕ
w : 1 < p
h : sMod p (p - 2) = 0
⊢ ↑0 = 0

Next tactic:
simp
@[ext]
theorem ext {x y : X q} (h₁ : x.1 = y.1) (h₂ : x.2 = y.2) : x = y := by
  

Proof state:
q : ℕ+
x y : X q
h₁ : x.1 = y.1
h₂ : x.2 = y.2
⊢ x = y

Next tactic:
cases x
@[ext]
theorem ext {x y : X q} (h₁ : x.1 = y.1) (h₂ : x.2 = y.2) : x = y := by
  cases x; 

Proof state:
case mk
q : ℕ+
y : X q
fst✝ snd✝ : ZMod ↑q
h₁ : (fst✝, snd✝).1 = y.1
h₂ : (fst✝, snd✝).2 = y.2
⊢ (fst✝, snd✝) = y

Next tactic:
cases y
@[ext]
theorem ext {x y : X q} (h₁ : x.1 = y.1) (h₂ : x.2 = y.2) : x = y := by
  cases x; cases y; 

Proof state:
case mk.mk
q : ℕ+
fst✝¹ snd✝¹ fst✝ snd✝ : ZMod ↑q
h₁ : (fst✝¹, snd✝¹).1 = (fst✝, snd✝).1
h₂ : (fst✝¹, snd✝¹).2 = (fst✝, snd✝).2
⊢ (fst✝¹, snd✝¹) = (fst✝, snd✝)

Next tactic:
congr
instance : Monoid (X q) :=
  { inferInstanceAs (Mul (X q)), inferInstanceAs (One (X q)) with
    mul_assoc := fun x y z => by 

Proof state:
q : ℕ+
src✝¹ : Mul (X q) := inferInstanceAs (Mul (X q))
src✝ : One (X q) := inferInstanceAs (One (X q))
x y z : X q
⊢ x * y * z = x * (y * z)

Next tactic:
ext
instance : Monoid (X q) :=
  { inferInstanceAs (Mul (X q)), inferInstanceAs (One (X q)) with
    mul_assoc := fun x y z => by ext <;> 

Proof state:
case h₁
q : ℕ+
src✝¹ : Mul (X q) := inferInstanceAs (Mul (X q))
src✝ : One (X q) := inferInstanceAs (One (X q))
x y z : X q
⊢ (x * y * z).1 = (x * (y * z)).1

Next tactic:
dsimp
instance : Monoid (X q) :=
  { inferInstanceAs (Mul (X q)), inferInstanceAs (One (X q)) with
    mul_assoc := fun x y z => by ext <;> 

Proof state:
case h₂
q : ℕ+
src✝¹ : Mul (X q) := inferInstanceAs (Mul (X q))
src✝ : One (X q) := inferInstanceAs (One (X q))
x y z : X q
⊢ (x * y * z).2 = (x * (y * z)).2

Next tactic:
dsimp
instance : Monoid (X q) :=
  { inferInstanceAs (Mul (X q)), inferInstanceAs (One (X q)) with
    mul_assoc := fun x y z => by ext <;> dsimp <;> 

Proof state:
case h₁
q : ℕ+
src✝¹ : Mul (X q) := inferInstanceAs (Mul (X q))
src✝ : One (X q) := inferInstanceAs (One (X q))
x y z : X q
⊢ (x.1 * y.1 + 3 * x.2 * y.2) * z.1 + 3 * (x.1 * y.2 + x.2 * y.1) * z.2 =
    x.1 * (y.1 * z.1 + 3 * y.2 * z.2) + 3 * x.2 * (y.1 * z.2 + y.2 * z.1)

Next tactic:
ring
instance : Monoid (X q) :=
  { inferInstanceAs (Mul (X q)), inferInstanceAs (One (X q)) with
    mul_assoc := fun x y z => by ext <;> dsimp <;> 

Proof state:
case h₂
q : ℕ+
src✝¹ : Mul (X q) := inferInstanceAs (Mul (X q))
src✝ : One (X q) := inferInstanceAs (One (X q))
x y z : X q
⊢ (x.1 * y.1 + 3 * x.2 * y.2) * z.2 + (x.1 * y.2 + x.2 * y.1) * z.1 =
    x.1 * (y.1 * z.2 + y.2 * z.1) + x.2 * (y.1 * z.1 + 3 * y.2 * z.2)

Next tactic:
ring
instance : Monoid (X q) :=
  { inferInstanceAs (Mul (X q)), inferInstanceAs (One (X q)) with
    mul_assoc := fun x y z => by ext <;> dsimp <;> ring
    one_mul := fun x => by 

Proof state:
q : ℕ+
src✝¹ : Mul (X q) := inferInstanceAs (Mul (X q))
src✝ : One (X q) := inferInstanceAs (One (X q))
x : X q
⊢ 1 * x = x

Next tactic:
ext
instance : Monoid (X q) :=
  { inferInstanceAs (Mul (X q)), inferInstanceAs (One (X q)) with
    mul_assoc := fun x y z => by ext <;> dsimp <;> ring
    one_mul := fun x => by ext <;> 

Proof state:
case h₁
q : ℕ+
src✝¹ : Mul (X q) := inferInstanceAs (Mul (X q))
src✝ : One (X q) := inferInstanceAs (One (X q))
x : X q
⊢ (1 * x).1 = x.1

Next tactic:
simp
instance : Monoid (X q) :=
  { inferInstanceAs (Mul (X q)), inferInstanceAs (One (X q)) with
    mul_assoc := fun x y z => by ext <;> dsimp <;> ring
    one_mul := fun x => by ext <;> 

Proof state:
case h₂
q : ℕ+
src✝¹ : Mul (X q) := inferInstanceAs (Mul (X q))
src✝ : One (X q) := inferInstanceAs (One (X q))
x : X q
⊢ (1 * x).2 = x.2

Next tactic:
simp
instance : Monoid (X q) :=
  { inferInstanceAs (Mul (X q)), inferInstanceAs (One (X q)) with
    mul_assoc := fun x y z => by ext <;> dsimp <;> ring
    one_mul := fun x => by ext <;> simp
    mul_one := fun x => by 

Proof state:
q : ℕ+
src✝¹ : Mul (X q) := inferInstanceAs (Mul (X q))
src✝ : One (X q) := inferInstanceAs (One (X q))
x : X q
⊢ x * 1 = x

Next tactic:
ext
instance : Monoid (X q) :=
  { inferInstanceAs (Mul (X q)), inferInstanceAs (One (X q)) with
    mul_assoc := fun x y z => by ext <;> dsimp <;> ring
    one_mul := fun x => by ext <;> simp
    mul_one := fun x => by ext <;> 

Proof state:
case h₁
q : ℕ+
src✝¹ : Mul (X q) := inferInstanceAs (Mul (X q))
src✝ : One (X q) := inferInstanceAs (One (X q))
x : X q
⊢ (x * 1).1 = x.1

Next tactic:
simp
instance : Monoid (X q) :=
  { inferInstanceAs (Mul (X q)), inferInstanceAs (One (X q)) with
    mul_assoc := fun x y z => by ext <;> dsimp <;> ring
    one_mul := fun x => by ext <;> simp
    mul_one := fun x => by ext <;> 

Proof state:
case h₂
q : ℕ+
src✝¹ : Mul (X q) := inferInstanceAs (Mul (X q))
src✝ : One (X q) := inferInstanceAs (One (X q))
x : X q
⊢ (x * 1).2 = x.2

Next tactic:
simp
instance : AddGroupWithOne (X q) :=
  { inferInstanceAs (Monoid (X q)), inferInstanceAs (AddCommGroup (X q)),
      inferInstanceAs (NatCast (X q)) with
    natCast_zero := by 

Proof state:
q : ℕ+
src✝² : Monoid (X q) := inferInstanceAs (Monoid (X q))
src✝¹ : AddCommGroup (X q) := inferInstanceAs (AddCommGroup (X q))
src✝ : NatCast (X q) := inferInstanceAs (NatCast (X q))
⊢ NatCast.natCast 0 = 0

Next tactic:
ext
instance : AddGroupWithOne (X q) :=
  { inferInstanceAs (Monoid (X q)), inferInstanceAs (AddCommGroup (X q)),
      inferInstanceAs (NatCast (X q)) with
    natCast_zero := by ext <;> 

Proof state:
case h₁
q : ℕ+
src✝² : Monoid (X q) := inferInstanceAs (Monoid (X q))
src✝¹ : AddCommGroup (X q) := inferInstanceAs (AddCommGroup (X q))
src✝ : NatCast (X q) := inferInstanceAs (NatCast (X q))
⊢ (NatCast.natCast 0).1 = 0.1

Next tactic:
simp
instance : AddGroupWithOne (X q) :=
  { inferInstanceAs (Monoid (X q)), inferInstanceAs (AddCommGroup (X q)),
      inferInstanceAs (NatCast (X q)) with
    natCast_zero := by ext <;> 

Proof state:
case h₂
q : ℕ+
src✝² : Monoid (X q) := inferInstanceAs (Monoid (X q))
src✝¹ : AddCommGroup (X q) := inferInstanceAs (AddCommGroup (X q))
src✝ : NatCast (X q) := inferInstanceAs (NatCast (X q))
⊢ (NatCast.natCast 0).2 = 0.2

Next tactic:
simp
instance : AddGroupWithOne (X q) :=
  { inferInstanceAs (Monoid (X q)), inferInstanceAs (AddCommGroup (X q)),
      inferInstanceAs (NatCast (X q)) with
    natCast_zero := by ext <;> simp
    natCast_succ := fun _ ↦ by 

Proof state:
q : ℕ+
src✝² : Monoid (X q) := inferInstanceAs (Monoid (X q))
src✝¹ : AddCommGroup (X q) := inferInstanceAs (AddCommGroup (X q))
src✝ : NatCast (X q) := inferInstanceAs (NatCast (X q))
x✝ : ℕ
⊢ NatCast.natCast (x✝ + 1) = NatCast.natCast x✝ + 1

Next tactic:
ext
instance : AddGroupWithOne (X q) :=
  { inferInstanceAs (Monoid (X q)), inferInstanceAs (AddCommGroup (X q)),
      inferInstanceAs (NatCast (X q)) with
    natCast_zero := by ext <;> simp
    natCast_succ := fun _ ↦ by ext <;> 

Proof state:
case h₁
q : ℕ+
src✝² : Monoid (X q) := inferInstanceAs (Monoid (X q))
src✝¹ : AddCommGroup (X q) := inferInstanceAs (AddCommGroup (X q))
src✝ : NatCast (X q) := inferInstanceAs (NatCast (X q))
x✝ : ℕ
⊢ (NatCast.natCast (x✝ + 1)).1 = (NatCast.natCast x✝ + 1).1

Next tactic:
simp
instance : AddGroupWithOne (X q) :=
  { inferInstanceAs (Monoid (X q)), inferInstanceAs (AddCommGroup (X q)),
      inferInstanceAs (NatCast (X q)) with
    natCast_zero := by ext <;> simp
    natCast_succ := fun _ ↦ by ext <;> 

Proof state:
case h₂
q : ℕ+
src✝² : Monoid (X q) := inferInstanceAs (Monoid (X q))
src✝¹ : AddCommGroup (X q) := inferInstanceAs (AddCommGroup (X q))
src✝ : NatCast (X q) := inferInstanceAs (NatCast (X q))
x✝ : ℕ
⊢ (NatCast.natCast (x✝ + 1)).2 = (NatCast.natCast x✝ + 1).2

Next tactic:
simp
instance : AddGroupWithOne (X q) :=
  { inferInstanceAs (Monoid (X q)), inferInstanceAs (AddCommGroup (X q)),
      inferInstanceAs (NatCast (X q)) with
    natCast_zero := by ext <;> simp
    natCast_succ := fun _ ↦ by ext <;> simp
    intCast := fun n => ⟨n, 0⟩
    intCast_ofNat := fun n => by 

Proof state:
q : ℕ+
src✝² : Monoid (X q) := inferInstanceAs (Monoid (X q))
src✝¹ : AddCommGroup (X q) := inferInstanceAs (AddCommGroup (X q))
src✝ : NatCast (X q) := inferInstanceAs (NatCast (X q))
n : ℕ
⊢ IntCast.intCast ↑n = ↑n

Next tactic:
ext
instance : AddGroupWithOne (X q) :=
  { inferInstanceAs (Monoid (X q)), inferInstanceAs (AddCommGroup (X q)),
      inferInstanceAs (NatCast (X q)) with
    natCast_zero := by ext <;> simp
    natCast_succ := fun _ ↦ by ext <;> simp
    intCast := fun n => ⟨n, 0⟩
    intCast_ofNat := fun n => by ext <;> 

Proof state:
case h₁
q : ℕ+
src✝² : Monoid (X q) := inferInstanceAs (Monoid (X q))
src✝¹ : AddCommGroup (X q) := inferInstanceAs (AddCommGroup (X q))
src✝ : NatCast (X q) := inferInstanceAs (NatCast (X q))
n : ℕ
⊢ (IntCast.intCast ↑n).1 = (↑n).1

Next tactic:
simp
instance : AddGroupWithOne (X q) :=
  { inferInstanceAs (Monoid (X q)), inferInstanceAs (AddCommGroup (X q)),
      inferInstanceAs (NatCast (X q)) with
    natCast_zero := by ext <;> simp
    natCast_succ := fun _ ↦ by ext <;> simp
    intCast := fun n => ⟨n, 0⟩
    intCast_ofNat := fun n => by ext <;> 

Proof state:
case h₂
q : ℕ+
src✝² : Monoid (X q) := inferInstanceAs (Monoid (X q))
src✝¹ : AddCommGroup (X q) := inferInstanceAs (AddCommGroup (X q))
src✝ : NatCast (X q) := inferInstanceAs (NatCast (X q))
n : ℕ
⊢ (IntCast.intCast ↑n).2 = (↑n).2

Next tactic:
simp
instance : AddGroupWithOne (X q) :=
  { inferInstanceAs (Monoid (X q)), inferInstanceAs (AddCommGroup (X q)),
      inferInstanceAs (NatCast (X q)) with
    natCast_zero := by ext <;> simp
    natCast_succ := fun _ ↦ by ext <;> simp
    intCast := fun n => ⟨n, 0⟩
    intCast_ofNat := fun n => by ext <;> simp
    intCast_negSucc := fun n => by 

Proof state:
q : ℕ+
src✝² : Monoid (X q) := inferInstanceAs (Monoid (X q))
src✝¹ : AddCommGroup (X q) := inferInstanceAs (AddCommGroup (X q))
src✝ : NatCast (X q) := inferInstanceAs (NatCast (X q))
n : ℕ
⊢ IntCast.intCast (Int.negSucc n) = -↑(n + 1)

Next tactic:
ext