l3lab/ntp-mathlib huggingface dataset:
theorem xy_modEq_yn (n) :
    ∀ k, xn a1 (n * k) ≡ xn a1 n ^ k [MOD yn a1 n ^ 2] ∧ yn a1 (n * k) ≡
        k * xn a1 n ^ (k - 1) * yn a1 n [MOD yn a1 n ^ 3]
  | 0 => by constructor <;> simp <;> exact Nat.ModEq.refl _
  | k + 1 => by
    let ⟨hx, hy⟩ := xy_modEq_yn n k
    have L : xn a1 (n * k) * xn a1 n + d a1 * yn a1 (n * k) * yn a1 n ≡
        xn a1 n ^ k * xn a1 n + 0 [MOD yn a1 n ^ 2] :=
      (hx.mul_right _).add <|
        modEq_zero_iff_dvd.2 <| by
          rw [_root_.pow_succ']
          exact
            mul_dvd_mul_right
              (dvd_mul_of_dvd_right
                (modEq_zero_iff_dvd.1 <|
                  (hy.of_dvd <| by simp [_root_.pow_succ']).trans <|
                    modEq_zero_iff_dvd.2 <| by simp)
                _) _
    have R : xn a1 (n * k) * yn a1 n + yn a1 (n * k) * xn a1 n ≡
        xn a1 n ^ k * yn a1 n + k * xn a1 n ^ k * yn a1 n [MOD yn a1 n ^ 3] :=
      ModEq.add
          (by
            rw [_root_.pow_succ']
            exact hx.mul_right' _) <| by
        have : k * xn a1 n ^ (k - 1) * yn a1 n * xn a1 n = k * xn a1 n ^ k * yn a1 n := by
          cases' k with k <;> simp [_root_.pow_succ']; ring_nf
        rw [← this]
        

Proof state:
a : ℕ
a1 : 1 < a
n k : ℕ
hx : xn a1 (n * k) ≡ xn a1 n ^ k [MOD yn a1 n ^ 2]
hy : yn a1 (n * k) ≡ k * xn a1 n ^ (k - 1) * yn a1 n [MOD yn a1 n ^ 3]
L : xn a1 (n * k) * xn a1 n + Pell.d a1 * yn a1 (n * k) * yn a1 n ≡ xn a1 n ^ k * xn a1 n + 0 [MOD yn a1 n ^ 2]
this : k * xn a1 n ^ (k - 1) * yn a1 n * xn a1 n = k * xn a1 n ^ k * yn a1 n
⊢ yn a1 (n * k) * xn a1 n ≡ k * xn a1 n ^ (k - 1) * yn a1 n * xn a1 n [MOD yn a1 n ^ 3]

Next tactic:
exact hy.mul_right _
theorem xy_modEq_yn (n) :
    ∀ k, xn a1 (n * k) ≡ xn a1 n ^ k [MOD yn a1 n ^ 2] ∧ yn a1 (n * k) ≡
        k * xn a1 n ^ (k - 1) * yn a1 n [MOD yn a1 n ^ 3]
  | 0 => by constructor <;> simp <;> exact Nat.ModEq.refl _
  | k + 1 => by
    let ⟨hx, hy⟩ := xy_modEq_yn n k
    have L : xn a1 (n * k) * xn a1 n + d a1 * yn a1 (n * k) * yn a1 n ≡
        xn a1 n ^ k * xn a1 n + 0 [MOD yn a1 n ^ 2] :=
      (hx.mul_right _).add <|
        modEq_zero_iff_dvd.2 <| by
          rw [_root_.pow_succ']
          exact
            mul_dvd_mul_right
              (dvd_mul_of_dvd_right
                (modEq_zero_iff_dvd.1 <|
                  (hy.of_dvd <| by simp [_root_.pow_succ']).trans <|
                    modEq_zero_iff_dvd.2 <| by simp)
                _) _
    have R : xn a1 (n * k) * yn a1 n + yn a1 (n * k) * xn a1 n ≡
        xn a1 n ^ k * yn a1 n + k * xn a1 n ^ k * yn a1 n [MOD yn a1 n ^ 3] :=
      ModEq.add
          (by
            rw [_root_.pow_succ']
            exact hx.mul_right' _) <| by
        have : k * xn a1 n ^ (k - 1) * yn a1 n * xn a1 n = k * xn a1 n ^ k * yn a1 n := by
          cases' k with k <;> simp [_root_.pow_succ']; ring_nf
        rw [← this]
        exact hy.mul_right _
    

Proof state:
a : ℕ
a1 : 1 < a
n k : ℕ
hx : xn a1 (n * k) ≡ xn a1 n ^ k [MOD yn a1 n ^ 2]
hy : yn a1 (n * k) ≡ k * xn a1 n ^ (k - 1) * yn a1 n [MOD yn a1 n ^ 3]
L : xn a1 (n * k) * xn a1 n + Pell.d a1 * yn a1 (n * k) * yn a1 n ≡ xn a1 n ^ k * xn a1 n + 0 [MOD yn a1 n ^ 2]
R :
  xn a1 (n * k) * yn a1 n + yn a1 (n * k) * xn a1 n ≡ xn a1 n ^ k * yn a1 n + k * xn a1 n ^ k * yn a1 n [MOD
    yn a1 n ^ 3]
⊢ xn a1 (n * (k + 1)) ≡ xn a1 n ^ (k + 1) [MOD yn a1 n ^ 2] ∧
    yn a1 (n * (k + 1)) ≡ (k + 1) * xn a1 n ^ (k + 1 - 1) * yn a1 n [MOD yn a1 n ^ 3]

Next tactic:
rw [add_tsub_cancel_right, Nat.mul_succ, xn_add, yn_add, pow_succ' (xn _ n), Nat.succ_mul,
      add_comm (k * xn _ n ^ k) (xn _ n ^ k), right_distrib]
theorem xy_modEq_yn (n) :
    ∀ k, xn a1 (n * k) ≡ xn a1 n ^ k [MOD yn a1 n ^ 2] ∧ yn a1 (n * k) ≡
        k * xn a1 n ^ (k - 1) * yn a1 n [MOD yn a1 n ^ 3]
  | 0 => by constructor <;> simp <;> exact Nat.ModEq.refl _
  | k + 1 => by
    let ⟨hx, hy⟩ := xy_modEq_yn n k
    have L : xn a1 (n * k) * xn a1 n + d a1 * yn a1 (n * k) * yn a1 n ≡
        xn a1 n ^ k * xn a1 n + 0 [MOD yn a1 n ^ 2] :=
      (hx.mul_right _).add <|
        modEq_zero_iff_dvd.2 <| by
          rw [_root_.pow_succ']
          exact
            mul_dvd_mul_right
              (dvd_mul_of_dvd_right
                (modEq_zero_iff_dvd.1 <|
                  (hy.of_dvd <| by simp [_root_.pow_succ']).trans <|
                    modEq_zero_iff_dvd.2 <| by simp)
                _) _
    have R : xn a1 (n * k) * yn a1 n + yn a1 (n * k) * xn a1 n ≡
        xn a1 n ^ k * yn a1 n + k * xn a1 n ^ k * yn a1 n [MOD yn a1 n ^ 3] :=
      ModEq.add
          (by
            rw [_root_.pow_succ']
            exact hx.mul_right' _) <| by
        have : k * xn a1 n ^ (k - 1) * yn a1 n * xn a1 n = k * xn a1 n ^ k * yn a1 n := by
          cases' k with k <;> simp [_root_.pow_succ']; ring_nf
        rw [← this]
        exact hy.mul_right _
    rw [add_tsub_cancel_right, Nat.mul_succ, xn_add, yn_add, pow_succ' (xn _ n), Nat.succ_mul,
      add_comm (k * xn _ n ^ k) (xn _ n ^ k), right_distrib]
    

Proof state:
a : ℕ
a1 : 1 < a
n k : ℕ
hx : xn a1 (n * k) ≡ xn a1 n ^ k [MOD yn a1 n ^ 2]
hy : yn a1 (n * k) ≡ k * xn a1 n ^ (k - 1) * yn a1 n [MOD yn a1 n ^ 3]
L : xn a1 (n * k) * xn a1 n + Pell.d a1 * yn a1 (n * k) * yn a1 n ≡ xn a1 n ^ k * xn a1 n + 0 [MOD yn a1 n ^ 2]
R :
  xn a1 (n * k) * yn a1 n + yn a1 (n * k) * xn a1 n ≡ xn a1 n ^ k * yn a1 n + k * xn a1 n ^ k * yn a1 n [MOD
    yn a1 n ^ 3]
⊢ xn a1 (n * k) * xn a1 n + Pell.d a1 * yn a1 (n * k) * yn a1 n ≡ xn a1 n ^ k * xn a1 n [MOD yn a1 n ^ 2] ∧
    xn a1 (n * k) * yn a1 n + yn a1 (n * k) * xn a1 n ≡ xn a1 n ^ k * yn a1 n + k * xn a1 n ^ k * yn a1 n [MOD
      yn a1 n ^ 3]

Next tactic:
exact ⟨L, R⟩
theorem ysq_dvd_yy (n) : yn a1 n * yn a1 n ∣ yn a1 (n * yn a1 n) :=
  modEq_zero_iff_dvd.1 <|
    ((xy_modEq_yn a1 n (yn a1 n)).right.of_dvd <| by 

Proof state:
a : ℕ
a1 : 1 < a
n : ℕ
⊢ yn a1 n * yn a1 n ∣ yn a1 n ^ 3

Next tactic:
simp [_root_.pow_succ]
theorem ysq_dvd_yy (n) : yn a1 n * yn a1 n ∣ yn a1 (n * yn a1 n) :=
  modEq_zero_iff_dvd.1 <|
    ((xy_modEq_yn a1 n (yn a1 n)).right.of_dvd <| by simp [_root_.pow_succ]).trans
      (modEq_zero_iff_dvd.2 <| by 

Proof state:
a : ℕ
a1 : 1 < a
n : ℕ
⊢ yn a1 n * yn a1 n ∣ yn a1 n * xn a1 n ^ (yn a1 n - 1) * yn a1 n

Next tactic:
simp [mul_dvd_mul_left, mul_assoc]
theorem dvd_of_ysq_dvd {n t} (h : yn a1 n * yn a1 n ∣ yn a1 t) : yn a1 n ∣ t :=
  have nt : n ∣ t := (y_dvd_iff a1 n t).1 <| dvd_of_mul_left_dvd h
  n.eq_zero_or_pos.elim (fun n0 => by 

Proof state:
a : ℕ
a1 : 1 < a
n t : ℕ
h : yn a1 n * yn a1 n ∣ yn a1 t
nt : n ∣ t
n0 : n = 0
⊢ yn a1 n ∣ t

Next tactic:
rwa [n0] at nt ⊢
theorem dvd_of_ysq_dvd {n t} (h : yn a1 n * yn a1 n ∣ yn a1 t) : yn a1 n ∣ t :=
  have nt : n ∣ t := (y_dvd_iff a1 n t).1 <| dvd_of_mul_left_dvd h
  n.eq_zero_or_pos.elim (fun n0 => by rwa [n0] at nt ⊢) fun n0l : 0 < n => by
    

Proof state:
a : ℕ
a1 : 1 < a
n t : ℕ
h : yn a1 n * yn a1 n ∣ yn a1 t
nt : n ∣ t
n0l : 0 < n
⊢ yn a1 n ∣ t

Next tactic:
let ⟨k, ke⟩ := nt
theorem dvd_of_ysq_dvd {n t} (h : yn a1 n * yn a1 n ∣ yn a1 t) : yn a1 n ∣ t :=
  have nt : n ∣ t := (y_dvd_iff a1 n t).1 <| dvd_of_mul_left_dvd h
  n.eq_zero_or_pos.elim (fun n0 => by rwa [n0] at nt ⊢) fun n0l : 0 < n => by
    let ⟨k, ke⟩ := nt
    

Proof state:
a : ℕ
a1 : 1 < a
n t : ℕ
h : yn a1 n * yn a1 n ∣ yn a1 t
nt : n ∣ t
n0l : 0 < n
k : ℕ
ke : t = n * k
⊢ yn a1 n ∣ t

Next tactic:
have : yn a1 n ∣ k * xn a1 n ^ (k - 1) :=
      Nat.dvd_of_mul_dvd_mul_right (strictMono_y a1 n0l) <|
        modEq_zero_iff_dvd.1 <| by
          have xm := (xy_modEq_yn a1 n k).right; rw [← ke] at xm
          exact (xm.of_dvd <| by simp [_root_.pow_succ]).symm.trans h.modEq_zero_nat
theorem dvd_of_ysq_dvd {n t} (h : yn a1 n * yn a1 n ∣ yn a1 t) : yn a1 n ∣ t :=
  have nt : n ∣ t := (y_dvd_iff a1 n t).1 <| dvd_of_mul_left_dvd h
  n.eq_zero_or_pos.elim (fun n0 => by rwa [n0] at nt ⊢) fun n0l : 0 < n => by
    let ⟨k, ke⟩ := nt
    have : yn a1 n ∣ k * xn a1 n ^ (k - 1) :=
      Nat.dvd_of_mul_dvd_mul_right (strictMono_y a1 n0l) <|
        modEq_zero_iff_dvd.1 <| by
          

Proof state:
a : ℕ
a1 : 1 < a
n t : ℕ
h : yn a1 n * yn a1 n ∣ yn a1 t
nt : n ∣ t
n0l : 0 < n
k : ℕ
ke : t = n * k
⊢ k * xn a1 n ^ (k - 1) * yn a1 n ≡ 0 [MOD yn a1 n * yn a1 n]

Next tactic:
have xm := (xy_modEq_yn a1 n k).right
theorem dvd_of_ysq_dvd {n t} (h : yn a1 n * yn a1 n ∣ yn a1 t) : yn a1 n ∣ t :=
  have nt : n ∣ t := (y_dvd_iff a1 n t).1 <| dvd_of_mul_left_dvd h
  n.eq_zero_or_pos.elim (fun n0 => by rwa [n0] at nt ⊢) fun n0l : 0 < n => by
    let ⟨k, ke⟩ := nt
    have : yn a1 n ∣ k * xn a1 n ^ (k - 1) :=
      Nat.dvd_of_mul_dvd_mul_right (strictMono_y a1 n0l) <|
        modEq_zero_iff_dvd.1 <| by
          have xm := (xy_modEq_yn a1 n k).right; 

Proof state:
a : ℕ
a1 : 1 < a
n t : ℕ
h : yn a1 n * yn a1 n ∣ yn a1 t
nt : n ∣ t
n0l : 0 < n
k : ℕ
ke : t = n * k
xm : yn a1 (n * k) ≡ k * xn a1 n ^ (k - 1) * yn a1 n [MOD yn a1 n ^ 3]
⊢ k * xn a1 n ^ (k - 1) * yn a1 n ≡ 0 [MOD yn a1 n * yn a1 n]

Next tactic:
rw [← ke] at xm
theorem dvd_of_ysq_dvd {n t} (h : yn a1 n * yn a1 n ∣ yn a1 t) : yn a1 n ∣ t :=
  have nt : n ∣ t := (y_dvd_iff a1 n t).1 <| dvd_of_mul_left_dvd h
  n.eq_zero_or_pos.elim (fun n0 => by rwa [n0] at nt ⊢) fun n0l : 0 < n => by
    let ⟨k, ke⟩ := nt
    have : yn a1 n ∣ k * xn a1 n ^ (k - 1) :=
      Nat.dvd_of_mul_dvd_mul_right (strictMono_y a1 n0l) <|
        modEq_zero_iff_dvd.1 <| by
          have xm := (xy_modEq_yn a1 n k).right; rw [← ke] at xm
          

Proof state:
a : ℕ
a1 : 1 < a
n t : ℕ
h : yn a1 n * yn a1 n ∣ yn a1 t
nt : n ∣ t
n0l : 0 < n
k : ℕ
ke : t = n * k
xm : yn a1 t ≡ k * xn a1 n ^ (k - 1) * yn a1 n [MOD yn a1 n ^ 3]
⊢ k * xn a1 n ^ (k - 1) * yn a1 n ≡ 0 [MOD yn a1 n * yn a1 n]

Next tactic:
exact (xm.of_dvd <| by simp [_root_.pow_succ]).symm.trans h.modEq_zero_nat
theorem dvd_of_ysq_dvd {n t} (h : yn a1 n * yn a1 n ∣ yn a1 t) : yn a1 n ∣ t :=
  have nt : n ∣ t := (y_dvd_iff a1 n t).1 <| dvd_of_mul_left_dvd h
  n.eq_zero_or_pos.elim (fun n0 => by rwa [n0] at nt ⊢) fun n0l : 0 < n => by
    let ⟨k, ke⟩ := nt
    have : yn a1 n ∣ k * xn a1 n ^ (k - 1) :=
      Nat.dvd_of_mul_dvd_mul_right (strictMono_y a1 n0l) <|
        modEq_zero_iff_dvd.1 <| by
          have xm := (xy_modEq_yn a1 n k).right; rw [← ke] at xm
          exact (xm.of_dvd <| by 

Proof state:
a : ℕ
a1 : 1 < a
n t : ℕ
h : yn a1 n * yn a1 n ∣ yn a1 t
nt : n ∣ t
n0l : 0 < n
k : ℕ
ke : t = n * k
xm : yn a1 t ≡ k * xn a1 n ^ (k - 1) * yn a1 n [MOD yn a1 n ^ 3]
⊢ yn a1 n * yn a1 n ∣ yn a1 n ^ 3

Next tactic:
simp [_root_.pow_succ]
theorem dvd_of_ysq_dvd {n t} (h : yn a1 n * yn a1 n ∣ yn a1 t) : yn a1 n ∣ t :=
  have nt : n ∣ t := (y_dvd_iff a1 n t).1 <| dvd_of_mul_left_dvd h
  n.eq_zero_or_pos.elim (fun n0 => by rwa [n0] at nt ⊢) fun n0l : 0 < n => by
    let ⟨k, ke⟩ := nt
    have : yn a1 n ∣ k * xn a1 n ^ (k - 1) :=
      Nat.dvd_of_mul_dvd_mul_right (strictMono_y a1 n0l) <|
        modEq_zero_iff_dvd.1 <| by
          have xm := (xy_modEq_yn a1 n k).right; rw [← ke] at xm
          exact (xm.of_dvd <| by simp [_root_.pow_succ]).symm.trans h.modEq_zero_nat
    

Proof state:
a : ℕ
a1 : 1 < a
n t : ℕ
h : yn a1 n * yn a1 n ∣ yn a1 t
nt : n ∣ t
n0l : 0 < n
k : ℕ
ke : t = n * k
this : yn a1 n ∣ k * xn a1 n ^ (k - 1)
⊢ yn a1 n ∣ t

Next tactic:
rw [ke]
theorem dvd_of_ysq_dvd {n t} (h : yn a1 n * yn a1 n ∣ yn a1 t) : yn a1 n ∣ t :=
  have nt : n ∣ t := (y_dvd_iff a1 n t).1 <| dvd_of_mul_left_dvd h
  n.eq_zero_or_pos.elim (fun n0 => by rwa [n0] at nt ⊢) fun n0l : 0 < n => by
    let ⟨k, ke⟩ := nt
    have : yn a1 n ∣ k * xn a1 n ^ (k - 1) :=
      Nat.dvd_of_mul_dvd_mul_right (strictMono_y a1 n0l) <|
        modEq_zero_iff_dvd.1 <| by
          have xm := (xy_modEq_yn a1 n k).right; rw [← ke] at xm
          exact (xm.of_dvd <| by simp [_root_.pow_succ]).symm.trans h.modEq_zero_nat
    rw [ke]
    

Proof state:
a : ℕ
a1 : 1 < a
n t : ℕ
h : yn a1 n * yn a1 n ∣ yn a1 t
nt : n ∣ t
n0l : 0 < n
k : ℕ
ke : t = n * k
this : yn a1 n ∣ k * xn a1 n ^ (k - 1)
⊢ yn a1 n ∣ n * k

Next tactic:
exact dvd_mul_of_dvd_right (((xy_coprime _ _).pow_left _).symm.dvd_of_dvd_mul_right this) _
theorem pellZd_succ_succ (n) :
    pellZd a1 (n + 2) + pellZd a1 n = (2 * a : ℕ) * pellZd a1 (n + 1) := by
  

Proof state:
a : ℕ
a1 : 1 < a
n : ℕ
⊢ pellZd a1 (n + 2) + pellZd a1 n = ↑(2 * a) * pellZd a1 (n + 1)

Next tactic:
have : (1 : ℤ√(d a1)) + ⟨a, 1⟩ * ⟨a, 1⟩ = ⟨a, 1⟩ * (2 * a) := by
    rw [Zsqrtd.coe_nat_val]
    change (⟨_, _⟩ : ℤ√(d a1)) = ⟨_, _⟩
    rw [dz_val]
    dsimp [az]
    rw [Zsqrtd.ext]
    dsimp
    constructor <;> ring_nf
theorem pellZd_succ_succ (n) :
    pellZd a1 (n + 2) + pellZd a1 n = (2 * a : ℕ) * pellZd a1 (n + 1) := by
  have : (1 : ℤ√(d a1)) + ⟨a, 1⟩ * ⟨a, 1⟩ = ⟨a, 1⟩ * (2 * a) := by
    

Proof state:
a : ℕ
a1 : 1 < a
n : ℕ
⊢ 1 + { re := ↑a, im := 1 } * { re := ↑a, im := 1 } = { re := ↑a, im := 1 } * (2 * ↑a)

Next tactic:
rw [Zsqrtd.coe_nat_val]
theorem pellZd_succ_succ (n) :
    pellZd a1 (n + 2) + pellZd a1 n = (2 * a : ℕ) * pellZd a1 (n + 1) := by
  have : (1 : ℤ√(d a1)) + ⟨a, 1⟩ * ⟨a, 1⟩ = ⟨a, 1⟩ * (2 * a) := by
    rw [Zsqrtd.coe_nat_val]
    

Proof state:
a : ℕ
a1 : 1 < a
n : ℕ
⊢ 1 + { re := ↑a, im := 1 } * { re := ↑a, im := 1 } = { re := ↑a, im := 1 } * (2 * { re := ↑a, im := 0 })

Next tactic:
change (⟨_, _⟩ : ℤ√(d a1)) = ⟨_, _⟩
theorem pellZd_succ_succ (n) :
    pellZd a1 (n + 2) + pellZd a1 n = (2 * a : ℕ) * pellZd a1 (n + 1) := by
  have : (1 : ℤ√(d a1)) + ⟨a, 1⟩ * ⟨a, 1⟩ = ⟨a, 1⟩ * (2 * a) := by
    rw [Zsqrtd.coe_nat_val]
    change (⟨_, _⟩ : ℤ√(d a1)) = ⟨_, _⟩
    

Proof state:
a : ℕ
a1 : 1 < a
n : ℕ
⊢ { re := 1.re + ({ re := ↑a, im := 1 } * { re := ↑a, im := 1 }).re,
      im := 1.im + ({ re := ↑a, im := 1 } * { re := ↑a, im := 1 }).im } =
    {
      re :=
        { re := ↑a, im := 1 }.re * (2 * { re := ↑a, im := 0 }).re +
          ↑(Pell.d a1) * { re := ↑a, im := 1 }.im * (2 * { re := ↑a, im := 0 }).im,
      im :=
        { re := ↑a, im := 1 }.re * (2 * { re := ↑a, im := 0 }).im +
          { re := ↑a, im := 1 }.im * (2 * { re := ↑a, im := 0 }).re }

Next tactic:
rw [dz_val]
theorem pellZd_succ_succ (n) :
    pellZd a1 (n + 2) + pellZd a1 n = (2 * a : ℕ) * pellZd a1 (n + 1) := by
  have : (1 : ℤ√(d a1)) + ⟨a, 1⟩ * ⟨a, 1⟩ = ⟨a, 1⟩ * (2 * a) := by
    rw [Zsqrtd.coe_nat_val]
    change (⟨_, _⟩ : ℤ√(d a1)) = ⟨_, _⟩
    rw [dz_val]
    

Proof state:
a : ℕ
a1 : 1 < a
n : ℕ
⊢ { re := 1.re + ({ re := ↑a, im := 1 } * { re := ↑a, im := 1 }).re,
      im := 1.im + ({ re := ↑a, im := 1 } * { re := ↑a, im := 1 }).im } =
    {
      re :=
        { re := ↑a, im := 1 }.re * (2 * { re := ↑a, im := 0 }).re +
          (az a * az a - 1) * { re := ↑a, im := 1 }.im * (2 * { re := ↑a, im := 0 }).im,
      im :=
        { re := ↑a, im := 1 }.re * (2 * { re := ↑a, im := 0 }).im +
          { re := ↑a, im := 1 }.im * (2 * { re := ↑a, im := 0 }).re }

Next tactic:
dsimp [az]
theorem pellZd_succ_succ (n) :
    pellZd a1 (n + 2) + pellZd a1 n = (2 * a : ℕ) * pellZd a1 (n + 1) := by
  have : (1 : ℤ√(d a1)) + ⟨a, 1⟩ * ⟨a, 1⟩ = ⟨a, 1⟩ * (2 * a) := by
    rw [Zsqrtd.coe_nat_val]
    change (⟨_, _⟩ : ℤ√(d a1)) = ⟨_, _⟩
    rw [dz_val]
    dsimp [az]
    

Proof state:
a : ℕ
a1 : 1 < a
n : ℕ
⊢ { re := 1 + (↑a * ↑a + (↑a * ↑a - 1) * 1 * 1), im := 0 + (↑a * 1 + 1 * ↑a) } =
    { re := ↑a * (↑2 * ↑a + (↑a * ↑a - 1) * 0 * 0) + (↑a * ↑a - 1) * 1 * (↑2 * 0 + 0 * ↑a),
      im := ↑a * (↑2 * 0 + 0 * ↑a) + 1 * (↑2 * ↑a + (↑a * ↑a - 1) * 0 * 0) }

Next tactic:
rw [Zsqrtd.ext]
theorem pellZd_succ_succ (n) :
    pellZd a1 (n + 2) + pellZd a1 n = (2 * a : ℕ) * pellZd a1 (n + 1) := by
  have : (1 : ℤ√(d a1)) + ⟨a, 1⟩ * ⟨a, 1⟩ = ⟨a, 1⟩ * (2 * a) := by
    rw [Zsqrtd.coe_nat_val]
    change (⟨_, _⟩ : ℤ√(d a1)) = ⟨_, _⟩
    rw [dz_val]
    dsimp [az]
    rw [Zsqrtd.ext]
    

Proof state:
a : ℕ
a1 : 1 < a
n : ℕ
⊢ { re := 1 + (↑a * ↑a + (↑a * ↑a - 1) * 1 * 1), im := 0 + (↑a * 1 + 1 * ↑a) }.re =
      { re := ↑a * (↑2 * ↑a + (↑a * ↑a - 1) * 0 * 0) + (↑a * ↑a - 1) * 1 * (↑2 * 0 + 0 * ↑a),
          im := ↑a * (↑2 * 0 + 0 * ↑a) + 1 * (↑2 * ↑a + (↑a * ↑a - 1) * 0 * 0) }.re ∧
    { re := 1 + (↑a * ↑a + (↑a * ↑a - 1) * 1 * 1), im := 0 + (↑a * 1 + 1 * ↑a) }.im =
      { re := ↑a * (↑2 * ↑a + (↑a * ↑a - 1) * 0 * 0) + (↑a * ↑a - 1) * 1 * (↑2 * 0 + 0 * ↑a),
          im := ↑a * (↑2 * 0 + 0 * ↑a) + 1 * (↑2 * ↑a + (↑a * ↑a - 1) * 0 * 0) }.im

Next tactic:
dsimp
theorem pellZd_succ_succ (n) :
    pellZd a1 (n + 2) + pellZd a1 n = (2 * a : ℕ) * pellZd a1 (n + 1) := by
  have : (1 : ℤ√(d a1)) + ⟨a, 1⟩ * ⟨a, 1⟩ = ⟨a, 1⟩ * (2 * a) := by
    rw [Zsqrtd.coe_nat_val]
    change (⟨_, _⟩ : ℤ√(d a1)) = ⟨_, _⟩
    rw [dz_val]
    dsimp [az]
    rw [Zsqrtd.ext]
    dsimp
    

Proof state:
a : ℕ
a1 : 1 < a
n : ℕ
⊢ 1 + (↑a * ↑a + (↑a * ↑a - 1) * 1 * 1) =
      ↑a * (↑2 * ↑a + (↑a * ↑a - 1) * 0 * 0) + (↑a * ↑a - 1) * 1 * (↑2 * 0 + 0 * ↑a) ∧
    0 + (↑a * 1 + 1 * ↑a) = ↑a * (↑2 * 0 + 0 * ↑a) + 1 * (↑2 * ↑a + (↑a * ↑a - 1) * 0 * 0)

Next tactic:
constructor
theorem pellZd_succ_succ (n) :
    pellZd a1 (n + 2) + pellZd a1 n = (2 * a : ℕ) * pellZd a1 (n + 1) := by
  have : (1 : ℤ√(d a1)) + ⟨a, 1⟩ * ⟨a, 1⟩ = ⟨a, 1⟩ * (2 * a) := by
    rw [Zsqrtd.coe_nat_val]
    change (⟨_, _⟩ : ℤ√(d a1)) = ⟨_, _⟩
    rw [dz_val]
    dsimp [az]
    rw [Zsqrtd.ext]
    dsimp
    constructor <;> 

Proof state:
case left
a : ℕ
a1 : 1 < a
n : ℕ
⊢ 1 + (↑a * ↑a + (↑a * ↑a - 1) * 1 * 1) = ↑a * (↑2 * ↑a + (↑a * ↑a - 1) * 0 * 0) + (↑a * ↑a - 1) * 1 * (↑2 * 0 + 0 * ↑a)

Next tactic:
ring_nf
theorem pellZd_succ_succ (n) :
    pellZd a1 (n + 2) + pellZd a1 n = (2 * a : ℕ) * pellZd a1 (n + 1) := by
  have : (1 : ℤ√(d a1)) + ⟨a, 1⟩ * ⟨a, 1⟩ = ⟨a, 1⟩ * (2 * a) := by
    rw [Zsqrtd.coe_nat_val]
    change (⟨_, _⟩ : ℤ√(d a1)) = ⟨_, _⟩
    rw [dz_val]
    dsimp [az]
    rw [Zsqrtd.ext]
    dsimp
    constructor <;> 

Proof state:
case right
a : ℕ
a1 : 1 < a
n : ℕ
⊢ 0 + (↑a * 1 + 1 * ↑a) = ↑a * (↑2 * 0 + 0 * ↑a) + 1 * (↑2 * ↑a + (↑a * ↑a - 1) * 0 * 0)

Next tactic:
ring_nf
theorem pellZd_succ_succ (n) :
    pellZd a1 (n + 2) + pellZd a1 n = (2 * a : ℕ) * pellZd a1 (n + 1) := by
  have : (1 : ℤ√(d a1)) + ⟨a, 1⟩ * ⟨a, 1⟩ = ⟨a, 1⟩ * (2 * a) := by
    rw [Zsqrtd.coe_nat_val]
    change (⟨_, _⟩ : ℤ√(d a1)) = ⟨_, _⟩
    rw [dz_val]
    dsimp [az]
    rw [Zsqrtd.ext]
    dsimp
    constructor <;> ring_nf
  

Proof state:
a : ℕ
a1 : 1 < a
n : ℕ
this : 1 + { re := ↑a, im := 1 } * { re := ↑a, im := 1 } = { re := ↑a, im := 1 } * (2 * ↑a)
⊢ pellZd a1 (n + 2) + pellZd a1 n = ↑(2 * a) * pellZd a1 (n + 1)

Next tactic:
simpa [mul_add, mul_comm, mul_left_comm, add_comm] using congr_arg (· * pellZd a1 n) this
theorem xy_succ_succ (n) :
    xn a1 (n + 2) + xn a1 n =
      2 * a * xn a1 (n + 1) ∧ yn a1 (n + 2) + yn a1 n = 2 * a * yn a1 (n + 1) := by
  

Proof state:
a : ℕ
a1 : 1 < a
n : ℕ
⊢ xn a1 (n + 2) + xn a1 n = 2 * a * xn a1 (n + 1) ∧ yn a1 (n + 2) + yn a1 n = 2 * a * yn a1 (n + 1)

Next tactic:
have := pellZd_succ_succ a1 n
theorem xy_succ_succ (n) :
    xn a1 (n + 2) + xn a1 n =
      2 * a * xn a1 (n + 1) ∧ yn a1 (n + 2) + yn a1 n = 2 * a * yn a1 (n + 1) := by
  have := pellZd_succ_succ a1 n; 

Proof state:
a : ℕ
a1 : 1 < a
n : ℕ
this : pellZd a1 (n + 2) + pellZd a1 n = ↑(2 * a) * pellZd a1 (n + 1)
⊢ xn a1 (n + 2) + xn a1 n = 2 * a * xn a1 (n + 1) ∧ yn a1 (n + 2) + yn a1 n = 2 * a * yn a1 (n + 1)

Next tactic:
unfold pellZd at this
theorem xy_succ_succ (n) :
    xn a1 (n + 2) + xn a1 n =
      2 * a * xn a1 (n + 1) ∧ yn a1 (n + 2) + yn a1 n = 2 * a * yn a1 (n + 1) := by
  have := pellZd_succ_succ a1 n; unfold pellZd at this
  

Proof state:
a : ℕ
a1 : 1 < a
n : ℕ
this :
  { re := ↑(xn a1 (n + 2)), im := ↑(yn a1 (n + 2)) } + { re := ↑(xn a1 n), im := ↑(yn a1 n) } =
    ↑(2 * a) * { re := ↑(xn a1 (n + 1)), im := ↑(yn a1 (n + 1)) }
⊢ xn a1 (n + 2) + xn a1 n = 2 * a * xn a1 (n + 1) ∧ yn a1 (n + 2) + yn a1 n = 2 * a * yn a1 (n + 1)

Next tactic:
erw [Zsqrtd.smul_val (2 * a : ℕ)] at this
theorem xy_succ_succ (n) :
    xn a1 (n + 2) + xn a1 n =
      2 * a * xn a1 (n + 1) ∧ yn a1 (n + 2) + yn a1 n = 2 * a * yn a1 (n + 1) := by
  have := pellZd_succ_succ a1 n; unfold pellZd at this
  erw [Zsqrtd.smul_val (2 * a : ℕ)] at this
  

Proof state:
a : ℕ
a1 : 1 < a
n : ℕ
this :
  { re := ↑(xn a1 (n + 2)), im := ↑(yn a1 (n + 2)) } + { re := ↑(xn a1 n), im := ↑(yn a1 n) } =
    { re := ↑(2 * a) * ↑(xn a1 (n + 1)), im := ↑(2 * a) * ↑(yn a1 (n + 1)) }
⊢ xn a1 (n + 2) + xn a1 n = 2 * a * xn a1 (n + 1) ∧ yn a1 (n + 2) + yn a1 n = 2 * a * yn a1 (n + 1)

Next tactic:
injection this with h₁ h₂
theorem xy_succ_succ (n) :
    xn a1 (n + 2) + xn a1 n =
      2 * a * xn a1 (n + 1) ∧ yn a1 (n + 2) + yn a1 n = 2 * a * yn a1 (n + 1) := by
  have := pellZd_succ_succ a1 n; unfold pellZd at this
  erw [Zsqrtd.smul_val (2 * a : ℕ)] at this
  injection this with h₁ h₂
  

Proof state:
a : ℕ
a1 : 1 < a
n : ℕ
h₁ :
  { re := ↑(xn a1 (n + 2)), im := ↑(yn a1 (n + 2)) }.re + { re := ↑(xn a1 n), im := ↑(yn a1 n) }.re =
    ↑(2 * a) * ↑(xn a1 (n + 1))
h₂ :
  { re := ↑(xn a1 (n + 2)), im := ↑(yn a1 (n + 2)) }.im + { re := ↑(xn a1 n), im := ↑(yn a1 n) }.im =
    ↑(2 * a) * ↑(yn a1 (n + 1))
⊢ xn a1 (n + 2) + xn a1 n = 2 * a * xn a1 (n + 1) ∧ yn a1 (n + 2) + yn a1 n = 2 * a * yn a1 (n + 1)

Next tactic:
constructor <;> apply Int.ofNat.inj <;> [simpa using h₁; simpa using h₂]
theorem xy_succ_succ (n) :
    xn a1 (n + 2) + xn a1 n =
      2 * a * xn a1 (n + 1) ∧ yn a1 (n + 2) + yn a1 n = 2 * a * yn a1 (n + 1) := by
  have := pellZd_succ_succ a1 n; unfold pellZd at this
  erw [Zsqrtd.smul_val (2 * a : ℕ)] at this
  injection this with h₁ h₂
  

Proof state:
a : ℕ
a1 : 1 < a
n : ℕ
h₁ :
  { re := ↑(xn a1 (n + 2)), im := ↑(yn a1 (n + 2)) }.re + { re := ↑(xn a1 n), im := ↑(yn a1 n) }.re =
    ↑(2 * a) * ↑(xn a1 (n + 1))
h₂ :
  { re := ↑(xn a1 (n + 2)), im := ↑(yn a1 (n + 2)) }.im + { re := ↑(xn a1 n), im := ↑(yn a1 n) }.im =
    ↑(2 * a) * ↑(yn a1 (n + 1))
⊢ xn a1 (n + 2) + xn a1 n = 2 * a * xn a1 (n + 1) ∧ yn a1 (n + 2) + yn a1 n = 2 * a * yn a1 (n + 1)

Next tactic:
constructor
theorem xy_succ_succ (n) :
    xn a1 (n + 2) + xn a1 n =
      2 * a * xn a1 (n + 1) ∧ yn a1 (n + 2) + yn a1 n = 2 * a * yn a1 (n + 1) := by
  have := pellZd_succ_succ a1 n; unfold pellZd at this
  erw [Zsqrtd.smul_val (2 * a : ℕ)] at this
  injection this with h₁ h₂
  constructor <;> 

Proof state:
case left
a : ℕ
a1 : 1 < a
n : ℕ
h₁ :
  { re := ↑(xn a1 (n + 2)), im := ↑(yn a1 (n + 2)) }.re + { re := ↑(xn a1 n), im := ↑(yn a1 n) }.re =
    ↑(2 * a) * ↑(xn a1 (n + 1))
h₂ :
  { re := ↑(xn a1 (n + 2)), im := ↑(yn a1 (n + 2)) }.im + { re := ↑(xn a1 n), im := ↑(yn a1 n) }.im =
    ↑(2 * a) * ↑(yn a1 (n + 1))
⊢ xn a1 (n + 2) + xn a1 n = 2 * a * xn a1 (n + 1)

Next tactic:
apply Int.ofNat.inj
theorem xy_succ_succ (n) :
    xn a1 (n + 2) + xn a1 n =
      2 * a * xn a1 (n + 1) ∧ yn a1 (n + 2) + yn a1 n = 2 * a * yn a1 (n + 1) := by
  have := pellZd_succ_succ a1 n; unfold pellZd at this
  erw [Zsqrtd.smul_val (2 * a : ℕ)] at this
  injection this with h₁ h₂
  constructor <;> 

Proof state:
case right
a : ℕ
a1 : 1 < a
n : ℕ
h₁ :
  { re := ↑(xn a1 (n + 2)), im := ↑(yn a1 (n + 2)) }.re + { re := ↑(xn a1 n), im := ↑(yn a1 n) }.re =
    ↑(2 * a) * ↑(xn a1 (n + 1))
h₂ :
  { re := ↑(xn a1 (n + 2)), im := ↑(yn a1 (n + 2)) }.im + { re := ↑(xn a1 n), im := ↑(yn a1 n) }.im =
    ↑(2 * a) * ↑(yn a1 (n + 1))
⊢ yn a1 (n + 2) + yn a1 n = 2 * a * yn a1 (n + 1)

Next tactic:
apply Int.ofNat.inj
theorem xy_succ_succ (n) :
    xn a1 (n + 2) + xn a1 n =
      2 * a * xn a1 (n + 1) ∧ yn a1 (n + 2) + yn a1 n = 2 * a * yn a1 (n + 1) := by
  have := pellZd_succ_succ a1 n; unfold pellZd at this
  erw [Zsqrtd.smul_val (2 * a : ℕ)] at this
  injection this with h₁ h₂
  constructor <;> apply Int.ofNat.inj <;> [

Proof state:
case left.x
a : ℕ
a1 : 1 < a
n : ℕ
h₁ :
  { re := ↑(xn a1 (n + 2)), im := ↑(yn a1 (n + 2)) }.re + { re := ↑(xn a1 n), im := ↑(yn a1 n) }.re =
    ↑(2 * a) * ↑(xn a1 (n + 1))
h₂ :
  { re := ↑(xn a1 (n + 2)), im := ↑(yn a1 (n + 2)) }.im + { re := ↑(xn a1 n), im := ↑(yn a1 n) }.im =
    ↑(2 * a) * ↑(yn a1 (n + 1))
⊢ Int.ofNat (xn a1 (n + 2) + xn a1 n) = Int.ofNat (2 * a * xn a1 (n + 1))

Next tactic:
simpa using h₁