File: Mathlib/NumberTheory/Pell.lean

full_name: Pell.is_pell_solution_iff_mem_unitary
code: /-- An element of `ℤ√d` has norm one (i.e., `a.re^2 - d*a.im^2 = 1`) if and only if
it is contained in the submonoid of unitary elements.

TODO: merge this result with `Pell.isPell_iff_mem_unitary`. -/
theorem is_pell_solution_iff_mem_unitary {d : ℤ} {a : ℤ√d} :
    a.re ^ 2 - d * a.im ^ 2 = 1 ↔ a ∈ unitary (ℤ√d) 
goal: a.re ^ 2 - d * a.im ^ 2 = 1 ↔ a ∈ unitary (ℤ√d)

full_name: Pell.Solution₁
code: /-- `Pell.Solution₁ d` is the type of solutions to the Pell equation `x^2 - d*y^2 = 1`.
We define this in terms of elements of `ℤ√d` of norm one.
-/
def Solution₁ (d : ℤ) : Type 
goal: Type

full_name: Pell.Solution₁.instCommGroup
code: instance instCommGroup : CommGroup (Solution₁ d) 
goal: CommGroup (Pell.Solution₁ d)

full_name: Pell.Solution₁.instHasDistribNeg
code: instance instHasDistribNeg : HasDistribNeg (Solution₁ d) 
goal: HasDistribNeg (Pell.Solution₁ d)

full_name: Pell.Solution₁.instInhabited
code: instance instInhabited : Inhabited (Solution₁ d) 
goal: Inhabited (Pell.Solution₁ d)

full_name: Pell.Solution₁.instCoeZsqrtd
code: instance : Coe (Solution₁ d) (ℤ√d) 
goal: Coe (Pell.Solution₁ d) (ℤ√d)

full_name: Pell.Solution₁.x
code: /-- The `x` component of a solution to the Pell equation `x^2 - d*y^2 = 1` -/
protected def x (a : Solution₁ d) : ℤ 
goal: ℤ

full_name: Pell.Solution₁.y
code: /-- The `y` component of a solution to the Pell equation `x^2 - d*y^2 = 1` -/
protected def y (a : Solution₁ d) : ℤ 
goal: ℤ

full_name: Pell.Solution₁.prop
code: /-- The proof that `a` is a solution to the Pell equation `x^2 - d*y^2 = 1` -/
theorem prop (a : Solution₁ d) : a.x ^ 2 - d * a.y ^ 2 = 1 
goal: a.x ^ 2 - d * a.y ^ 2 = 1

full_name: Pell.Solution₁.prop_x
code: /-- An alternative form of the equation, suitable for rewriting `x^2`. -/
theorem prop_x (a : Solution₁ d) : a.x ^ 2 = 1 + d * a.y ^ 2 
goal: a.x ^ 2 = 1 + d * a.y ^ 2

full_name: Pell.Solution₁.prop_y
code: /-- An alternative form of the equation, suitable for rewriting `d * y^2`. -/
theorem prop_y (a : Solution₁ d) : d * a.y ^ 2 = a.x ^ 2 - 1 
goal: d * a.y ^ 2 = a.x ^ 2 - 1

full_name: Pell.Solution₁.ext
code: /-- Two solutions are equal if their `x` and `y` components are equal. -/
@[ext]
theorem ext {a b : Solution₁ d} (hx : a.x = b.x) (hy : a.y = b.y) : a = b 
goal: a = b

full_name: Pell.Solution₁.mk
code: /-- Construct a solution from `x`, `y` and a proof that the equation is satisfied. -/
def mk (x y : ℤ) (prop : x ^ 2 - d * y ^ 2 = 1) : Solution₁ d 
goal: Pell.Solution₁ d

full_name: Pell.Solution₁.x_mk
code: @[simp]
theorem x_mk (x y : ℤ) (prop : x ^ 2 - d * y ^ 2 = 1) : (mk x y prop).x = x 
goal: (Pell.Solution₁.mk x y prop).x = x

full_name: Pell.Solution₁.y_mk
code: @[simp]
theorem y_mk (x y : ℤ) (prop : x ^ 2 - d * y ^ 2 = 1) : (mk x y prop).y = y 
goal: (Pell.Solution₁.mk x y prop).y = y

full_name: Pell.Solution₁.coe_mk
code: @[simp]
theorem coe_mk (x y : ℤ) (prop : x ^ 2 - d * y ^ 2 = 1) : (↑(mk x y prop) : ℤ√d) = ⟨x, y⟩ 
goal: ↑(Pell.Solution₁.mk x y prop) = { re := x, im := y }

