mathlib3 documentation

number_theory.pell

Pell's Equation #

THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.

Pell's Equation is the equation $x^2 - d y^2 = 1$, where $d$ is a positive integer that is not a square, and one is interested in solutions in integers $x$ and $y$.

In this file, we aim at providing all of the essential theory of Pell's Equation for general $d$ (as opposed to the contents of number_theory.pell_matiyasevic, which is specific to the case $d = a^2 - 1$ for some $a > 1$).

We begin by defining a type pell.solution₁ d for solutions of the equation, show that it has a natural structure as an abelian group, and prove some basic properties.

We then prove the following

Theorem. Let $d$ be a positive integer that is not a square. Then the equation $x^2 - d y^2 = 1$ has a nontrivial (i.e., with $y \ne 0$) solution in integers.

See pell.exists_of_not_is_square and pell.solution₁.exists_nontrivial_of_not_is_square.

We then define the fundamental solution to be the solution with smallest $x$ among all solutions satisfying $x > 1$ and $y > 0$. We show that every solution is a power (in the sense of the group structure mentioned above) of the fundamental solution up to a (common) sign, see pell.is_fundamental.eq_zpow_or_neg_zpow, and that a (positive) solution has this property if and only if it is fundamental, see pell.pos_generator_iff_fundamental.

References #

Tags #

Pell's equation

TODO #

Group structure of the solution set #

We define a structure of a commutative multiplicative group with distributive negation on the set of all solutions to the Pell equation x^2 - d*y^2 = 1.

The type of such solutions is pell.solution₁ d. It corresponds to a pair of integers x and y and a proof that (x, y) is indeed a solution.

The multiplication is given by (x, y) * (x', y') = (x*y' + d*y*y', x*y' + y*x'). This is obtained by mapping (x, y) to x + y*√d and multiplying the results. In fact, we define pell.solution₁ d to be ↥(unitary (ℤ√d)) and transport the "commutative group with distributive negation" structure from ↥(unitary (ℤ√d)).

We then set up an API for pell.solution₁ d.

theorem pell.is_pell_solution_iff_mem_unitary {d : } {a : ℤ√d} :
a.re ^ 2 - d * a.im ^ 2 = 1 a unitary (ℤ√d)

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.is_pell_iff_mem_unitary.

def pell.solution₁ (d : ) :

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.

Equations
Instances for pell.solution₁
@[protected, instance]
@[protected, instance]
@[protected]

The x component of a solution to the Pell equation x^2 - d*y^2 = 1

Equations
@[protected]

The y component of a solution to the Pell equation x^2 - d*y^2 = 1

Equations
theorem pell.solution₁.prop {d : } (a : pell.solution₁ d) :
a.x ^ 2 - d * a.y ^ 2 = 1

The proof that a is a solution to the Pell equation x^2 - d*y^2 = 1

theorem pell.solution₁.prop_x {d : } (a : pell.solution₁ d) :
a.x ^ 2 = 1 + d * a.y ^ 2

An alternative form of the equation, suitable for rewriting x^2.

theorem pell.solution₁.prop_y {d : } (a : pell.solution₁ d) :
d * a.y ^ 2 = a.x ^ 2 - 1

An alternative form of the equation, suitable for rewriting d * y^2.

@[ext]
theorem pell.solution₁.ext {d : } {a b : pell.solution₁ d} (hx : a.x = b.x) (hy : a.y = b.y) :
a = b

Two solutions are equal if their x and y components are equal.

def pell.solution₁.mk {d : } (x y : ) (prop : x ^ 2 - d * y ^ 2 = 1) :

Construct a solution from x, y and a proof that the equation is satisfied.

Equations
@[simp]
theorem pell.solution₁.x_mk {d : } (x y : ) (prop : x ^ 2 - d * y ^ 2 = 1) :
(pell.solution₁.mk x y prop).x = x
@[simp]
theorem pell.solution₁.y_mk {d : } (x y : ) (prop : x ^ 2 - d * y ^ 2 = 1) :
(pell.solution₁.mk x y prop).y = y
@[simp]
theorem pell.solution₁.coe_mk {d : } (x y : ) (prop : x ^ 2 - d * y ^ 2 = 1) :
(pell.solution₁.mk x y prop) = {re := x, im := y}
@[simp]
theorem pell.solution₁.x_one {d : } :
1.x = 1
@[simp]
theorem pell.solution₁.y_one {d : } :
1.y = 0
@[simp]
theorem pell.solution₁.x_mul {d : } (a b : pell.solution₁ d) :
(a * b).x = a.x * b.x + d * (a.y * b.y)
@[simp]
theorem pell.solution₁.y_mul {d : } (a b : pell.solution₁ d) :
(a * b).y = a.x * b.y + a.y * b.x
@[simp]
theorem pell.solution₁.x_inv {d : } (a : pell.solution₁ d) :
a⁻¹.x = a.x
@[simp]
theorem pell.solution₁.y_inv {d : } (a : pell.solution₁ d) :
a⁻¹.y = -a.y
@[simp]
theorem pell.solution₁.x_neg {d : } (a : pell.solution₁ d) :
(-a).x = -a.x
@[simp]
theorem pell.solution₁.y_neg {d : } (a : pell.solution₁ d) :
(-a).y = -a.y
theorem pell.solution₁.eq_zero_of_d_neg {d : } (h₀ : d < 0) (a : pell.solution₁ d) :
a.x = 0 a.y = 0