full_name: Pell.Solution₁.x_one
code: @[simp]
theorem x_one : (1 : Solution₁ d).x = 1 
goal: Pell.Solution₁.x 1 = 1

full_name: Pell.Solution₁.y_one
code: @[simp]
theorem y_one : (1 : Solution₁ d).y = 0 
goal: Pell.Solution₁.y 1 = 0

full_name: Pell.Solution₁.x_mul
code: @[simp]
theorem x_mul (a b : Solution₁ d) : (a * b).x = a.x * b.x + d * (a.y * b.y) 
goal: (a * b).x = a.x * b.x + d * (a.y * b.y)

full_name: Pell.Solution₁.y_mul
code: @[simp]
theorem y_mul (a b : Solution₁ d) : (a * b).y = a.x * b.y + a.y * b.x 
goal: (a * b).y = a.x * b.y + a.y * b.x

full_name: Pell.Solution₁.x_inv
code: @[simp]
theorem x_inv (a : Solution₁ d) : a⁻¹.x = a.x 
goal: a⁻¹.x = a.x

full_name: Pell.Solution₁.y_inv
code: @[simp]
theorem y_inv (a : Solution₁ d) : a⁻¹.y = -a.y 
goal: a⁻¹.y = -a.y

full_name: Pell.Solution₁.x_neg
code: @[simp]
theorem x_neg (a : Solution₁ d) : (-a).x = -a.x 
goal: (-a).x = -a.x

full_name: Pell.Solution₁.y_neg
code: @[simp]
theorem y_neg (a : Solution₁ d) : (-a).y = -a.y 
goal: (-a).y = -a.y

full_name: Pell.Solution₁.eq_zero_of_d_neg
code: /-- When `d` is negative, then `x` or `y` must be zero in a solution. -/
theorem eq_zero_of_d_neg (h₀ : d < 0) (a : Solution₁ d) : a.x = 0 ∨ a.y = 0 
goal: a.x = 0 ∨ a.y = 0

full_name: Pell.Solution₁.x_ne_zero
code: /-- A solution has `x ≠ 0`. -/
theorem x_ne_zero (h₀ : 0 ≤ d) (a : Solution₁ d) : a.x ≠ 0 
goal: a.x ≠ 0

full_name: Pell.Solution₁.y_ne_zero_of_one_lt_x
code: /-- A solution with `x > 1` must have `y ≠ 0`. -/
theorem y_ne_zero_of_one_lt_x {a : Solution₁ d} (ha : 1 < a.x) : a.y ≠ 0 
goal: a.y ≠ 0

full_name: Pell.Solution₁.d_pos_of_one_lt_x
code: /-- If a solution has `x > 1`, then `d` is positive. -/
theorem d_pos_of_one_lt_x {a : Solution₁ d} (ha : 1 < a.x) : 0 < d 
goal: 0 < d

full_name: Pell.Solution₁.d_nonsquare_of_one_lt_x
code: /-- If a solution has `x > 1`, then `d` is not a square. -/
theorem d_nonsquare_of_one_lt_x {a : Solution₁ d} (ha : 1 < a.x) : ¬IsSquare d 
goal: ¬IsSquare d

full_name: Pell.Solution₁.eq_one_of_x_eq_one
code: /-- A solution with `x = 1` is trivial. -/
theorem eq_one_of_x_eq_one (h₀ : d ≠ 0) {a : Solution₁ d} (ha : a.x = 1) : a = 1 
goal: a = 1

full_name: Pell.Solution₁.eq_one_or_neg_one_iff_y_eq_zero
code: /-- A solution is `1` or `-1` if and only if `y = 0`. -/
theorem eq_one_or_neg_one_iff_y_eq_zero {a : Solution₁ d} : a = 1 ∨ a = -1 ↔ a.y = 0 
goal: a = 1 ∨ a = -1 ↔ a.y = 0

full_name: Pell.Solution₁.x_mul_pos
code: /-- The set of solutions with `x > 0` is closed under multiplication. -/
theorem x_mul_pos {a b : Solution₁ d} (ha : 0 < a.x) (hb : 0 < b.x) : 0 < (a * b).x 
goal: 0 < (a * b).x

full_name: Pell.Solution₁.y_mul_pos
code: /-- The set of solutions with `x` and `y` positive is closed under multiplication. -/
theorem y_mul_pos {a b : Solution₁ d} (hax : 0 < a.x) (hay : 0 < a.y) (hbx : 0 < b.x)
    (hby : 0 < b.y) : 0 < (a * b).y 
goal: 0 < (a * b).y

full_name: Pell.Solution₁.x_pow_pos
code: /-- If `(x, y)` is a solution with `x` positive, then all its powers with natural exponents
have positive `x`. -/
theorem x_pow_pos {a : Solution₁ d} (hax : 0 < a.x) (n : ℕ) : 0 < (a ^ n).x 
goal: 0 < (a ^ n).x

full_name: Pell.Solution₁.y_pow_succ_pos
code: /-- If `(x, y)` is a solution with `x` and `y` positive, then all its powers with positive
natural exponents have positive `y`. -/
theorem y_pow_succ_pos {a : Solution₁ d} (hax : 0 < a.x) (hay : 0 < a.y) (n : ℕ) :
    0 < (a ^ n.succ).y 
goal: 0 < (a ^ n.succ).y

full_name: Pell.Solution₁.y_zpow_pos
code: /-- If `(x, y)` is a solution with `x` and `y` positive, then all its powers with positive
exponents have positive `y`. -/
theorem y_zpow_pos {a : Solution₁ d} (hax : 0 < a.x) (hay : 0 < a.y) {n : ℤ} (hn : 0 < n) :
    0 < (a ^ n).y 
goal: 0 < (a ^ n).y

full_name: Pell.Solution₁.x_zpow_pos
code: /-- If `(x, y)` is a solution with `x` positive, then all its powers have positive `x`. -/
theorem x_zpow_pos {a : Solution₁ d} (hax : 0 < a.x) (n : ℤ) : 0 < (a ^ n).x 
goal: 0 < (a ^ n).x

full_name: Pell.Solution₁.sign_y_zpow_eq_sign_of_x_pos_of_y_pos
code: /-- If `(x, y)` is a solution with `x` and `y` positive, then the `y` component of any power
has the same sign as the exponent. -/
theorem sign_y_zpow_eq_sign_of_x_pos_of_y_pos {a : Solution₁ d} (hax : 0 < a.x) (hay : 0 < a.y)
    (n : ℤ) : (a ^ n).y.sign = n.sign 
goal: (a ^ n).y.sign = n.sign

full_name: Pell.Solution₁.exists_pos_variant
code: /-- If `a` is any solution, then one of `a`, `a⁻¹`, `-a`, `-a⁻¹` has
positive `x` and nonnegative `y`. -/
theorem exists_pos_variant (h₀ : 0 < d) (a : Solution₁ d) :
    ∃ b : Solution₁ d, 0 < b.x ∧ 0 ≤ b.y ∧ a ∈ ({b, b⁻¹, -b, -b⁻¹} : Set (Solution₁ d)) 
goal: ∃ b, 0 < b.x ∧ 0 ≤ b.y ∧ a ∈ {b, b⁻¹, -b, -b⁻¹}

full_name: Pell.exists_of_not_isSquare
code: /-- If `d` is a positive integer that is not a square, then there is a nontrivial solution
to the Pell equation `x^2 - d*y^2 = 1`. -/
theorem exists_of_not_isSquare (h₀ : 0 < d) (hd : ¬IsSquare d) :
    ∃ x y : ℤ, x ^ 2 - d * y ^ 2 = 1 ∧ y ≠ 0 
goal: ∃ x y, x ^ 2 - d * y ^ 2 = 1 ∧ y ≠ 0

full_name: Pell.exists_iff_not_isSquare
code: /-- If `d` is a positive integer, then there is a nontrivial solution
to the Pell equation `x^2 - d*y^2 = 1` if and only if `d` is not a square. -/
theorem exists_iff_not_isSquare (h₀ : 0 < d) :
    (∃ x y : ℤ, x ^ 2 - d * y ^ 2 = 1 ∧ y ≠ 0) ↔ ¬IsSquare d 
goal: (∃ x y, x ^ 2 - d * y ^ 2 = 1 ∧ y ≠ 0) ↔ ¬IsSquare d

full_name: Pell.Solution₁.exists_nontrivial_of_not_isSquare
code: /-- If `d` is a positive integer that is not a square, then there exists a nontrivial solution
to the Pell equation `x^2 - d*y^2 = 1`. -/
theorem exists_nontrivial_of_not_isSquare (h₀ : 0 < d) (hd : ¬IsSquare d) :
    ∃ a : Solution₁ d, a ≠ 1 ∧ a ≠ -1 
goal: ∃ a, a ≠ 1 ∧ a ≠ -1