When d is negative, then x or y must be zero in a solution.

theorem pell.solution₁.x_ne_zero {d : } (h₀ : 0 d) (a : pell.solution₁ d) :
a.x 0

A solution has x ≠ 0.

theorem pell.solution₁.y_ne_zero_of_one_lt_x {d : } {a : pell.solution₁ d} (ha : 1 < a.x) :
a.y 0

A solution with x > 1 must have y ≠ 0.

theorem pell.solution₁.d_pos_of_one_lt_x {d : } {a : pell.solution₁ d} (ha : 1 < a.x) :
0 < d

If a solution has x > 1, then d is positive.

If a solution has x > 1, then d is not a square.

theorem pell.solution₁.eq_one_of_x_eq_one {d : } (h₀ : d 0) {a : pell.solution₁ d} (ha : a.x = 1) :
a = 1

A solution with x = 1 is trivial.

A solution is 1 or -1 if and only if y = 0.

theorem pell.solution₁.x_mul_pos {d : } {a b : pell.solution₁ d} (ha : 0 < a.x) (hb : 0 < b.x) :
0 < (a * b).x

The set of solutions with x > 0 is closed under multiplication.

theorem pell.solution₁.y_mul_pos {d : } {a b : pell.solution₁ d} (hax : 0 < a.x) (hay : 0 < a.y) (hbx : 0 < b.x) (hby : 0 < b.y) :
0 < (a * b).y

The set of solutions with x and y positive is closed under multiplication.

theorem pell.solution₁.x_pow_pos {d : } {a : pell.solution₁ d} (hax : 0 < a.x) (n : ) :
0 < (a ^ n).x

If (x, y) is a solution with x positive, then all its powers with natural exponents have positive x.

theorem pell.solution₁.y_pow_succ_pos {d : } {a : pell.solution₁ d} (hax : 0 < a.x) (hay : 0 < a.y) (n : ) :
0 < (a ^ n.succ).y

If (x, y) is a solution with x and y positive, then all its powers with positive natural exponents have positive y.

theorem pell.solution₁.y_zpow_pos {d : } {a : pell.solution₁ d} (hax : 0 < a.x) (hay : 0 < a.y) {n : } (hn : 0 < n) :
0 < (a ^ n).y

If (x, y) is a solution with x and y positive, then all its powers with positive exponents have positive y.

theorem pell.solution₁.x_zpow_pos {d : } {a : pell.solution₁ d} (hax : 0 < a.x) (n : ) :
0 < (a ^ n).x

If (x, y) is a solution with x positive, then all its powers have positive x.

theorem pell.solution₁.sign_y_zpow_eq_sign_of_x_pos_of_y_pos {d : } {a : pell.solution₁ d} (hax : 0 < a.x) (hay : 0 < a.y) (n : ) :
(a ^ n).y.sign = n.sign

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 pell.solution₁.exists_pos_variant {d : } (h₀ : 0 < d) (a : pell.solution₁ d) :
(b : pell.solution₁ d), 0 < b.x 0 b.y a {b, b⁻¹, -b, -b⁻¹}

If a is any solution, then one of a, a⁻¹, -a, -a⁻¹ has positive x and nonnegative y.

Existence of nontrivial solutions #

theorem pell.exists_of_not_is_square {d : } (h₀ : 0 < d) (hd : ¬is_square d) :
(x y : ), x ^ 2 - d * y ^ 2 = 1 y 0

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 pell.exists_iff_not_is_square {d : } (h₀ : 0 < d) :
( (x y : ), x ^ 2 - d * y ^ 2 = 1 y 0) ¬is_square d

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 pell.solution₁.exists_nontrivial_of_not_is_square {d : } (h₀ : 0 < d) (hd : ¬is_square d) :
(a : pell.solution₁ d), a 1 a -1

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 pell.solution₁.exists_pos_of_not_is_square {d : } (h₀ : 0 < d) (hd : ¬is_square d) :
(a : pell.solution₁ d), 1 < a.x 0 < a.y

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.

Fundamental solutions #

We define the notion of a fundamental solution of Pell's equation and show that it exists and is unique (when d is positive and non-square) and generates the group of solutions up to sign.

def pell.is_fundamental {d : } (a : pell.solution₁ d) :
Prop

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.

Equations
theorem pell.is_fundamental.x_pos {d : } {a : pell.solution₁ d} (h : pell.is_fundamental a) :
0 < a.x