full_name: Pell.Solution₁.exists_pos_of_not_isSquare
code: /-- If `d` is a positive integer that is not a square, then there exists a solution
to the Pell equation `x^2 - d*y^2 = 1` with `x > 1` and `y > 0`. -/
theorem exists_pos_of_not_isSquare (h₀ : 0 < d) (hd : ¬IsSquare d) :
    ∃ a : Solution₁ d, 1 < a.x ∧ 0 < a.y 
goal: ∃ a, 1 < a.x ∧ 0 < a.y

full_name: Pell.IsFundamental
code: /-- We define a solution to be *fundamental* if it has `x > 1` and `y > 0`
and its `x` is the smallest possible among solutions with `x > 1`. -/
def IsFundamental (a : Solution₁ d) : Prop 
goal: Prop

full_name: Pell.IsFundamental.x_pos
code: /-- A fundamental solution has positive `x`. -/
theorem x_pos {a : Solution₁ d} (h : IsFundamental a) : 0 < a.x 
goal: 0 < a.x

full_name: Pell.IsFundamental.d_pos
code: /-- If a fundamental solution exists, then `d` must be positive. -/
theorem d_pos {a : Solution₁ d} (h : IsFundamental a) : 0 < d 
goal: 0 < d

full_name: Pell.IsFundamental.d_nonsquare
code: /-- If a fundamental solution exists, then `d` must be a non-square. -/
theorem d_nonsquare {a : Solution₁ d} (h : IsFundamental a) : ¬IsSquare d 
goal: ¬IsSquare d

full_name: Pell.IsFundamental.subsingleton
code: /-- If there is a fundamental solution, it is unique. -/
theorem subsingleton {a b : Solution₁ d} (ha : IsFundamental a) (hb : IsFundamental b) : a = b 
goal: a = b

full_name: Pell.IsFundamental.exists_of_not_isSquare
code: /-- If `d` is positive and not a square, then a fundamental solution exists. -/
theorem exists_of_not_isSquare (h₀ : 0 < d) (hd : ¬IsSquare d) :
    ∃ a : Solution₁ d, IsFundamental a 
goal: ∃ a, Pell.IsFundamental a

full_name: Pell.IsFundamental.y_strictMono
code: /-- The map sending an integer `n` to the `y`-coordinate of `a^n` for a fundamental
solution `a` is stritcly increasing. -/
theorem y_strictMono {a : Solution₁ d} (h : IsFundamental a) :
    StrictMono fun n : ℤ => (a ^ n).y 
goal: StrictMono fun n => (a ^ n).y

full_name: Pell.IsFundamental.zpow_y_lt_iff_lt
code: /-- If `a` is a fundamental solution, then `(a^m).y < (a^n).y` if and only if `m < n`. -/
theorem zpow_y_lt_iff_lt {a : Solution₁ d} (h : IsFundamental a) (m n : ℤ) :
    (a ^ m).y < (a ^ n).y ↔ m < n 
goal: (a ^ m).y < (a ^ n).y ↔ m < n

full_name: Pell.IsFundamental.zpow_eq_one_iff
code: /-- The `n`th power of a fundamental solution is trivial if and only if `n = 0`. -/
theorem zpow_eq_one_iff {a : Solution₁ d} (h : IsFundamental a) (n : ℤ) : a ^ n = 1 ↔ n = 0 
goal: a ^ n = 1 ↔ n = 0

full_name: Pell.IsFundamental.zpow_ne_neg_zpow
code: /-- A power of a fundamental solution is never equal to the negative of a power of this
fundamental solution. -/
theorem zpow_ne_neg_zpow {a : Solution₁ d} (h : IsFundamental a) {n n' : ℤ} : a ^ n ≠ -a ^ n' 
goal: a ^ n ≠ -a ^ n'

full_name: Pell.IsFundamental.x_le_x
code: /-- The `x`-coordinate of a fundamental solution is a lower bound for the `x`-coordinate
of any positive solution. -/
theorem x_le_x {a₁ : Solution₁ d} (h : IsFundamental a₁) {a : Solution₁ d} (hax : 1 < a.x) :
    a₁.x ≤ a.x 
goal: a₁.x ≤ a.x

full_name: Pell.IsFundamental.y_le_y
code: /-- The `y`-coordinate of a fundamental solution is a lower bound for the `y`-coordinate
of any positive solution. -/
theorem y_le_y {a₁ : Solution₁ d} (h : IsFundamental a₁) {a : Solution₁ d} (hax : 1 < a.x)
    (hay : 0 < a.y) : a₁.y ≤ a.y 
goal: a₁.y ≤ a.y

full_name: Pell.IsFundamental.x_mul_y_le_y_mul_x
code: theorem x_mul_y_le_y_mul_x {a₁ : Solution₁ d} (h : IsFundamental a₁) {a : Solution₁ d}
    (hax : 1 < a.x) (hay : 0 < a.y) : a.x * a₁.y ≤ a.y * a₁.x 
goal: a.x * a₁.y ≤ a.y * a₁.x

full_name: Pell.IsFundamental.mul_inv_y_nonneg
code: /-- If we multiply a positive solution with the inverse of a fundamental solution,
the `y`-coordinate remains nonnegative. -/
theorem mul_inv_y_nonneg {a₁ : Solution₁ d} (h : IsFundamental a₁) {a : Solution₁ d} (hax : 1 < a.x)
    (hay : 0 < a.y) : 0 ≤ (a * a₁⁻¹).y 
goal: 0 ≤ (a * a₁⁻¹).y

full_name: Pell.IsFundamental.mul_inv_x_pos
code: /-- If we multiply a positive solution with the inverse of a fundamental solution,
the `x`-coordinate stays positive. -/
theorem mul_inv_x_pos {a₁ : Solution₁ d} (h : IsFundamental a₁) {a : Solution₁ d} (hax : 1 < a.x)
    (hay : 0 < a.y) : 0 < (a * a₁⁻¹).x 
goal: 0 < (a * a₁⁻¹).x

full_name: Pell.IsFundamental.mul_inv_x_lt_x
code: /-- If we multiply a positive solution with the inverse of a fundamental solution,
the `x`-coordinate decreases. -/
theorem mul_inv_x_lt_x {a₁ : Solution₁ d} (h : IsFundamental a₁) {a : Solution₁ d} (hax : 1 < a.x)
    (hay : 0 < a.y) : (a * a₁⁻¹).x < a.x 
goal: (a * a₁⁻¹).x < a.x

full_name: Pell.IsFundamental.eq_pow_of_nonneg
code: /-- Any nonnegative solution is a power with nonnegative exponent of a fundamental solution. -/
theorem eq_pow_of_nonneg {a₁ : Solution₁ d} (h : IsFundamental a₁) {a : Solution₁ d} (hax : 0 < a.x)
    (hay : 0 ≤ a.y) : ∃ n : ℕ, a = a₁ ^ n 
goal: ∃ n, a = a₁ ^ n

full_name: Pell.IsFundamental.eq_zpow_or_neg_zpow
code: /-- Every solution is, up to a sign, a power of a given fundamental solution. -/
theorem eq_zpow_or_neg_zpow {a₁ : Solution₁ d} (h : IsFundamental a₁) (a : Solution₁ d) :
    ∃ n : ℤ, a = a₁ ^ n ∨ a = -a₁ ^ n 
goal: ∃ n, a = a₁ ^ n ∨ a = -a₁ ^ n

full_name: Pell.existsUnique_pos_generator
code: /-- When `d` is positive and not a square, then the group of solutions to the Pell equation
`x^2 - d*y^2 = 1` has a unique positive generator (up to sign). -/
theorem existsUnique_pos_generator (h₀ : 0 < d) (hd : ¬IsSquare d) :
    ∃! a₁ : Solution₁ d,
      1 < a₁.x ∧ 0 < a₁.y ∧ ∀ a : Solution₁ d, ∃ n : ℤ, a = a₁ ^ n ∨ a = -a₁ ^ n 
goal: ∃! a₁, 1 < a₁.x ∧ 0 < a₁.y ∧ ∀ (a : Pell.Solution₁ d), ∃ n, a = a₁ ^ n ∨ a = -a₁ ^ n

full_name: Pell.pos_generator_iff_fundamental
code: /-- A positive solution is a generator (up to sign) of the group of all solutions to the
Pell equation `x^2 - d*y^2 = 1` if and only if it is a fundamental solution. -/
theorem pos_generator_iff_fundamental (a : Solution₁ d) :
    (1 < a.x ∧ 0 < a.y ∧ ∀ b : Solution₁ d, ∃ n : ℤ, b = a ^ n ∨ b = -a ^ n) ↔ IsFundamental a 
goal: (1 < a.x ∧ 0 < a.y ∧ ∀ (b : Pell.Solution₁ d), ∃ n, b = a ^ n ∨ b = -a ^ n) ↔ Pell.IsFundamental a