A fundamental solution has positive x.

theorem pell.is_fundamental.d_pos {d : } {a : pell.solution₁ d} (h : pell.is_fundamental a) :
0 < d

If a fundamental solution exists, then d must be positive.

If a fundamental solution exists, then d must be a non-square.

If there is a fundamental solution, it is unique.

If d is positive and not a square, then a fundamental solution exists.

theorem pell.is_fundamental.y_strict_mono {d : } {a : pell.solution₁ d} (h : pell.is_fundamental a) :
strict_mono (λ (n : ), (a ^ n).y)

The map sending an integer n to the y-coordinate of a^n for a fundamental solution a is stritcly increasing.

theorem pell.is_fundamental.zpow_y_lt_iff_lt {d : } {a : pell.solution₁ d} (h : pell.is_fundamental a) (m n : ) :
(a ^ m).y < (a ^ n).y m < n

If a is a fundamental solution, then (a^m).y < (a^n).y if and only if m < n.

theorem pell.is_fundamental.zpow_eq_one_iff {d : } {a : pell.solution₁ d} (h : pell.is_fundamental a) (n : ) :
a ^ n = 1 n = 0

The nth power of a fundamental solution is trivial if and only if n = 0.

theorem pell.is_fundamental.zpow_ne_neg_zpow {d : } {a : pell.solution₁ d} (h : pell.is_fundamental a) {n n' : } :
a ^ n -a ^ n'

A power of a fundamental solution is never equal to the negative of a power of this fundamental solution.

theorem pell.is_fundamental.x_le_x {d : } {a₁ : pell.solution₁ d} (h : pell.is_fundamental a₁) {a : pell.solution₁ d} (hax : 1 < a.x) :
a₁.x a.x

The x-coordinate of a fundamental solution is a lower bound for the x-coordinate of any positive solution.

theorem pell.is_fundamental.y_le_y {d : } {a₁ : pell.solution₁ d} (h : pell.is_fundamental a₁) {a : pell.solution₁ d} (hax : 1 < a.x) (hay : 0 < a.y) :
a₁.y a.y

The y-coordinate of a fundamental solution is a lower bound for the y-coordinate of any positive solution.

theorem pell.is_fundamental.x_mul_y_le_y_mul_x {d : } {a₁ : pell.solution₁ d} (h : pell.is_fundamental a₁) {a : pell.solution₁ d} (hax : 1 < a.x) (hay : 0 < a.y) :
a.x * a₁.y a.y * a₁.x
theorem pell.is_fundamental.mul_inv_y_nonneg {d : } {a₁ : pell.solution₁ d} (h : pell.is_fundamental a₁) {a : pell.solution₁ d} (hax : 1 < a.x) (hay : 0 < a.y) :
0 (a * a₁⁻¹).y

If we multiply a positive solution with the inverse of a fundamental solution, the y-coordinate remains nonnegative.

theorem pell.is_fundamental.mul_inv_x_pos {d : } {a₁ : pell.solution₁ d} (h : pell.is_fundamental a₁) {a : pell.solution₁ d} (hax : 1 < a.x) (hay : 0 < a.y) :
0 < (a * a₁⁻¹).x

If we multiply a positive solution with the inverse of a fundamental solution, the x-coordinate stays positive.

theorem pell.is_fundamental.mul_inv_x_lt_x {d : } {a₁ : pell.solution₁ d} (h : pell.is_fundamental a₁) {a : pell.solution₁ d} (hax : 1 < a.x) (hay : 0 < a.y) :
(a * a₁⁻¹).x < a.x

If we multiply a positive solution with the inverse of a fundamental solution, the x-coordinate decreases.

theorem pell.is_fundamental.eq_pow_of_nonneg {d : } {a₁ : pell.solution₁ d} (h : pell.is_fundamental a₁) {a : pell.solution₁ d} (hax : 0 < a.x) (hay : 0 a.y) :
(n : ), a = a₁ ^ n

Any nonnegative solution is a power with nonnegative exponent of a fundamental solution.

theorem pell.is_fundamental.eq_zpow_or_neg_zpow {d : } {a₁ : pell.solution₁ d} (h : pell.is_fundamental a₁) (a : pell.solution₁ d) :
(n : ), a = a₁ ^ n a = -a₁ ^ n

Every solution is, up to a sign, a power of a given fundamental solution.

theorem pell.exists_unique_pos_generator {d : } (h₀ : 0 < d) (hd : ¬is_square d) :
∃! (a₁ : pell.solution₁ d), 1 < a₁.x 0 < a₁.y (a : pell.solution₁ d), (n : ), a = a₁ ^ n a = -a₁ ^ n

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 pell.pos_generator_iff_fundamental {d : } (a : pell.solution₁ d) :
(1 < a.x 0 < a.y (b : pell.solution₁ d), (n : ), b = a ^ n b = -a ^ n) pell.is_fundamental a

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.